summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/AnimBlendAssociation.h2
-rw-r--r--src/animation/AnimBlendHierarchy.cpp18
-rw-r--r--src/animation/AnimBlendSequence.cpp104
-rw-r--r--src/animation/AnimBlendSequence.h16
-rw-r--r--src/animation/AnimManager.cpp2
5 files changed, 132 insertions, 10 deletions
diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h
index 2dff4391..80927da2 100644
--- a/src/animation/AnimBlendAssociation.h
+++ b/src/animation/AnimBlendAssociation.h
@@ -13,7 +13,7 @@ enum {
ASSOC_MOVEMENT = 0x20, // ???
ASSOC_HAS_TRANSLATION = 0x40,
ASSOC_WALK = 0x80, // for CPed::PlayFootSteps(void)
- ASSOC_FLAG_XPRESS = 0x100, // only used by xpress scratch, see CPed::Chat(void)
+ ASSOC_IDLE = 0x100, // only used by xpress scratch, see CPed::Chat(void)
ASSOC_NOWALK = 0x200, // see CPed::PlayFootSteps(void)
ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
ASSOC_FRONTAL = 0x800, // anims that we fall to front
diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp
index feeaca3d..67b19019 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -30,15 +30,14 @@ void
CAnimBlendHierarchy::CalcTotalTime(void)
{
int i, j;
- float totalTime = 0.0f;
+ totalLength = 0.0f;
for(i = 0; i < numSequences; i++){
float seqTime = 0.0f;
for(j = 0; j < sequences[i].numFrames; j++)
seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
- totalTime = Max(totalTime, seqTime);
+ totalLength = Max(totalLength, seqTime);
}
- totalLength = totalTime;
}
void
@@ -61,6 +60,12 @@ CAnimBlendHierarchy::RemoveAnimSequences(void)
void
CAnimBlendHierarchy::Uncompress(void)
{
+#ifdef ANIM_COMPRESSION
+ int i;
+ assert(compressed);
+ for(i = 0; i < numSequences; i++)
+ sequences[i].Uncompress();
+#endif
if(totalLength == 0.0f)
CalcTotalTime();
compressed = 0;
@@ -69,6 +74,11 @@ CAnimBlendHierarchy::Uncompress(void)
void
CAnimBlendHierarchy::RemoveUncompressedData(void)
{
- // useless
+#ifdef ANIM_COMPRESSION
+ int i;
+ assert(!compressed);
+ for(i = 0; i < numSequences; i++)
+ sequences[i].RemoveUncompressedData();
+#endif
compressed = 1;
}
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index 4578ec50..d35fbc46 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -15,6 +15,7 @@ CAnimBlendSequence::CAnimBlendSequence(void)
CAnimBlendSequence::~CAnimBlendSequence(void)
{
+ assert(keyFramesCompressed == nil);
if(keyFrames)
RwFree(keyFrames);
}
@@ -60,3 +61,106 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
last = frame->rotation;
}
}
+
+void
+CAnimBlendSequence::Uncompress(void)
+{
+ int i;
+
+ if(numFrames == 0)
+ return;
+
+ float rotScale = 1.0f/4096.0f;
+ float timeScale = 1.0f/60.0f;
+ float transScale = 1.0f/128.0f;
+ if(type & KF_TRANS){
+ void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans));
+ KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed;
+ KeyFrameTrans *kf = (KeyFrameTrans*)newKfs;
+ for(i = 0; i < numFrames; i++){
+ kf->rotation.x = ckf->rot[0]*rotScale;
+ kf->rotation.y = ckf->rot[1]*rotScale;
+ kf->rotation.z = ckf->rot[2]*rotScale;
+ kf->rotation.w = ckf->rot[3]*rotScale;
+ kf->deltaTime = ckf->deltaTime*timeScale;
+ kf->translation.x = ckf->trans[0]*transScale;
+ kf->translation.y = ckf->trans[1]*transScale;
+ kf->translation.z = ckf->trans[2]*transScale;
+ kf++;
+ ckf++;
+ }
+ keyFrames = newKfs;
+ }else{
+ void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame));
+ KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed;
+ KeyFrame *kf = (KeyFrame*)newKfs;
+ for(i = 0; i < numFrames; i++){
+ kf->rotation.x = ckf->rot[0]*rotScale;
+ kf->rotation.y = ckf->rot[1]*rotScale;
+ kf->rotation.z = ckf->rot[2]*rotScale;
+ kf->rotation.w = ckf->rot[3]*rotScale;
+ kf->deltaTime = ckf->deltaTime*timeScale;
+ kf++;
+ ckf++;
+ }
+ keyFrames = newKfs;
+ }
+ RwFree(keyFramesCompressed);
+ keyFramesCompressed = nil;
+}
+
+void
+CAnimBlendSequence::CompressKeyframes(void)
+{
+ int i;
+
+ if(numFrames == 0)
+ return;
+
+ float rotScale = 4096.0f;
+ float timeScale = 60.0f;
+ float transScale = 128.0f;
+ if(type & KF_TRANS){
+ void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed));
+ KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs;
+ KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames;
+ for(i = 0; i < numFrames; i++){
+ ckf->rot[0] = kf->rotation.x*rotScale;
+ ckf->rot[1] = kf->rotation.y*rotScale;
+ ckf->rot[2] = kf->rotation.z*rotScale;
+ ckf->rot[3] = kf->rotation.w*rotScale;
+ ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
+ ckf->trans[0] = kf->translation.x*transScale;
+ ckf->trans[1] = kf->translation.y*transScale;
+ ckf->trans[2] = kf->translation.z*transScale;
+ kf++;
+ ckf++;
+ }
+ keyFramesCompressed = newKfs;
+ }else{
+ void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed));
+ KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs;
+ KeyFrame *kf = (KeyFrame*)keyFrames;
+ for(i = 0; i < numFrames; i++){
+ ckf->rot[0] = kf->rotation.x*rotScale;
+ ckf->rot[1] = kf->rotation.y*rotScale;
+ ckf->rot[2] = kf->rotation.z*rotScale;
+ ckf->rot[3] = kf->rotation.w*rotScale;
+ ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
+ kf++;
+ ckf++;
+ }
+ keyFramesCompressed = newKfs;
+ }
+}
+
+void
+CAnimBlendSequence::RemoveUncompressedData(void)
+{
+ if(numFrames == 0)
+ return;
+ CompressKeyframes();
+ RwFree(keyFrames);
+ keyFrames = nil;
+}
+
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index 44ac8886..e51e5aaa 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -12,6 +12,15 @@ struct KeyFrameTrans : KeyFrame {
CVector translation;
};
+struct KeyFrameCompressed {
+ int16 rot[4]; // 4096
+ int16 deltaTime; // 60
+};
+
+struct KeyFrameTransCompressed : KeyFrameCompressed {
+ int16 trans[3]; // 128
+};
+
// The sequence of key frames of one animated node
class CAnimBlendSequence
@@ -41,10 +50,9 @@ public:
&((KeyFrame*)keyFrames)[n];
}
bool HasTranslation(void) { return !!(type & KF_TRANS); }
- // TODO? these are unused
-// void Uncompress(void);
-// void CompressKeyframes(void);
-// void RemoveUncompressedData(void);
+ void Uncompress(void);
+ void CompressKeyframes(void);
+ void RemoveUncompressedData(void);
#ifdef PED_SKIN
void SetBoneTag(int tag) { boneTag = tag; }
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp
index 444b6d45..877dcd76 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -176,7 +176,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_FLAG_XPRESS },
+ { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },