Implemented HAnim plugin.

This commit is contained in:
Angelo Papenhoff 2015-01-17 15:15:03 +01:00
parent f8f7efab40
commit c0fab82c52
9 changed files with 184 additions and 14 deletions

View File

@ -6,7 +6,7 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
BUILDDIR=build-$(BUILD)
SRCDIR=src
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
geometry.cpp geometryplg.cpp\
geometry.cpp plugins.cpp\
ps2.cpp ogl.cpp\
image.cpp gtaplg.cpp)
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))

View File

@ -6,7 +6,7 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
BUILDDIR=build-$(BUILD)
SRCDIR=src
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
geometry.cpp geometryplg.cpp\
geometry.cpp plugins.cpp\
ps2.cpp ogl.cpp\
image.cpp gtaplg.cpp)
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))

View File

@ -7,7 +7,7 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/')
BUILDDIR=build-$(BUILD)
SRCDIR=src
SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\
geometry.cpp geometryplg.cpp\
geometry.cpp plugins.cpp\
ps2.cpp ogl.cpp\
image.cpp gtaplg.cpp)
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))

2
TODO
View File

@ -15,8 +15,6 @@ Clump & related:
- implement plugins:
Clump
R* Collision
Frame
HAnim
Atomic
((Particles))
R* Pipeline Set

View File

@ -21,6 +21,7 @@ main(int argc, char *argv[])
Rw::RegisterMaterialRightsPlugin();
Rw::RegisterMatFXPlugin();
Rw::RegisterAtomicRightsPlugin();
Rw::RegisterHAnimPlugin();
Rw::RegisterNodeNamePlugin();
Rw::RegisterBreakableModelPlugin();
Rw::RegisterExtraVertColorPlugin();

View File

@ -108,6 +108,7 @@ Frame::updateLTM(void)
Frame *parent = (Frame*)this->parent;
if(parent){
parent->updateLTM();
// TODO: replace with platform optimized code
#define L(i,j) this->ltm[i*4+j]
#define A(i,j) parent->ltm[i*4+j]
#define B(i,j) this->matrix[i*4+j]
@ -127,6 +128,21 @@ Frame::updateLTM(void)
}
}
static Frame*
dirtyCB(Frame *f, void *)
{
f->dirty = true;
f->forAllChildren(dirtyCB, NULL);
return f;
}
void
Frame::setDirty(void)
{
this->dirty = true;
this->forAllChildren(dirtyCB, NULL);
}
static Frame*
sizeCB(Frame *f, void *size)
{

View File

@ -2,9 +2,6 @@
#include <cstdlib>
#include <cstring>
#include <cassert>
//#include <iostream>
//#include <fstream>
#include <new>
#include "rwbase.h"
@ -17,6 +14,128 @@ using namespace std;
namespace Rw {
//
// HAnim
//
int32 HAnimOffset;
static void*
createHAnim(void *object, int32 offset, int32 size)
{
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
hanim->id = -1;
hanim->hierarchy = NULL;
return object;
}
static void*
destroyHAnim(void *object, int32 offset, int32 size)
{
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
if(hanim->hierarchy){
HAnimHierarchy *hier = hanim->hierarchy;
delete[] (uint8*)hier->matricesUnaligned;
delete[] hier->nodeInfo;
delete hier;
}
hanim->id = -1;
hanim->hierarchy = NULL;
return object;
}
static void*
copyHAnim(void *dst, void *src, int32 offset, int32 size)
{
HAnimData *dsthanim = PLUGINOFFSET(HAnimData, dst, offset);
HAnimData *srchanim = PLUGINOFFSET(HAnimData, src, offset);
dsthanim->id = srchanim->id;
// TODO
dsthanim->hierarchy = NULL;
return dst;
}
static void
readHAnim(Stream *stream, int32 len, void *object, int32 offset, int32)
{
int32 cnst, numNodes;
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
cnst = stream->readI32();
if(cnst != 256){
printf("hanim const was not 256\n");
return;
}
hanim->id = stream->readI32();
numNodes = stream->readI32();
if(numNodes != 0){
HAnimHierarchy *hier = new HAnimHierarchy;
hanim->hierarchy = hier;
hier->numNodes = numNodes;
hier->flags = stream->readI32();
hier->maxInterpKeyFrameSize = stream->readI32();
hier->parentFrame = (Frame*)object;
hier->parentHierarchy = hier;
if(hier->flags & 2)
hier->matrices = hier->matricesUnaligned = NULL;
else{
hier->matricesUnaligned =
(float*) new uint8[hier->numNodes*64 + 15];
hier->matrices =
(float*)((uintptr)hier->matricesUnaligned & ~0xF);
}
hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
for(int32 i = 0; i < hier->numNodes; i++){
hier->nodeInfo[i].id = stream->readI32();
hier->nodeInfo[i].index = stream->readI32();
hier->nodeInfo[i].flags = stream->readI32();
hier->nodeInfo[i].frame = NULL;
}
}
}
static void
writeHAnim(Stream *stream, int32 len, void *object, int32 offset, int32)
{
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
stream->writeI32(256);
stream->writeI32(hanim->id);
if(hanim->hierarchy == NULL){
stream->writeI32(0);
return;
}
HAnimHierarchy *hier = hanim->hierarchy;
stream->writeI32(hier->numNodes);
stream->writeI32(hier->flags);
stream->writeI32(hier->maxInterpKeyFrameSize);
for(int32 i = 0; i < hier->numNodes; i++){
stream->writeI32(hier->nodeInfo[i].id);
stream->writeI32(hier->nodeInfo[i].index);
stream->writeI32(hier->nodeInfo[i].flags);
}
}
static int32
getSizeHAnim(void *object, int32 offset, int32)
{
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
if(hanim->hierarchy)
return 12 + 8 + hanim->hierarchy->numNodes*12;
return 12;
}
void
RegisterHAnimPlugin(void)
{
HAnimOffset = Frame::registerPlugin(sizeof(HAnimData), ID_HANIMPLUGIN,
createHAnim,
destroyHAnim, copyHAnim);
Frame::registerPluginStream(ID_HANIMPLUGIN,
readHAnim,
writeHAnim,
getSizeHAnim);
}
//
// Geometry
//
@ -207,7 +326,9 @@ RegisterNativeDataPlugin(void)
(StreamGetSize)getSizeNativeData);
}
//
// Skin
//
SkinGlobals_ SkinGlobals = { 0, NULL };
@ -442,7 +563,11 @@ RegisterSkinPlugin(void)
Atomic::setStreamRightsCallback(ID_SKIN, skinRights);
}
// Atomic MatFX
//
// MatFX
//
// Atomic
static void*
createAtomicMatFX(void *object, int32 offset, int32)
@ -463,10 +588,7 @@ readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
{
int32 flag;
uint32 version;
//stream->seek(-4);
//version = stream->readU32();
stream->read(&flag, 4);
//printf("atomicMatFX: %X %X\n", LibraryIDUnpackVersion(version), flag);
*PLUGINOFFSET(int32, object, offset) = flag;
if(flag)
((Atomic*)object)->pipeline = MatFXGlobals.pipeline;
@ -488,7 +610,7 @@ getSizeAtomicMatFX(void *object, int32 offset, int32)
return flag ? 4 : -1;
}
// Material MatFX
// Material
MatFXGlobals_ MatFXGlobals = { 0, 0, NULL };

View File

@ -110,6 +110,7 @@ enum PluginID
ID_UVANIMDICT = 0x2B,
ID_SKIN = 0x116,
ID_HANIMPLUGIN = 0x11E,
ID_MATFX = 0x120,
ID_PDS = 0x131,
ID_ADC = 0x134,

View File

@ -1,6 +1,6 @@
namespace Rw {
// TODO: mostly
// TODO: mostly a stub right now
struct Pipeline
{
uint32 pluginID;
@ -37,8 +37,40 @@ struct Frame : PluginBase<Frame>, Object
Frame *forAllChildren(Callback cb, void *data);
int32 count(void);
void updateLTM(void);
void setDirty(void);
};
struct HAnimNodeInfo
{
int32 id;
int32 index;
int32 flags;
Frame *frame;
};
struct HAnimHierarchy
{
int32 flags;
int32 numNodes;
float *matrices;
float *matricesUnaligned;
HAnimNodeInfo *nodeInfo;
Frame *parentFrame;
HAnimHierarchy *parentHierarchy; // mostly unused
// temporary
int32 maxInterpKeyFrameSize;
};
struct HAnimData
{
int32 id;
HAnimHierarchy *hierarchy;
};
extern int32 HAnimOffset;
void RegisterHAnimPlugin(void);
struct Image
{
int32 flags;