diff options
| author | claude-bot <[email protected]> | 2026-07-13 12:40:03 +0000 |
|---|---|---|
| committer | claude-bot <[email protected]> | 2026-07-13 12:40:03 +0000 |
| commit | 847962910f0bff071f3bf07c9abb87764fb6cac3 (patch) | |
| tree | ddcd429e134c7fd5f72ddc97ced175de8d66fcd0 /src/rwanim.h | |
| download | librw-master.tar.gz librw-master.zip | |
Snapshot for re3/reVC vendoring, per @lzcnt.
Source: https://github.com/aap/librw (master).
Diffstat (limited to 'src/rwanim.h')
| -rw-r--r-- | src/rwanim.h | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/rwanim.h b/src/rwanim.h new file mode 100644 index 0000000..e6dd1d5 --- /dev/null +++ b/src/rwanim.h @@ -0,0 +1,195 @@ +#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); + +} |
