-
Notifications
You must be signed in to change notification settings - Fork 100
/
rwanim.h
195 lines (163 loc) · 4.54 KB
/
rwanim.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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);
}