mirror of https://github.com/aap/librw.git
196 lines
4.5 KiB
C++
196 lines
4.5 KiB
C++
#include <stddef.h>
|
|
|
|
namespace rw {
|
|
|
|
struct Animation;
|
|
|
|
// These sizes of these are sadly not platform independent
|
|
// because pointer sizes can vary.
|
|
|
|
struct KeyFrameHeader
|
|
{
|
|
KeyFrameHeader *prev;
|
|
float32 time;
|
|
|
|
KeyFrameHeader *next(int32 sz){
|
|
return (KeyFrameHeader*)((uint8*)this + sz); }
|
|
};
|
|
|
|
struct InterpFrameHeader
|
|
{
|
|
KeyFrameHeader *keyFrame1;
|
|
KeyFrameHeader *keyFrame2;
|
|
};
|
|
|
|
struct AnimInterpolatorInfo
|
|
{
|
|
typedef void (*ApplyCB)(void *result, void *frame);
|
|
typedef void (*BlendCB)(void *out, void *in1, void *in2, float32 a);
|
|
typedef void (*InterpCB)(void *out, void *in1, void *in2, float32 t,
|
|
void *custom);
|
|
typedef void (*AddCB)(void *out, void *in1, void *in2);
|
|
typedef void (*MulRecipCB)(void *frame, void *start);
|
|
|
|
int32 id;
|
|
int32 interpKeyFrameSize;
|
|
int32 animKeyFrameSize;
|
|
int32 customDataSize;
|
|
|
|
ApplyCB applyCB;
|
|
BlendCB blendCB;
|
|
InterpCB interpCB;
|
|
AddCB addCB;
|
|
MulRecipCB mulRecipCB;
|
|
void (*streamRead)(Stream *stream, Animation *anim);
|
|
void (*streamWrite)(Stream *stream, Animation *anim);
|
|
uint32 (*streamGetSize)(Animation *anim);
|
|
|
|
static void registerInterp(AnimInterpolatorInfo *interpInfo);
|
|
static void unregisterInterp(AnimInterpolatorInfo *interpInfo);
|
|
static AnimInterpolatorInfo *find(int32 id);
|
|
};
|
|
|
|
struct Animation
|
|
{
|
|
AnimInterpolatorInfo *interpInfo;
|
|
int32 numFrames;
|
|
int32 flags;
|
|
float32 duration;
|
|
void *keyframes;
|
|
void *customData;
|
|
|
|
static Animation *create(AnimInterpolatorInfo*, int32 numFrames,
|
|
int32 flags, float duration);
|
|
void destroy(void);
|
|
int32 getNumNodes(void);
|
|
KeyFrameHeader *getAnimFrame(int32 n){
|
|
return (KeyFrameHeader*)((uint8*)this->keyframes +
|
|
n*this->interpInfo->animKeyFrameSize);
|
|
}
|
|
static Animation *streamRead(Stream *stream);
|
|
static Animation *streamReadLegacy(Stream *stream);
|
|
bool streamWrite(Stream *stream);
|
|
bool streamWriteLegacy(Stream *stream);
|
|
uint32 streamGetSize(void);
|
|
};
|
|
|
|
struct AnimInterpolator
|
|
{
|
|
Animation *currentAnim;
|
|
float32 currentTime;
|
|
void *nextFrame;
|
|
int32 maxInterpKeyFrameSize;
|
|
int32 currentInterpKeyFrameSize;
|
|
int32 currentAnimKeyFrameSize;
|
|
int32 numNodes;
|
|
// TODO some callbacks, parent/sub
|
|
// cached from the InterpolatorInfo
|
|
AnimInterpolatorInfo::ApplyCB applyCB;
|
|
AnimInterpolatorInfo::BlendCB blendCB;
|
|
AnimInterpolatorInfo::InterpCB interpCB;
|
|
AnimInterpolatorInfo::AddCB addCB;
|
|
// after this interpolated frames
|
|
|
|
static AnimInterpolator *create(int32 numNodes, int32 maxKeyFrameSize);
|
|
void destroy(void);
|
|
bool32 setCurrentAnim(Animation *anim);
|
|
void addTime(float32 t);
|
|
void *getFrames(void){ return this+1;}
|
|
InterpFrameHeader *getInterpFrame(int32 n){
|
|
return (InterpFrameHeader*)((uint8*)getFrames() +
|
|
n*currentInterpKeyFrameSize);
|
|
}
|
|
KeyFrameHeader *getAnimFrame(int32 n){
|
|
return (KeyFrameHeader*)((uint8*)currentAnim->keyframes +
|
|
n*currentAnimKeyFrameSize);
|
|
}
|
|
};
|
|
|
|
//
|
|
// UV anim
|
|
//
|
|
|
|
struct UVAnimParamData
|
|
{
|
|
float32 theta; // rotation
|
|
float32 s0; // scale x
|
|
float32 s1; // scale y
|
|
float32 skew; // skew
|
|
float32 x; // x pos
|
|
float32 y; // y pos
|
|
};
|
|
|
|
struct UVAnimKeyFrame
|
|
{
|
|
UVAnimKeyFrame *prev;
|
|
float32 time;
|
|
float32 uv[6];
|
|
};
|
|
|
|
struct UVAnimInterpFrame
|
|
{
|
|
UVAnimKeyFrame *keyFrame1;
|
|
UVAnimKeyFrame *keyFrame2;
|
|
float32 uv[6];
|
|
};
|
|
|
|
struct UVAnimDictionary;
|
|
|
|
// RW does it differently...maybe we should implement RtDict
|
|
// and make it more general?
|
|
|
|
struct UVAnimCustomData
|
|
{
|
|
char name[32];
|
|
int32 nodeToUVChannel[8];
|
|
int32 refCount;
|
|
|
|
void destroy(Animation *anim);
|
|
static UVAnimCustomData *get(Animation *anim){
|
|
return (UVAnimCustomData*)anim->customData; }
|
|
};
|
|
|
|
// This should be more general probably
|
|
struct UVAnimDictEntry
|
|
{
|
|
Animation *anim;
|
|
LLLink inDict;
|
|
static UVAnimDictEntry *fromDict(LLLink *lnk){
|
|
return LLLinkGetData(lnk, UVAnimDictEntry, inDict); }
|
|
};
|
|
|
|
// This too
|
|
struct UVAnimDictionary
|
|
{
|
|
LinkList animations;
|
|
|
|
static UVAnimDictionary *create(void);
|
|
void destroy(void);
|
|
int32 count(void) { return this->animations.count(); }
|
|
void add(Animation *anim);
|
|
Animation *find(const char *name);
|
|
|
|
static UVAnimDictionary *streamRead(Stream *stream);
|
|
bool streamWrite(Stream *stream);
|
|
uint32 streamGetSize(void);
|
|
};
|
|
|
|
extern UVAnimDictionary *currentUVAnimDictionary;
|
|
|
|
// Material plugin
|
|
struct UVAnim
|
|
{
|
|
Matrix *uv[2];
|
|
AnimInterpolator *interp[8];
|
|
|
|
static bool32 exists(Material *mat);
|
|
static void addTime(Material *mat, float32 t);
|
|
static void applyUpdate(Material *mat);
|
|
};
|
|
|
|
extern int32 uvAnimOffset;
|
|
|
|
void registerUVAnimPlugin(void);
|
|
|
|
}
|