2019-06-11 08:59:28 +02:00
|
|
|
#include "common.h"
|
2020-04-17 15:31:11 +02:00
|
|
|
|
2019-06-11 08:59:28 +02:00
|
|
|
#include "NodeName.h"
|
|
|
|
#include "VisibilityPlugins.h"
|
|
|
|
#include "AnimBlendClumpData.h"
|
|
|
|
#include "AnimBlendAssociation.h"
|
|
|
|
#include "RpAnimBlend.h"
|
|
|
|
|
2020-05-10 23:47:53 +02:00
|
|
|
//--MIAMI: file done
|
|
|
|
|
2020-04-16 10:50:45 +02:00
|
|
|
CAnimBlendClumpData *gpAnimBlendClump;
|
2019-06-11 08:59:28 +02:00
|
|
|
|
2020-04-23 22:25:18 +02:00
|
|
|
// PS2 names without "NonSkinned"
|
|
|
|
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
|
2020-04-25 14:03:20 +02:00
|
|
|
void FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
|
|
|
|
void FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
|
2020-04-23 22:25:18 +02:00
|
|
|
|
|
|
|
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
|
2020-04-25 14:03:20 +02:00
|
|
|
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
|
|
|
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
|
2020-04-23 22:25:18 +02:00
|
|
|
|
2020-12-18 23:46:51 +01:00
|
|
|
void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
|
|
|
void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
|
|
|
|
|
2019-06-11 08:59:28 +02:00
|
|
|
void
|
2020-04-23 22:25:18 +02:00
|
|
|
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
|
2019-06-11 08:59:28 +02:00
|
|
|
{
|
|
|
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
|
|
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
float totalBlendAmount = 0.0f;
|
|
|
|
RwMatrix *mat = RwFrameGetMatrix(frame->frame);
|
|
|
|
CAnimBlendNode **node;
|
|
|
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
|
|
|
|
|
|
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
|
2019-06-12 21:17:02 +02:00
|
|
|
gpAnimBlendClump->velocity){
|
2019-06-11 08:59:28 +02:00
|
|
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(frame, arg);
|
2019-06-11 08:59:28 +02:00
|
|
|
else
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWithVelocityExtractionNonSkinned(frame, arg);
|
2019-06-11 08:59:28 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)->Update(vec, q, 1.0f-totalBlendAmount);
|
|
|
|
if((*node)->sequence->HasTranslation())
|
|
|
|
pos += vec;
|
2020-05-10 23:47:53 +02:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
rot += q;
|
2019-06-11 08:59:28 +02:00
|
|
|
}
|
|
|
|
++*node;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
|
|
|
RwMatrixSetIdentity(mat);
|
2020-04-23 22:25:18 +02:00
|
|
|
rot.Normalise();
|
2019-06-11 08:59:28 +02:00
|
|
|
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
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
|
2019-06-11 08:59:28 +02:00
|
|
|
{
|
|
|
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
|
|
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
float totalBlendAmount = 0.0f;
|
|
|
|
float transx = 0.0f, transy = 0.0f;
|
|
|
|
float curx = 0.0f, cury = 0.0f;
|
|
|
|
float endx = 0.0f, endy = 0.0f;
|
|
|
|
bool looped = false;
|
|
|
|
RwMatrix *mat = RwFrameGetMatrix(frame->frame);
|
|
|
|
CAnimBlendNode **node;
|
|
|
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
|
|
|
|
|
|
|
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)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
cury += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
curx += vec.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(node = updateData->nodes; *node; node++){
|
|
|
|
if((*node)->sequence){
|
|
|
|
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
|
2020-05-10 23:47:53 +02:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
rot += q;
|
2019-06-11 08:59:28 +02:00
|
|
|
if((*node)->sequence->HasTranslation()){
|
|
|
|
pos += vec;
|
|
|
|
if((*node)->association->HasTranslation()){
|
|
|
|
transy += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
transx += vec.x;
|
|
|
|
looped |= nodelooped;
|
|
|
|
if(nodelooped){
|
|
|
|
(*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
endy += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
endx += vec.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++*node;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
|
|
|
RwMatrixSetIdentity(mat);
|
2020-04-23 22:25:18 +02:00
|
|
|
rot.Normalise();
|
2019-06-11 08:59:28 +02:00
|
|
|
rot.Get(mat);
|
|
|
|
}
|
|
|
|
|
|
|
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
2019-06-12 21:17:02 +02:00
|
|
|
gpAnimBlendClump->velocity->x = transx - curx;
|
|
|
|
gpAnimBlendClump->velocity->y = transy - cury;
|
2019-06-11 08:59:28 +02:00
|
|
|
if(looped){
|
2019-06-12 21:17:02 +02:00
|
|
|
gpAnimBlendClump->velocity->x += endx;
|
|
|
|
gpAnimBlendClump->velocity->y += endy;
|
2019-06-11 08:59:28 +02:00
|
|
|
}
|
|
|
|
mat->pos.x = pos.x - transx;
|
|
|
|
mat->pos.y = pos.y - transy;
|
|
|
|
mat->pos.z = pos.z;
|
2020-05-12 01:24:57 +02:00
|
|
|
if(mat->pos.z >= -0.8f) {
|
2019-06-11 08:59:28 +02:00
|
|
|
if(mat->pos.z < -0.4f)
|
|
|
|
mat->pos.z += (2.5f * mat->pos.z + 2.0f) * frame->resetPos.z;
|
|
|
|
else
|
|
|
|
mat->pos.z += frame->resetPos.z;
|
2020-05-12 01:24:57 +02:00
|
|
|
}
|
2019-06-11 08:59:28 +02:00
|
|
|
mat->pos.x += frame->resetPos.x;
|
|
|
|
mat->pos.y += frame->resetPos.y;
|
|
|
|
}
|
|
|
|
RwMatrixUpdate(mat);
|
|
|
|
}
|
|
|
|
|
|
|
|
// original code uses do loops?
|
|
|
|
void
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
|
2019-06-11 08:59:28 +02:00
|
|
|
{
|
|
|
|
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(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)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
cur += vec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(node = updateData->nodes; *node; node++){
|
|
|
|
if((*node)->sequence){
|
|
|
|
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
|
2020-05-10 23:47:53 +02:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
rot += q;
|
2019-06-11 08:59:28 +02:00
|
|
|
if((*node)->sequence->HasTranslation()){
|
|
|
|
pos += vec;
|
|
|
|
if((*node)->association->HasTranslation()){
|
|
|
|
trans += vec;
|
|
|
|
looped |= nodelooped;
|
|
|
|
if(nodelooped){
|
|
|
|
(*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
end += vec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++*node;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
|
|
|
|
RwMatrixSetIdentity(mat);
|
2020-04-23 22:25:18 +02:00
|
|
|
rot.Normalise();
|
2019-06-11 08:59:28 +02:00
|
|
|
rot.Get(mat);
|
|
|
|
}
|
|
|
|
|
|
|
|
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
|
2019-06-12 21:17:02 +02:00
|
|
|
*gpAnimBlendClump->velocity = trans - cur;
|
2019-06-11 08:59:28 +02:00
|
|
|
if(looped)
|
2019-06-12 21:17:02 +02:00
|
|
|
*gpAnimBlendClump->velocity += end;
|
2019-06-11 08:59:28 +02:00
|
|
|
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);
|
|
|
|
}
|
2020-04-23 22:25:18 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
|
|
|
|
{
|
|
|
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
2020-06-08 13:00:45 +02:00
|
|
|
float transBlendAmount = 0.0f;
|
2020-04-23 22:25:18 +02:00
|
|
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
float totalBlendAmount = 0.0f;
|
2020-07-24 23:29:33 +02:00
|
|
|
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
|
2020-04-23 22:25:18 +02:00
|
|
|
CAnimBlendNode **node;
|
|
|
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
|
|
|
|
|
|
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
|
|
|
|
gpAnimBlendClump->velocity){
|
|
|
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWith3dVelocityExtractionSkinned(frame, arg);
|
2020-04-23 22:25:18 +02:00
|
|
|
else
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
|
2020-04-23 22:25:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)->Update(vec, q, 1.0f-totalBlendAmount);
|
2020-06-08 13:00:45 +02:00
|
|
|
if((*node)->sequence->HasTranslation()){
|
2020-04-23 22:25:18 +02:00
|
|
|
pos += vec;
|
2020-06-08 13:00:45 +02:00
|
|
|
transBlendAmount += (*node)->association->blendAmount;
|
|
|
|
}
|
2020-05-10 23:47:53 +02:00
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
rot += q;
|
2020-04-23 22:25:18 +02:00
|
|
|
}
|
|
|
|
++*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){
|
2020-06-08 13:00:45 +02:00
|
|
|
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;
|
2020-04-23 22:25:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
|
2020-04-23 22:25:18 +02:00
|
|
|
{
|
|
|
|
CVector vec, pos(0.0f, 0.0f, 0.0f);
|
|
|
|
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
float totalBlendAmount = 0.0f;
|
|
|
|
float transx = 0.0f, transy = 0.0f;
|
|
|
|
float curx = 0.0f, cury = 0.0f;
|
|
|
|
float endx = 0.0f, endy = 0.0f;
|
|
|
|
bool looped = false;
|
2020-07-24 23:29:33 +02:00
|
|
|
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
|
2020-04-23 22:25:18 +02:00
|
|
|
CAnimBlendNode **node;
|
|
|
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
|
|
|
|
|
|
|
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)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
cury += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
curx += vec.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(node = updateData->nodes; *node; node++){
|
|
|
|
if((*node)->sequence){
|
|
|
|
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
|
2020-05-10 23:47:53 +02:00
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
rot += q;
|
2020-04-23 22:25:18 +02:00
|
|
|
if((*node)->sequence->HasTranslation()){
|
|
|
|
pos += vec;
|
|
|
|
if((*node)->association->HasTranslation()){
|
|
|
|
transy += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
transx += vec.x;
|
|
|
|
looped |= nodelooped;
|
|
|
|
if(nodelooped){
|
|
|
|
(*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
endy += vec.y;
|
|
|
|
if((*node)->association->HasXTranslation())
|
|
|
|
endx += vec.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++*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->x = transx - curx;
|
|
|
|
gpAnimBlendClump->velocity->y = transy - cury;
|
|
|
|
if(looped){
|
|
|
|
gpAnimBlendClump->velocity->x += endx;
|
|
|
|
gpAnimBlendClump->velocity->y += endy;
|
|
|
|
}
|
|
|
|
xform->t.x = pos.x - transx;
|
|
|
|
xform->t.y = pos.y - transy;
|
|
|
|
xform->t.z = pos.z;
|
2020-05-12 01:24:57 +02:00
|
|
|
if(xform->t.z >= -0.8f) {
|
2020-04-23 22:25:18 +02:00
|
|
|
if(xform->t.z < -0.4f)
|
|
|
|
xform->t.z += (2.5f * xform->t.z + 2.0f) * frame->resetPos.z;
|
|
|
|
else
|
|
|
|
xform->t.z += frame->resetPos.z;
|
2020-05-12 01:24:57 +02:00
|
|
|
}
|
2020-04-23 22:25:18 +02:00
|
|
|
xform->t.x += frame->resetPos.x;
|
|
|
|
xform->t.y += frame->resetPos.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-04-25 14:03:20 +02:00
|
|
|
FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
|
2020-04-23 22:25:18 +02:00
|
|
|
{
|
|
|
|
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;
|
2020-07-24 23:29:33 +02:00
|
|
|
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
|
2020-04-23 22:25:18 +02:00
|
|
|
CAnimBlendNode **node;
|
|
|
|
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
|
|
|
|
|
|
|
|
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)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
|
|
|
|
cur += vec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(node = updateData->nodes; *node; node++){
|
|
|
|
if((*node)->sequence){
|
|
|
|
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
|
2020-05-10 23:47:53 +02:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
if(DotProduct(rot, q) < 0.0f)
|
|
|
|
rot -= q;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
rot += q;
|
2020-04-23 22:25:18 +02:00
|
|
|
if((*node)->sequence->HasTranslation()){
|
|
|
|
pos += vec;
|
|
|
|
if((*node)->association->HasTranslation()){
|
|
|
|
trans += vec;
|
|
|
|
looped |= nodelooped;
|
|
|
|
if(nodelooped){
|
|
|
|
(*node)->GetEndTranslation(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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-10 23:47:53 +02:00
|
|
|
void
|
|
|
|
FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
|
|
|
|
{
|
|
|
|
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
|
|
|
|
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
|
|
|
|
}
|
2020-12-18 23:46:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|