1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 03:12:36 +01:00

Added LoaderIFP for loading IFP animation files

Added support to datadump for viewing animation data
This commit is contained in:
Daniel Evans 2013-07-24 09:41:27 +01:00
parent 1251c4c2a7
commit 21fcece46c
4 changed files with 224 additions and 1 deletions

View File

@ -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;

View File

@ -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
View 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);
}

View 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