animation compression from PS2
This commit is contained in:
parent
5335b46cbb
commit
3564b85b4e
@ -13,7 +13,7 @@ enum {
|
|||||||
ASSOC_MOVEMENT = 0x20, // ???
|
ASSOC_MOVEMENT = 0x20, // ???
|
||||||
ASSOC_HAS_TRANSLATION = 0x40,
|
ASSOC_HAS_TRANSLATION = 0x40,
|
||||||
ASSOC_WALK = 0x80, // for CPed::PlayFootSteps(void)
|
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_NOWALK = 0x200, // see CPed::PlayFootSteps(void)
|
||||||
ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
|
ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
|
||||||
ASSOC_FRONTAL = 0x800, // anims that we fall to front
|
ASSOC_FRONTAL = 0x800, // anims that we fall to front
|
||||||
|
@ -30,15 +30,14 @@ void
|
|||||||
CAnimBlendHierarchy::CalcTotalTime(void)
|
CAnimBlendHierarchy::CalcTotalTime(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
float totalTime = 0.0f;
|
totalLength = 0.0f;
|
||||||
|
|
||||||
for(i = 0; i < numSequences; i++){
|
for(i = 0; i < numSequences; i++){
|
||||||
float seqTime = 0.0f;
|
float seqTime = 0.0f;
|
||||||
for(j = 0; j < sequences[i].numFrames; j++)
|
for(j = 0; j < sequences[i].numFrames; j++)
|
||||||
seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
|
seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
|
||||||
totalTime = Max(totalTime, seqTime);
|
totalLength = Max(totalLength, seqTime);
|
||||||
}
|
}
|
||||||
totalLength = totalTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -61,6 +60,12 @@ CAnimBlendHierarchy::RemoveAnimSequences(void)
|
|||||||
void
|
void
|
||||||
CAnimBlendHierarchy::Uncompress(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)
|
if(totalLength == 0.0f)
|
||||||
CalcTotalTime();
|
CalcTotalTime();
|
||||||
compressed = 0;
|
compressed = 0;
|
||||||
@ -69,6 +74,11 @@ CAnimBlendHierarchy::Uncompress(void)
|
|||||||
void
|
void
|
||||||
CAnimBlendHierarchy::RemoveUncompressedData(void)
|
CAnimBlendHierarchy::RemoveUncompressedData(void)
|
||||||
{
|
{
|
||||||
// useless
|
#ifdef ANIM_COMPRESSION
|
||||||
|
int i;
|
||||||
|
assert(!compressed);
|
||||||
|
for(i = 0; i < numSequences; i++)
|
||||||
|
sequences[i].RemoveUncompressedData();
|
||||||
|
#endif
|
||||||
compressed = 1;
|
compressed = 1;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ CAnimBlendSequence::CAnimBlendSequence(void)
|
|||||||
|
|
||||||
CAnimBlendSequence::~CAnimBlendSequence(void)
|
CAnimBlendSequence::~CAnimBlendSequence(void)
|
||||||
{
|
{
|
||||||
|
assert(keyFramesCompressed == nil);
|
||||||
if(keyFrames)
|
if(keyFrames)
|
||||||
RwFree(keyFrames);
|
RwFree(keyFrames);
|
||||||
}
|
}
|
||||||
@ -60,3 +61,106 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
|
|||||||
last = frame->rotation;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,15 @@ struct KeyFrameTrans : KeyFrame {
|
|||||||
CVector translation;
|
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
|
// The sequence of key frames of one animated node
|
||||||
class CAnimBlendSequence
|
class CAnimBlendSequence
|
||||||
@ -41,10 +50,9 @@ public:
|
|||||||
&((KeyFrame*)keyFrames)[n];
|
&((KeyFrame*)keyFrames)[n];
|
||||||
}
|
}
|
||||||
bool HasTranslation(void) { return !!(type & KF_TRANS); }
|
bool HasTranslation(void) { return !!(type & KF_TRANS); }
|
||||||
// TODO? these are unused
|
void Uncompress(void);
|
||||||
// void Uncompress(void);
|
void CompressKeyframes(void);
|
||||||
// void CompressKeyframes(void);
|
void RemoveUncompressedData(void);
|
||||||
// void RemoveUncompressedData(void);
|
|
||||||
|
|
||||||
#ifdef PED_SKIN
|
#ifdef PED_SKIN
|
||||||
void SetBoneTag(int tag) { boneTag = tag; }
|
void SetBoneTag(int tag) { boneTag = tag; }
|
||||||
|
@ -176,7 +176,7 @@ AnimAssocDesc aStdAnimDescs[] = {
|
|||||||
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
|
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
|
||||||
{ ANIM_EV_STEP, 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_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_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
|
||||||
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
|
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
|
||||||
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
|
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
|
||||||
|
@ -177,6 +177,7 @@ enum Config {
|
|||||||
# define GTA_PS2_STUFF
|
# define GTA_PS2_STUFF
|
||||||
# define RANDOMSPLASH
|
# define RANDOMSPLASH
|
||||||
# define VU_COLLISION
|
# define VU_COLLISION
|
||||||
|
# define ANIM_COMPRESSION
|
||||||
#elif defined GTA_PC
|
#elif defined GTA_PC
|
||||||
# define GTA3_1_1_PATCH
|
# define GTA3_1_1_PATCH
|
||||||
//# define GTA3_STEAM_PATCH
|
//# define GTA3_STEAM_PATCH
|
||||||
|
Loading…
Reference in New Issue
Block a user