mirror of
https://github.com/halpz/re3.git
synced 2024-12-24 17:55:29 +00:00
commit
6697ab6b63
|
@ -139,11 +139,15 @@ CAnimBlendAssociation::SetCurrentTime(float time)
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimManager::UncompressAnimation(hierarchy);
|
CAnimManager::UncompressAnimation(hierarchy);
|
||||||
if(hierarchy->compressed2){
|
#ifdef ANIM_COMPRESSION
|
||||||
|
// strangely PC has this but android doesn't
|
||||||
|
if(hierarchy->keepCompressed){
|
||||||
for(i = 0; i < numNodes; i++)
|
for(i = 0; i < numNodes; i++)
|
||||||
if(nodes[i].sequence)
|
if(nodes[i].sequence)
|
||||||
nodes[i].SetupKeyFrameCompressed();
|
nodes[i].SetupKeyFrameCompressed();
|
||||||
}else{
|
}else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
for(i = 0; i < numNodes; i++)
|
for(i = 0; i < numNodes; i++)
|
||||||
if(nodes[i].sequence)
|
if(nodes[i].sequence)
|
||||||
nodes[i].FindKeyFrame(currentTime);
|
nodes[i].FindKeyFrame(currentTime);
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct AnimBlendFrameData
|
||||||
VELOCITY_EXTRACTION = 8,
|
VELOCITY_EXTRACTION = 8,
|
||||||
VELOCITY_EXTRACTION_3D = 0x10,
|
VELOCITY_EXTRACTION_3D = 0x10,
|
||||||
UPDATE_KEYFRAMES = 0x20,
|
UPDATE_KEYFRAMES = 0x20,
|
||||||
UNK_COMPRESSED = 0x40,
|
COMPRESSED = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 flag;
|
uint8 flag;
|
||||||
|
|
|
@ -65,10 +65,10 @@ CAnimBlendHierarchy::CalcTotalTimeCompressed(void)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->deltaTime/60.0f);
|
totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->GetDeltaTime());
|
||||||
for(j = sequences[i].numFrames-1; j >= 1; j--){
|
for(j = sequences[i].numFrames-1; j >= 1; j--){
|
||||||
KeyFrame *kf1 = sequences[i].GetKeyFrameCompressed(j);
|
KeyFrameCompressed *kf1 = sequences[i].GetKeyFrameCompressed(j);
|
||||||
KeyFrame *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
|
KeyFrameCompressed *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
|
||||||
kf1->deltaTime -= kf2->deltaTime;
|
kf1->deltaTime -= kf2->deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,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
|
||||||
compressed = 0;
|
compressed = 0;
|
||||||
if(totalLength == 0.0f){
|
if(totalLength == 0.0f){
|
||||||
RemoveQuaternionFlips();
|
RemoveQuaternionFlips();
|
||||||
|
@ -104,7 +110,12 @@ 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,8 +15,8 @@ public:
|
||||||
char name[24];
|
char name[24];
|
||||||
CAnimBlendSequence *sequences;
|
CAnimBlendSequence *sequences;
|
||||||
int16 numSequences;
|
int16 numSequences;
|
||||||
bool compressed; // not really used
|
bool compressed;
|
||||||
bool compressed2; // not really used
|
bool keepCompressed;
|
||||||
float totalLength;
|
float totalLength;
|
||||||
CLink<CAnimBlendHierarchy*> *linkPtr;
|
CLink<CAnimBlendHierarchy*> *linkPtr;
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,44 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight)
|
||||||
return looped;
|
return looped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight)
|
||||||
|
{
|
||||||
|
bool looped = false;
|
||||||
|
|
||||||
|
trans = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
if(association->IsRunning()){
|
||||||
|
remainingTime -= association->timeStep;
|
||||||
|
if(remainingTime <= 0.0f)
|
||||||
|
looped = NextKeyFrameCompressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
float blend = association->GetBlendAmount(weight);
|
||||||
|
if(blend > 0.0f){
|
||||||
|
KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
|
||||||
|
KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
|
||||||
|
float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
|
||||||
|
if(sequence->type & CAnimBlendSequence::KF_TRANS){
|
||||||
|
CVector transA, transB;
|
||||||
|
kfA->GetTranslation(&transA);
|
||||||
|
kfB->GetTranslation(&transB);
|
||||||
|
trans = transB + t*(transA - transB);
|
||||||
|
trans *= blend;
|
||||||
|
}
|
||||||
|
if(sequence->type & CAnimBlendSequence::KF_ROT){
|
||||||
|
CQuaternion rotA, rotB;
|
||||||
|
kfA->GetRotation(&rotA);
|
||||||
|
kfB->GetRotation(&rotB);
|
||||||
|
rot.Slerp(rotB, rotA, theta, invSin, t);
|
||||||
|
rot *= blend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return looped;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CAnimBlendNode::NextKeyFrame(void)
|
CAnimBlendNode::NextKeyFrame(void)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +122,43 @@ CAnimBlendNode::NextKeyFrame(void)
|
||||||
return looped;
|
return looped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAnimBlendNode::NextKeyFrameCompressed(void)
|
||||||
|
{
|
||||||
|
bool looped;
|
||||||
|
|
||||||
|
if(sequence->numFrames <= 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
looped = false;
|
||||||
|
frameB = frameA;
|
||||||
|
|
||||||
|
// Advance as long as we have to
|
||||||
|
while(remainingTime <= 0.0f){
|
||||||
|
frameA++;
|
||||||
|
|
||||||
|
if(frameA >= sequence->numFrames){
|
||||||
|
// reached end of animation
|
||||||
|
if(!association->IsRepeating()){
|
||||||
|
frameA--;
|
||||||
|
remainingTime = 0.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
looped = true;
|
||||||
|
frameA = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
frameB = frameA - 1;
|
||||||
|
if(frameB < 0)
|
||||||
|
frameB += sequence->numFrames;
|
||||||
|
|
||||||
|
CalcDeltasCompressed();
|
||||||
|
return looped;
|
||||||
|
}
|
||||||
|
|
||||||
// Set animation to time t
|
// Set animation to time t
|
||||||
bool
|
bool
|
||||||
CAnimBlendNode::FindKeyFrame(float t)
|
CAnimBlendNode::FindKeyFrame(float t)
|
||||||
|
@ -132,7 +207,7 @@ CAnimBlendNode::SetupKeyFrameCompressed(void)
|
||||||
frameA = 0;
|
frameA = 0;
|
||||||
remainingTime = 0.0f;
|
remainingTime = 0.0f;
|
||||||
}else
|
}else
|
||||||
remainingTime = sequence->GetKeyFrameCompressed(frameA)->deltaTime/60.0f;
|
remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
|
||||||
|
|
||||||
CalcDeltasCompressed();
|
CalcDeltasCompressed();
|
||||||
return true;
|
return true;
|
||||||
|
@ -157,9 +232,17 @@ CAnimBlendNode::CalcDeltasCompressed(void)
|
||||||
{
|
{
|
||||||
if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
|
if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
|
||||||
return;
|
return;
|
||||||
KeyFrame *kfA = sequence->GetKeyFrameCompressed(frameA);
|
KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA);
|
||||||
KeyFrame *kfB = sequence->GetKeyFrameCompressed(frameB);
|
KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB);
|
||||||
float cos = DotProduct(kfA->rotation, kfB->rotation);
|
CQuaternion rotA, rotB;
|
||||||
|
kfA->GetRotation(&rotA);
|
||||||
|
kfB->GetRotation(&rotB);
|
||||||
|
float cos = DotProduct(rotA, rotB);
|
||||||
|
if(cos < 0.0f){
|
||||||
|
rotB *= -1.0f;
|
||||||
|
kfB->SetRotation(rotB);
|
||||||
|
}
|
||||||
|
cos = DotProduct(rotA, rotB);
|
||||||
if(cos > 1.0f)
|
if(cos > 1.0f)
|
||||||
cos = 1.0f;
|
cos = 1.0f;
|
||||||
theta = Acos(cos);
|
theta = Acos(cos);
|
||||||
|
@ -183,6 +266,26 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight)
|
||||||
|
{
|
||||||
|
trans = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
float blend = association->GetBlendAmount(weight);
|
||||||
|
if(blend > 0.0f){
|
||||||
|
KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
|
||||||
|
KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
|
||||||
|
float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
|
||||||
|
if(sequence->type & CAnimBlendSequence::KF_TRANS){
|
||||||
|
CVector transA, transB;
|
||||||
|
kfA->GetTranslation(&transA);
|
||||||
|
kfB->GetTranslation(&transB);
|
||||||
|
trans = transB + t*(transA - transB);
|
||||||
|
trans *= blend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
|
CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
|
||||||
{
|
{
|
||||||
|
@ -195,3 +298,19 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
|
||||||
trans = kf->translation * blend;
|
trans = kf->translation * blend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight)
|
||||||
|
{
|
||||||
|
trans = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
float blend = association->GetBlendAmount(weight);
|
||||||
|
if(blend > 0.0f){
|
||||||
|
KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1);
|
||||||
|
if(sequence->type & CAnimBlendSequence::KF_TRANS){
|
||||||
|
CVector trans;
|
||||||
|
kf->GetTranslation(&trans);
|
||||||
|
trans = trans * blend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,13 +20,17 @@ public:
|
||||||
|
|
||||||
void Init(void);
|
void Init(void);
|
||||||
bool Update(CVector &trans, CQuaternion &rot, float weight);
|
bool Update(CVector &trans, CQuaternion &rot, float weight);
|
||||||
|
bool UpdateCompressed(CVector &trans, CQuaternion &rot, float weight);
|
||||||
bool NextKeyFrame(void);
|
bool NextKeyFrame(void);
|
||||||
|
bool NextKeyFrameCompressed(void);
|
||||||
bool FindKeyFrame(float t);
|
bool FindKeyFrame(float t);
|
||||||
bool SetupKeyFrameCompressed(void);
|
bool SetupKeyFrameCompressed(void);
|
||||||
void CalcDeltas(void);
|
void CalcDeltas(void);
|
||||||
void CalcDeltasCompressed(void);
|
void CalcDeltasCompressed(void);
|
||||||
void GetCurrentTranslation(CVector &trans, float weight);
|
void GetCurrentTranslation(CVector &trans, float weight);
|
||||||
|
void GetCurrentTranslationCompressed(CVector &trans, float weight);
|
||||||
void GetEndTranslation(CVector &trans, float weight);
|
void GetEndTranslation(CVector &trans, float weight);
|
||||||
|
void GetEndTranslationCompressed(CVector &trans, float weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,119 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAnimBlendSequence::Uncompress(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(numFrames == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PUSH_MEMID(MEMID_ANIMATION);
|
||||||
|
|
||||||
|
float rotScale = 1.0f/4096.0f;
|
||||||
|
float timeScale = 1.0f/60.0f;
|
||||||
|
float transScale = 1.0f/1024.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;
|
||||||
|
}
|
||||||
|
REGISTER_MEMPTR(&keyFrames);
|
||||||
|
|
||||||
|
RwFree(keyFramesCompressed);
|
||||||
|
keyFramesCompressed = nil;
|
||||||
|
|
||||||
|
POP_MEMID();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAnimBlendSequence::CompressKeyframes(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(numFrames == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PUSH_MEMID(MEMID_ANIMATION);
|
||||||
|
|
||||||
|
float rotScale = 4096.0f;
|
||||||
|
float timeScale = 60.0f;
|
||||||
|
float transScale = 1024.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;
|
||||||
|
}
|
||||||
|
REGISTER_MEMPTR(&keyFramesCompressed);
|
||||||
|
|
||||||
|
POP_MEMID();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAnimBlendSequence::RemoveUncompressedData(void)
|
||||||
|
{
|
||||||
|
if(numFrames == 0)
|
||||||
|
return;
|
||||||
|
CompressKeyframes();
|
||||||
|
RwFree(keyFrames);
|
||||||
|
keyFrames = nil;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_CUSTOM_ALLOCATOR
|
#ifdef USE_CUSTOM_ALLOCATOR
|
||||||
bool
|
bool
|
||||||
CAnimBlendSequence::MoveMemory(void)
|
CAnimBlendSequence::MoveMemory(void)
|
||||||
|
@ -87,4 +200,3 @@ CAnimBlendSequence::MoveMemory(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,43 @@ struct KeyFrameTrans : KeyFrame {
|
||||||
CVector translation;
|
CVector translation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeyFrameCompressed {
|
||||||
|
int16 rot[4]; // 4096
|
||||||
|
int16 deltaTime; // 60
|
||||||
|
|
||||||
|
void GetRotation(CQuaternion *quat){
|
||||||
|
float scale = 1.0f/4096.0f;
|
||||||
|
quat->x = rot[0]*scale;
|
||||||
|
quat->y = rot[1]*scale;
|
||||||
|
quat->z = rot[2]*scale;
|
||||||
|
quat->w = rot[3]*scale;
|
||||||
|
}
|
||||||
|
void SetRotation(const CQuaternion &quat){
|
||||||
|
rot[0] = quat.x * 4096.0f;
|
||||||
|
rot[1] = quat.y * 4096.0f;
|
||||||
|
rot[2] = quat.z * 4096.0f;
|
||||||
|
rot[3] = quat.w * 4096.0f;
|
||||||
|
}
|
||||||
|
float GetDeltaTime(void) { return deltaTime/60.0f; }
|
||||||
|
void SetTime(float t) { deltaTime = t*60.0f + 0.5f; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyFrameTransCompressed : KeyFrameCompressed {
|
||||||
|
int16 trans[3]; // 1024
|
||||||
|
|
||||||
|
void GetTranslation(CVector *vec) {
|
||||||
|
float scale = 1.0f/1024.0f;
|
||||||
|
vec->x = trans[0]*scale;
|
||||||
|
vec->y = trans[1]*scale;
|
||||||
|
vec->z = trans[2]*scale;
|
||||||
|
}
|
||||||
|
void SetTranslation(const CVector &vec){
|
||||||
|
trans[0] = vec.x*1024.0f;
|
||||||
|
trans[1] = vec.y*1024.0f;
|
||||||
|
trans[2] = vec.z*1024.0f;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// The sequence of key frames of one animated node
|
// The sequence of key frames of one animated node
|
||||||
class CAnimBlendSequence
|
class CAnimBlendSequence
|
||||||
|
@ -42,12 +79,15 @@ public:
|
||||||
&((KeyFrameTrans*)keyFrames)[n] :
|
&((KeyFrameTrans*)keyFrames)[n] :
|
||||||
&((KeyFrame*)keyFrames)[n];
|
&((KeyFrame*)keyFrames)[n];
|
||||||
}
|
}
|
||||||
KeyFrame *GetKeyFrameCompressed(int n) {
|
KeyFrameCompressed *GetKeyFrameCompressed(int n) {
|
||||||
return type & KF_TRANS ?
|
return type & KF_TRANS ?
|
||||||
&((KeyFrameTrans*)keyFramesCompressed)[n] :
|
&((KeyFrameTransCompressed*)keyFramesCompressed)[n] :
|
||||||
&((KeyFrame*)keyFramesCompressed)[n];
|
&((KeyFrameCompressed*)keyFramesCompressed)[n];
|
||||||
}
|
}
|
||||||
bool HasTranslation(void) { return !!(type & KF_TRANS); }
|
bool HasTranslation(void) { return !!(type & KF_TRANS); }
|
||||||
|
void Uncompress(void);
|
||||||
|
void CompressKeyframes(void);
|
||||||
|
void RemoveUncompressedData(void);
|
||||||
bool MoveMemory(void);
|
bool MoveMemory(void);
|
||||||
|
|
||||||
void SetBoneTag(int tag) { boneTag = tag; }
|
void SetBoneTag(int tag) { boneTag = tag; }
|
||||||
|
|
|
@ -992,7 +992,7 @@ CAnimManager::Shutdown(void)
|
||||||
void
|
void
|
||||||
CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier)
|
CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier)
|
||||||
{
|
{
|
||||||
if(hier->compressed2){
|
if(hier->keepCompressed){
|
||||||
if(hier->totalLength == 0.0f)
|
if(hier->totalLength == 0.0f)
|
||||||
hier->CalcTotalTimeCompressed();
|
hier->CalcTotalTimeCompressed();
|
||||||
}else{
|
}else{
|
||||||
|
@ -1275,7 +1275,7 @@ CAnimManager::LoadAnimFile(const char *filename)
|
||||||
|
|
||||||
//--MIAMI: done
|
//--MIAMI: done
|
||||||
void
|
void
|
||||||
CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32])
|
CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32])
|
||||||
{
|
{
|
||||||
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
|
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
|
||||||
struct IfpHeader {
|
struct IfpHeader {
|
||||||
|
@ -1320,16 +1320,22 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]
|
||||||
RwStreamRead(stream, buf, name.size);
|
RwStreamRead(stream, buf, name.size);
|
||||||
hier->SetName(buf);
|
hier->SetName(buf);
|
||||||
|
|
||||||
// Unimplemented uncompressed anim thing
|
#ifdef ANIM_COMPRESSION
|
||||||
if (somename) {
|
bool compressHier = compress;
|
||||||
for (int i = 0; somename[i][0]; i++) {
|
#else
|
||||||
if (!CGeneral::faststricmp(somename[i], hier->name))
|
bool compressHier = false;
|
||||||
|
#endif
|
||||||
|
if (uncompressedAnims) {
|
||||||
|
for (int i = 0; uncompressedAnims[i][0]; i++) {
|
||||||
|
if (!CGeneral::faststricmp(uncompressedAnims[i], hier->name)){
|
||||||
debug("Loading %s uncompressed\n", hier->name);
|
debug("Loading %s uncompressed\n", hier->name);
|
||||||
|
compressHier = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hier->compressed = false;
|
hier->compressed = compressHier;
|
||||||
hier->compressed2 = false;
|
hier->keepCompressed = false;
|
||||||
|
|
||||||
// DG info has number of nodes/sequences
|
// DG info has number of nodes/sequences
|
||||||
RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader));
|
RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader));
|
||||||
|
@ -1349,67 +1355,86 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]
|
||||||
ROUNDSIZE(anim.size);
|
ROUNDSIZE(anim.size);
|
||||||
RwStreamRead(stream, buf, anim.size);
|
RwStreamRead(stream, buf, anim.size);
|
||||||
int numFrames = *(int*)(buf+28);
|
int numFrames = *(int*)(buf+28);
|
||||||
|
seq->SetName(buf);
|
||||||
if(anim.size == 44)
|
if(anim.size == 44)
|
||||||
seq->SetBoneTag(*(int*)(buf+40));
|
seq->SetBoneTag(*(int*)(buf+40));
|
||||||
seq->SetName(buf);
|
|
||||||
if(numFrames == 0)
|
if(numFrames == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool hasScale = false;
|
||||||
|
bool hasTranslation = false;
|
||||||
RwStreamRead(stream, &info, sizeof(info));
|
RwStreamRead(stream, &info, sizeof(info));
|
||||||
if(strncmp(info.ident, "KR00", 4) == 0){
|
if(strncmp(info.ident, "KRTS", 4) == 0){
|
||||||
seq->SetNumFrames(numFrames, false, false);
|
hasScale = true;
|
||||||
KeyFrame *kf = seq->GetKeyFrame(0);
|
seq->SetNumFrames(numFrames, true, compressHier);
|
||||||
if (strstr(seq->name, "L Toe"))
|
|
||||||
debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
|
|
||||||
|
|
||||||
for(l = 0; l < numFrames; l++, kf++){
|
|
||||||
RwStreamRead(stream, buf, 0x14);
|
|
||||||
kf->rotation.x = -fbuf[0];
|
|
||||||
kf->rotation.y = -fbuf[1];
|
|
||||||
kf->rotation.z = -fbuf[2];
|
|
||||||
kf->rotation.w = fbuf[3];
|
|
||||||
kf->deltaTime = fbuf[4]; // absolute time here
|
|
||||||
}
|
|
||||||
}else if(strncmp(info.ident, "KRT0", 4) == 0){
|
}else if(strncmp(info.ident, "KRT0", 4) == 0){
|
||||||
seq->SetNumFrames(numFrames, true, false);
|
hasTranslation = true;
|
||||||
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
|
seq->SetNumFrames(numFrames, true, compressHier);
|
||||||
if (strstr(seq->name, "L Toe"))
|
}else if(strncmp(info.ident, "KR00", 4) == 0){
|
||||||
debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
|
seq->SetNumFrames(numFrames, false, compressHier);
|
||||||
|
}
|
||||||
|
if(strstr(seq->name, "L Toe"))
|
||||||
|
debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name
|
||||||
|
|
||||||
for(l = 0; l < numFrames; l++, kf++){
|
for(l = 0; l < numFrames; l++){
|
||||||
RwStreamRead(stream, buf, 0x20);
|
if(hasScale){
|
||||||
kf->rotation.x = -fbuf[0];
|
|
||||||
kf->rotation.y = -fbuf[1];
|
|
||||||
kf->rotation.z = -fbuf[2];
|
|
||||||
kf->rotation.w = fbuf[3];
|
|
||||||
kf->translation.x = fbuf[4];
|
|
||||||
kf->translation.y = fbuf[5];
|
|
||||||
kf->translation.z = fbuf[6];
|
|
||||||
kf->deltaTime = fbuf[7]; // absolute time here
|
|
||||||
}
|
|
||||||
}else if(strncmp(info.ident, "KRTS", 4) == 0){
|
|
||||||
seq->SetNumFrames(numFrames, true, false);
|
|
||||||
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
|
|
||||||
if (strstr(seq->name, "L Toe"))
|
|
||||||
debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
|
|
||||||
|
|
||||||
for(l = 0; l < numFrames; l++, kf++){
|
|
||||||
RwStreamRead(stream, buf, 0x2C);
|
RwStreamRead(stream, buf, 0x2C);
|
||||||
kf->rotation.x = -fbuf[0];
|
CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
|
||||||
kf->rotation.y = -fbuf[1];
|
rot.Invert();
|
||||||
kf->rotation.z = -fbuf[2];
|
CVector trans(fbuf[4], fbuf[5], fbuf[6]);
|
||||||
kf->rotation.w = fbuf[3];
|
|
||||||
kf->translation.x = fbuf[4];
|
if(compressHier){
|
||||||
kf->translation.y = fbuf[5];
|
KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
|
||||||
kf->translation.z = fbuf[6];
|
kf->SetRotation(rot);
|
||||||
// scaling ignored
|
kf->SetTranslation(trans);
|
||||||
kf->deltaTime = fbuf[10]; // absolute time here
|
// scaling ignored
|
||||||
|
kf->SetTime(fbuf[10]); // absolute time here
|
||||||
|
}else{
|
||||||
|
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
|
||||||
|
kf->rotation = rot;
|
||||||
|
kf->translation = trans;
|
||||||
|
// scaling ignored
|
||||||
|
kf->deltaTime = fbuf[10]; // absolute time here
|
||||||
|
}
|
||||||
|
}else if(hasTranslation){
|
||||||
|
RwStreamRead(stream, buf, 0x20);
|
||||||
|
CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
|
||||||
|
rot.Invert();
|
||||||
|
CVector trans(fbuf[4], fbuf[5], fbuf[6]);
|
||||||
|
|
||||||
|
if(compressHier){
|
||||||
|
KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
|
||||||
|
kf->SetRotation(rot);
|
||||||
|
kf->SetTranslation(trans);
|
||||||
|
kf->SetTime(fbuf[7]); // absolute time here
|
||||||
|
}else{
|
||||||
|
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
|
||||||
|
kf->rotation = rot;
|
||||||
|
kf->translation = trans;
|
||||||
|
kf->deltaTime = fbuf[7]; // absolute time here
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
RwStreamRead(stream, buf, 0x14);
|
||||||
|
CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
|
||||||
|
rot.Invert();
|
||||||
|
|
||||||
|
if(compressHier){
|
||||||
|
KeyFrameCompressed *kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l);
|
||||||
|
kf->SetRotation(rot);
|
||||||
|
kf->SetTime(fbuf[4]); // absolute time here
|
||||||
|
}else{
|
||||||
|
KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l);
|
||||||
|
kf->rotation = rot;
|
||||||
|
kf->deltaTime = fbuf[4]; // absolute time here
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hier->RemoveQuaternionFlips();
|
if(!compressHier){
|
||||||
hier->CalcTotalTime();
|
hier->RemoveQuaternionFlips();
|
||||||
|
hier->CalcTotalTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(animIndex > ms_numAnimations)
|
if(animIndex > ms_numAnimations)
|
||||||
ms_numAnimations = animIndex;
|
ms_numAnimations = animIndex;
|
||||||
|
|
|
@ -136,7 +136,7 @@ public:
|
||||||
static CAnimBlendAssociation *BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId animId, float delta);
|
static CAnimBlendAssociation *BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId animId, float delta);
|
||||||
static void LoadAnimFiles(void);
|
static void LoadAnimFiles(void);
|
||||||
static void LoadAnimFile(const char *filename);
|
static void LoadAnimFile(const char *filename);
|
||||||
static void LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] = nil);
|
static void LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32] = nil);
|
||||||
static void CreateAnimAssocGroups(void);
|
static void CreateAnimAssocGroups(void);
|
||||||
static void RemoveLastAnimFile(void);
|
static void RemoveLastAnimFile(void);
|
||||||
static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; }
|
static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; }
|
||||||
|
|
|
@ -291,12 +291,15 @@ CCutsceneMgr::SetupCutsceneToStart(void)
|
||||||
if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
|
if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
|
||||||
pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
|
pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
|
||||||
} else {
|
} else {
|
||||||
KeyFrameTrans* keyFrames;
|
if (pAnimBlendAssoc->hierarchy->IsCompressed()){
|
||||||
if (pAnimBlendAssoc->hierarchy->IsCompressed())
|
KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
|
||||||
keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
|
CVector trans;
|
||||||
else
|
keyFrames->GetTranslation(&trans);
|
||||||
keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
|
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans);
|
||||||
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
|
}else{
|
||||||
|
KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
|
||||||
|
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pAnimBlendAssoc->SetRun();
|
pAnimBlendAssoc->SetRun();
|
||||||
} else {
|
} else {
|
||||||
|
@ -331,7 +334,7 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pNewAnim->hierarchy->IsCompressed())
|
if (pNewAnim->hierarchy->IsCompressed())
|
||||||
pNewAnim->hierarchy->compressed2 = true;
|
pNewAnim->hierarchy->keepCompressed = true;
|
||||||
|
|
||||||
CStreaming::ImGonnaUseStreamingMemory();
|
CStreaming::ImGonnaUseStreamingMemory();
|
||||||
pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
|
pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
|
||||||
|
@ -344,8 +347,8 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
|
||||||
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
|
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
|
||||||
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
|
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
|
||||||
|
|
||||||
if (pNewAnim->hierarchy->compressed2)
|
if (pNewAnim->hierarchy->keepCompressed)
|
||||||
pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED;
|
pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -19,6 +19,9 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
|
||||||
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
||||||
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
||||||
|
|
||||||
|
void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
||||||
|
void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
||||||
|
|
||||||
void
|
void
|
||||||
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
|
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -446,3 +449,222 @@ FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
|
||||||
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
|
||||||
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
|
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
|
||||||
|
{
|
||||||
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
||||||
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
float totalBlendAmount = 0.0f;
|
||||||
|
CVector trans(0.0f, 0.0f, 0.0f);
|
||||||
|
CVector cur(0.0f, 0.0f, 0.0f);
|
||||||
|
CVector end(0.0f, 0.0f, 0.0f);
|
||||||
|
bool looped = false;
|
||||||
|
RwMatrix *mat = RwFrameGetMatrix(frame->frame);
|
||||||
|
CAnimBlendNode **node;
|
||||||
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
||||||
|
|
||||||
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
|
||||||
|
gpAnimBlendClump->velocity){
|
||||||
|
if(updateData->foobar)
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->association->IsPartial())
|
||||||
|
totalBlendAmount += (*node)->association->blendAmount;
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->sequence->HasTranslation()){
|
||||||
|
if((*node)->association->HasTranslation()){
|
||||||
|
(*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
|
||||||
|
cur += vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++){
|
||||||
|
if((*node)->sequence){
|
||||||
|
bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
if(DotProduct(rot, q) < 0.0f)
|
||||||
|
rot -= q;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
rot += q;
|
||||||
|
if((*node)->sequence->HasTranslation()){
|
||||||
|
pos += vec;
|
||||||
|
if((*node)->association->HasTranslation()){
|
||||||
|
trans += vec;
|
||||||
|
looped |= nodelooped;
|
||||||
|
if(nodelooped){
|
||||||
|
(*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
|
||||||
|
end += vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++*node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
||||||
|
RwMatrixSetIdentity(mat);
|
||||||
|
rot.Normalise();
|
||||||
|
rot.Get(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
||||||
|
*gpAnimBlendClump->velocity = trans - cur;
|
||||||
|
if(looped)
|
||||||
|
*gpAnimBlendClump->velocity += end;
|
||||||
|
mat->pos.x = (pos - trans).x + frame->resetPos.x;
|
||||||
|
mat->pos.y = (pos - trans).y + frame->resetPos.y;
|
||||||
|
mat->pos.z = (pos - trans).z + frame->resetPos.z;
|
||||||
|
}
|
||||||
|
RwMatrixUpdate(mat);
|
||||||
|
}else{
|
||||||
|
if(updateData->foobar)
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->association->IsPartial())
|
||||||
|
totalBlendAmount += (*node)->association->blendAmount;
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++){
|
||||||
|
if((*node)->sequence){
|
||||||
|
(*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
|
||||||
|
if((*node)->sequence->HasTranslation())
|
||||||
|
pos += vec;
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
if(DotProduct(rot, q) < 0.0f)
|
||||||
|
rot -= q;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
rot += q;
|
||||||
|
}
|
||||||
|
++*node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
||||||
|
RwMatrixSetIdentity(mat);
|
||||||
|
rot.Normalise();
|
||||||
|
rot.Get(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
||||||
|
mat->pos.x = pos.x;
|
||||||
|
mat->pos.y = pos.y;
|
||||||
|
mat->pos.z = pos.z;
|
||||||
|
mat->pos.x += frame->resetPos.x;
|
||||||
|
mat->pos.y += frame->resetPos.y;
|
||||||
|
mat->pos.z += frame->resetPos.z;
|
||||||
|
}
|
||||||
|
RwMatrixUpdate(mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
|
||||||
|
{
|
||||||
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
||||||
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
float totalBlendAmount = 0.0f;
|
||||||
|
CVector trans(0.0f, 0.0f, 0.0f);
|
||||||
|
CVector cur(0.0f, 0.0f, 0.0f);
|
||||||
|
CVector end(0.0f, 0.0f, 0.0f);
|
||||||
|
bool looped = false;
|
||||||
|
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
|
||||||
|
CAnimBlendNode **node;
|
||||||
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
||||||
|
|
||||||
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
|
||||||
|
gpAnimBlendClump->velocity){
|
||||||
|
if(updateData->foobar)
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->association->IsPartial())
|
||||||
|
totalBlendAmount += (*node)->association->blendAmount;
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->sequence->HasTranslation()){
|
||||||
|
if((*node)->association->HasTranslation()){
|
||||||
|
(*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
|
||||||
|
cur += vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++){
|
||||||
|
if((*node)->sequence){
|
||||||
|
bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
if(DotProduct(rot, q) < 0.0f)
|
||||||
|
rot -= q;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
rot += q;
|
||||||
|
if((*node)->sequence->HasTranslation()){
|
||||||
|
pos += vec;
|
||||||
|
if((*node)->association->HasTranslation()){
|
||||||
|
trans += vec;
|
||||||
|
looped |= nodelooped;
|
||||||
|
if(nodelooped){
|
||||||
|
(*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
|
||||||
|
end += vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++*node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
||||||
|
rot.Normalise();
|
||||||
|
xform->q.imag.x = rot.x;
|
||||||
|
xform->q.imag.y = rot.y;
|
||||||
|
xform->q.imag.z = rot.z;
|
||||||
|
xform->q.real = rot.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
||||||
|
*gpAnimBlendClump->velocity = trans - cur;
|
||||||
|
if(looped)
|
||||||
|
*gpAnimBlendClump->velocity += end;
|
||||||
|
xform->t.x = (pos - trans).x + frame->resetPos.x;
|
||||||
|
xform->t.y = (pos - trans).y + frame->resetPos.y;
|
||||||
|
xform->t.z = (pos - trans).z + frame->resetPos.z;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
float transBlendAmount = 0.0f;
|
||||||
|
|
||||||
|
if(updateData->foobar)
|
||||||
|
for(node = updateData->nodes; *node; node++)
|
||||||
|
if((*node)->sequence && (*node)->association->IsPartial())
|
||||||
|
totalBlendAmount += (*node)->association->blendAmount;
|
||||||
|
|
||||||
|
for(node = updateData->nodes; *node; node++){
|
||||||
|
if((*node)->sequence){
|
||||||
|
(*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
|
||||||
|
if((*node)->sequence->HasTranslation()){
|
||||||
|
pos += vec;
|
||||||
|
transBlendAmount += (*node)->association->blendAmount;
|
||||||
|
}
|
||||||
|
if(DotProduct(rot, q) < 0.0f)
|
||||||
|
rot -= q;
|
||||||
|
else
|
||||||
|
rot += q;
|
||||||
|
}
|
||||||
|
++*node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
||||||
|
rot.Normalise();
|
||||||
|
xform->q.imag.x = rot.x;
|
||||||
|
xform->q.imag.y = rot.y;
|
||||||
|
xform->q.imag.z = rot.z;
|
||||||
|
xform->q.real = rot.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
||||||
|
xform->t.x = transBlendAmount*pos.x;
|
||||||
|
xform->t.y = transBlendAmount*pos.y;
|
||||||
|
xform->t.z = transBlendAmount*pos.z;
|
||||||
|
xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x;
|
||||||
|
xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y;
|
||||||
|
xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
#include "AnimBlendHierarchy.h"
|
#include "AnimBlendHierarchy.h"
|
||||||
#include "AnimBlendAssociation.h"
|
#include "AnimBlendAssociation.h"
|
||||||
|
#include "AnimManager.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
#include "PedModelInfo.h"
|
#include "PedModelInfo.h"
|
||||||
|
|
||||||
|
@ -443,6 +444,9 @@ RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// CAnimBlendClumpData::LoadFramesIntoSPR
|
||||||
|
// CAnimBlendClumpData::ForAllFramesInSPR
|
||||||
void
|
void
|
||||||
RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
|
RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
|
||||||
{
|
{
|
||||||
|
@ -466,7 +470,7 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
|
||||||
assoc = CAnimBlendAssociation::FromLink(link);
|
assoc = CAnimBlendAssociation::FromLink(link);
|
||||||
if(assoc->UpdateBlend(timeDelta)){
|
if(assoc->UpdateBlend(timeDelta)){
|
||||||
if(assoc->hierarchy->sequences){
|
if(assoc->hierarchy->sequences){
|
||||||
//CAnimManager::UncompressAnimation(v6->hierarchy)
|
CAnimManager::UncompressAnimation(assoc->hierarchy);
|
||||||
if(i < 11)
|
if(i < 11)
|
||||||
updateData.nodes[i++] = assoc->GetNode(0);
|
updateData.nodes[i++] = assoc->GetNode(0);
|
||||||
if(assoc->flags & ASSOC_MOVEMENT){
|
if(assoc->flags & ASSOC_MOVEMENT){
|
||||||
|
@ -486,6 +490,14 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
|
||||||
|
|
||||||
updateData.nodes[i] = nil;
|
updateData.nodes[i] = nil;
|
||||||
|
|
||||||
|
#ifdef ANIM_COMPRESSION
|
||||||
|
if(clumpData->frames[0].flag & AnimBlendFrameData::COMPRESSED){
|
||||||
|
if(IsClumpSkinned(clump))
|
||||||
|
clumpData->ForAllFrames(FrameUpdateCallBackSkinnedCompressed, &updateData);
|
||||||
|
else
|
||||||
|
clumpData->ForAllFrames(FrameUpdateCallBackNonSkinnedCompressed, &updateData);
|
||||||
|
}else
|
||||||
|
#endif
|
||||||
if(doRender){
|
if(doRender){
|
||||||
if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES)
|
if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES)
|
||||||
RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames);
|
RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames);
|
||||||
|
|
|
@ -43,3 +43,6 @@ extern CAnimBlendClumpData *gpAnimBlendClump;
|
||||||
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
|
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
|
||||||
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
|
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
|
||||||
void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg);
|
void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg);
|
||||||
|
|
||||||
|
void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
||||||
|
void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
||||||
|
|
|
@ -192,6 +192,11 @@ enum Config {
|
||||||
// those infamous texts
|
// those infamous texts
|
||||||
#define DRAW_GAME_VERSION_TEXT
|
#define DRAW_GAME_VERSION_TEXT
|
||||||
|
|
||||||
|
// Memory allocation and compression
|
||||||
|
// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
|
||||||
|
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
|
||||||
|
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
|
||||||
|
|
||||||
#if defined GTA_PS2
|
#if defined GTA_PS2
|
||||||
# define GTA_PS2_STUFF
|
# define GTA_PS2_STUFF
|
||||||
# define RANDOMSPLASH
|
# define RANDOMSPLASH
|
||||||
|
|
|
@ -12,6 +12,11 @@ public:
|
||||||
float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; }
|
float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; }
|
||||||
void Normalise(void);
|
void Normalise(void);
|
||||||
void Multiply(const CQuaternion &q1, const CQuaternion &q2);
|
void Multiply(const CQuaternion &q1, const CQuaternion &q2);
|
||||||
|
void Invert(void){ // Conjugate would have been a better name
|
||||||
|
x = -x;
|
||||||
|
y = -y;
|
||||||
|
z = -z;
|
||||||
|
}
|
||||||
|
|
||||||
const CQuaternion &operator+=(CQuaternion const &right) {
|
const CQuaternion &operator+=(CQuaternion const &right) {
|
||||||
x += right.x;
|
x += right.x;
|
||||||
|
|
|
@ -341,7 +341,7 @@ CMemoryHeap::TidyHeap(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// MIAMI: this is empty
|
||||||
void
|
void
|
||||||
CMemoryHeap::RegisterMemPointer(void *ptr)
|
CMemoryHeap::RegisterMemPointer(void *ptr)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue