mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 11:22:45 +01:00
Added LoaderIFP for loading IFP animation files
Added support to datadump for viewing animation data
This commit is contained in:
parent
1251c4c2a7
commit
21fcece46c
@ -4,6 +4,7 @@
|
||||
#include <algorithm>
|
||||
#include <renderwure/BinaryStream.hpp>
|
||||
#include <renderwure/loaders/LoaderCOL.hpp>
|
||||
#include <renderwure/loaders/LoaderIFP.hpp>
|
||||
#include "../framework/rwbinarystream.h"
|
||||
|
||||
using RW::BSSectionHeader;
|
||||
@ -442,6 +443,27 @@ void dumpGenericTree(char* data)
|
||||
dumpBinaryStreamSection(root, 0);
|
||||
}
|
||||
|
||||
void dumpAnimationFile(char* data)
|
||||
{
|
||||
LoaderIFP loader;
|
||||
|
||||
if(loader.loadFromMemory(data)) {
|
||||
std::cout << loader.animations.size() << " animations" << std::endl;
|
||||
|
||||
for( auto it = loader.animations.begin();
|
||||
it != loader.animations.end(); ++it ) {
|
||||
Animation* a = *it;
|
||||
std::cout << a->name << std::endl;
|
||||
std::cout << " " << a->bones.size() << " bones" << std::endl;
|
||||
for( auto bit = a->bones.begin();
|
||||
bit != a->bones.end(); ++bit ) {
|
||||
std::cout << " " << bit->first << " (" << bit->second->frames.size() << " frames)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool raw = false;
|
||||
@ -485,6 +507,11 @@ int main(int argc, char** argv)
|
||||
std::cout << "Dumping Collsion file" << std::endl;
|
||||
dumpCollisionModel(data, size);
|
||||
}
|
||||
else if(ext == "ifp")
|
||||
{
|
||||
std::cout << "Dumping animation file" << std::endl;
|
||||
dumpAnimationFile(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "I'm not sure what that is" << std::endl;
|
||||
|
@ -2,7 +2,6 @@ SET(RENDERWARE_SOURCES
|
||||
# RenderWare related
|
||||
BinaryStream.cpp
|
||||
TextureArchive.cpp
|
||||
LoaderDFF.cpp
|
||||
TextureLoader.cpp
|
||||
WeatherLoader.cpp
|
||||
|
||||
@ -11,6 +10,8 @@ SET(RENDERWARE_SOURCES
|
||||
LoaderIMG.cpp
|
||||
LoaderIPL.cpp
|
||||
LoaderIDE.cpp
|
||||
LoaderDFF.cpp
|
||||
LoaderIFP.cpp
|
||||
GTAData.cpp
|
||||
|
||||
GTAEngine.cpp
|
||||
@ -31,6 +32,7 @@ SET(RENDERWARE_HEADERS
|
||||
include/renderwure/loaders/LoaderIMG.hpp
|
||||
include/renderwure/loaders/LoaderIPL.hpp
|
||||
include/renderwure/loaders/LoaderIDE.hpp
|
||||
include/renderwure/loaders/LoaderIFP.hpp
|
||||
|
||||
include/renderwure/engine/GTAData.hpp
|
||||
include/renderwure/engine/GTAEngine.hpp
|
||||
|
93
framework2/LoaderIFP.cpp
Normal file
93
framework2/LoaderIFP.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <renderwure/loaders/LoaderIFP.hpp>
|
||||
|
||||
bool LoaderIFP::loadFromMemory(char *data)
|
||||
{
|
||||
size_t data_offs = 0;
|
||||
size_t* dataI = &data_offs;
|
||||
|
||||
ANPK* fileRoot = read<ANPK>(data, dataI);
|
||||
std::string listname = readString(data, dataI);
|
||||
|
||||
for( size_t a = 0; a < fileRoot->info.entries; ++a ) {
|
||||
// something about a name?
|
||||
NAME* n = read<NAME>(data, dataI);
|
||||
std::string animname = readString(data, dataI);
|
||||
|
||||
Animation* animation = new Animation;
|
||||
animation->name = animname;
|
||||
|
||||
size_t animstart = data_offs + 8;
|
||||
DGAN* animroot = read<DGAN>(data, dataI);
|
||||
std::string infoname = readString(data, dataI);
|
||||
|
||||
for( size_t c = 0; c < animroot->info.entries; ++c ) {
|
||||
size_t start = data_offs;
|
||||
CPAN* cpan = read<CPAN>(data, dataI);
|
||||
ANIM* frames = read<ANIM>(data, dataI);
|
||||
|
||||
AnimationBone* bonedata = new AnimationBone;
|
||||
bonedata->name = frames->name;
|
||||
bonedata->frames.reserve(frames->frames);
|
||||
|
||||
data_offs += ((8+frames->base.size) - sizeof(ANIM));
|
||||
|
||||
KFRM* frame = read<KFRM>(data, dataI);
|
||||
std::string type(frame->base.magic, 4);
|
||||
bonedata->time = frame->time;
|
||||
|
||||
if(type == "KR00") {
|
||||
for( size_t d = 0; d < frames->frames; ++d ) {
|
||||
bonedata->frames.push_back({
|
||||
*read<glm::quat>(data, dataI),
|
||||
glm::vec3(0.f, 0.f, 0.f),
|
||||
glm::vec3(1.f, 1.f, 1.f)
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(type == "KRT0") {
|
||||
for( size_t d = 0; d < frames->frames; ++d ) {
|
||||
bonedata->frames.push_back({
|
||||
*read<glm::quat>(data, dataI),
|
||||
*read<glm::vec3>(data, dataI),
|
||||
glm::vec3(1.f, 1.f, 1.f)
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(type == "KRTS") {
|
||||
for( size_t d = 0; d < frames->frames; ++d ) {
|
||||
bonedata->frames.push_back({
|
||||
*read<glm::quat>(data, dataI),
|
||||
*read<glm::vec3>(data, dataI),
|
||||
*read<glm::vec3>(data, dataI)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
data_offs = start + sizeof(CPAN) + cpan->base.size;
|
||||
|
||||
animation->bones.insert({
|
||||
std::string(frames->name),
|
||||
bonedata
|
||||
});
|
||||
}
|
||||
|
||||
data_offs = animstart + animroot->base.size;
|
||||
|
||||
animations.push_back(animation);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string LoaderIFP::readString(char *data, size_t *ofs)
|
||||
{
|
||||
size_t b = *ofs;
|
||||
for(size_t o = *ofs; o = *ofs;) {
|
||||
*ofs += 4;
|
||||
if(data[o+0] == 0) break;
|
||||
if(data[o+1] == 0) break;
|
||||
if(data[o+2] == 0) break;
|
||||
if(data[o+3] == 0) break;
|
||||
}
|
||||
return std::string(data+b);
|
||||
}
|
101
framework2/include/renderwure/loaders/LoaderIFP.hpp
Normal file
101
framework2/include/renderwure/loaders/LoaderIFP.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
#ifndef _LOADERDFF_IFP_
|
||||
#define _LOADERDFF_IFP_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
struct AnimationKeyframe
|
||||
{
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
glm::vec3 scale;
|
||||
};
|
||||
|
||||
struct AnimationBone
|
||||
{
|
||||
std::string name;
|
||||
int32_t previous;
|
||||
int32_t next;
|
||||
float time;
|
||||
std::vector<AnimationKeyframe> frames;
|
||||
};
|
||||
|
||||
struct Animation
|
||||
{
|
||||
std::string name;
|
||||
std::map<std::string, AnimationBone*> bones;
|
||||
};
|
||||
|
||||
class LoaderIFP
|
||||
{
|
||||
template<class T> T* read(char* data, size_t* ofs) {
|
||||
size_t b = *ofs; *ofs += sizeof(T);
|
||||
return reinterpret_cast<T*>(data + b);
|
||||
}
|
||||
template<class T> T* peek(char* data, size_t* ofs) {
|
||||
return reinterpret_cast<T*>(data + *ofs);
|
||||
}
|
||||
|
||||
std::string readString(char* data, size_t* ofs);
|
||||
|
||||
public:
|
||||
|
||||
struct BASE {
|
||||
char magic[4];
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct INFO {
|
||||
BASE base;
|
||||
int32_t entries;
|
||||
// null terminated string
|
||||
// entry data
|
||||
};
|
||||
|
||||
struct ANPK {
|
||||
BASE base;
|
||||
INFO info;
|
||||
};
|
||||
|
||||
struct NAME {
|
||||
BASE base;
|
||||
};
|
||||
|
||||
struct DGAN {
|
||||
BASE base;
|
||||
INFO info;
|
||||
};
|
||||
|
||||
struct CPAN {
|
||||
BASE base;
|
||||
};
|
||||
|
||||
struct ANIM {
|
||||
BASE base;
|
||||
char name[28];
|
||||
int32_t frames;
|
||||
int32_t unk;
|
||||
int32_t next;
|
||||
int32_t prev;
|
||||
};
|
||||
|
||||
struct KFRM {
|
||||
BASE base;
|
||||
float time;
|
||||
};
|
||||
|
||||
struct Anim {
|
||||
std::string name;
|
||||
|
||||
};
|
||||
|
||||
std::vector<Animation*> animations;
|
||||
|
||||
bool loadFromMemory(char *data);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user