summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-04-25 11:15:29 +0200
committerNikolay Korolev <nickvnuk@gmail.com>2020-04-25 11:15:29 +0200
commit34ef766c67b50b6abf4a05a77521e2393b116cca (patch)
tree3005e50fdcd82c3a9dc604fdcd89e694d5f621b8 /src/animation
parentundo (diff)
parentdisable mouse steering by default (diff)
downloadre3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar.gz
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar.bz2
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar.lz
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar.xz
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.tar.zst
re3-34ef766c67b50b6abf4a05a77521e2393b116cca.zip
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/AnimBlendClumpData.h4
-rw-r--r--src/animation/Bones.cpp52
-rw-r--r--src/animation/Bones.h24
-rw-r--r--src/animation/FrameUpdate.cpp243
-rw-r--r--src/animation/RpAnimBlend.cpp114
-rw-r--r--src/animation/RpAnimBlend.h5
6 files changed, 399 insertions, 43 deletions
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 1c8c391d..a537425a 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -18,7 +18,7 @@ struct AnimBlendFrameData
#ifdef PED_SKIN
union {
RwFrame *frame;
- RpHAnimStdKeyFrame *hanimframe;
+ RpHAnimStdKeyFrame *hanimFrame;
};
int32 nodeID;
#else
@@ -50,4 +50,6 @@ public:
#endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
};
+#ifndef PED_SKIN
static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error");
+#endif
diff --git a/src/animation/Bones.cpp b/src/animation/Bones.cpp
new file mode 100644
index 00000000..1608449d
--- /dev/null
+++ b/src/animation/Bones.cpp
@@ -0,0 +1,52 @@
+#include "common.h"
+#include "PedModelInfo.h"
+#include "Bones.h"
+
+#ifdef PED_SKIN
+
+int
+ConvertPedNode2BoneTag(int node)
+{
+ switch(node){
+ case PED_TORSO: return BONE_waist;
+ case PED_MID: return BONE_torso; // this is what Xbox/Mobile use
+ // return BONE_mid; // this is what PS2/PC use
+ case PED_HEAD: return BONE_head;
+ case PED_UPPERARML: return BONE_upperarml;
+ case PED_UPPERARMR: return BONE_upperarmr;
+ case PED_HANDL: return BONE_Lhand;
+ case PED_HANDR: return BONE_Rhand;
+ case PED_UPPERLEGL: return BONE_upperlegl;
+ case PED_UPPERLEGR: return BONE_upperlegr;
+ case PED_FOOTL: return BONE_footl;
+ case PED_FOOTR: return BONE_footr;
+ case PED_LOWERLEGR: return BONE_lowerlegl;
+ }
+ return -1;
+}
+
+const char*
+ConvertBoneTag2BoneName(int tag)
+{
+ switch(tag){
+ case BONE_waist: return "Swaist";
+ case BONE_upperlegr: return "Supperlegr";
+ case BONE_lowerlegr: return "Slowerlegr";
+ case BONE_footr: return "Sfootr";
+ case BONE_upperlegl: return "Supperlegl";
+ case BONE_lowerlegl: return "Slowerlegl";
+ case BONE_footl: return "Sfootl";
+ case BONE_mid: return "Smid";
+ case BONE_torso: return "Storso";
+ case BONE_head: return "Shead";
+ case BONE_upperarmr: return "Supperarmr";
+ case BONE_lowerarmr: return "Slowerarmr";
+ case BONE_Rhand: return "SRhand";
+ case BONE_upperarml: return "Supperarml";
+ case BONE_lowerarml: return "Slowerarml";
+ case BONE_Lhand: return "SLhand";
+ }
+ return nil;
+}
+
+#endif
diff --git a/src/animation/Bones.h b/src/animation/Bones.h
new file mode 100644
index 00000000..38d91ba3
--- /dev/null
+++ b/src/animation/Bones.h
@@ -0,0 +1,24 @@
+#pragma once
+
+enum BoneTag
+{
+ BONE_waist,
+ BONE_upperlegr,
+ BONE_lowerlegr,
+ BONE_footr,
+ BONE_upperlegl,
+ BONE_lowerlegl,
+ BONE_footl,
+ BONE_mid,
+ BONE_torso,
+ BONE_head,
+ BONE_upperarmr,
+ BONE_lowerarmr,
+ BONE_Rhand,
+ BONE_upperarml,
+ BONE_lowerarml,
+ BONE_Lhand,
+};
+
+int ConvertPedNode2BoneTag(int node);
+const char *ConvertBoneTag2BoneName(int tag);
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index df45bfb5..a38ebc74 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -8,12 +8,18 @@
CAnimBlendClumpData *gpAnimBlendClump;
-void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg);
-void FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg);
-void FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg);
+// PS2 names without "NonSkinned"
+void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackNonSkinnedWithVelocityExtraction(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackNonSkinnedWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg);
+
+void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedWithVelocityExtraction(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg);
+
void
-FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -25,9 +31,9 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
gpAnimBlendClump->velocity){
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
- FrameUpdateCallBackWith3dVelocityExtraction(frame, arg);
+ FrameUpdateCallBackNonSkinnedWith3dVelocityExtraction(frame, arg);
else
- FrameUpdateCallBackWithVelocityExtraction(frame, arg);
+ FrameUpdateCallBackNonSkinnedWithVelocityExtraction(frame, arg);
return;
}
@@ -48,12 +54,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -69,7 +70,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
}
void
-FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackNonSkinnedWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -122,12 +123,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -154,7 +150,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
// original code uses do loops?
void
-FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackNonSkinnedWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -201,12 +197,7 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -220,3 +211,203 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
}
RwMatrixUpdate(mat);
}
+
+#ifdef PED_SKIN
+
+void
+FrameUpdateCallBackSkinned(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;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity){
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
+ FrameUpdateCallBackSkinnedWith3dVelocityExtraction(frame, arg);
+ else
+ FrameUpdateCallBackSkinnedWithVelocityExtraction(frame, arg);
+ 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;
+ 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 = pos.x;
+ xform->t.y = pos.y;
+ xform->t.z = pos.z;
+ xform->t.x += frame->resetPos.x;
+ xform->t.y += frame->resetPos.y;
+ xform->t.z += frame->resetPos.z;
+ }
+}
+
+void
+FrameUpdateCallBackSkinnedWithVelocityExtraction(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;
+ float transx = 0.0f, transy = 0.0f;
+ float curx = 0.0f, cury = 0.0f;
+ float endx = 0.0f, endy = 0.0f;
+ bool looped = false;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ 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);
+ rot += q;
+ 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;
+ if(xform->t.z >= -0.8f)
+ 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;
+ xform->t.x += frame->resetPos.x;
+ xform->t.y += frame->resetPos.y;
+ }
+}
+
+void
+FrameUpdateCallBackSkinnedWith3dVelocityExtraction(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;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ 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);
+ rot += q;
+ 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;
+ }
+}
+
+#endif
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index 20290666..d3e10889 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -1,12 +1,17 @@
#include "common.h"
+#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
+#include "Bones.h"
#include "AnimBlendClumpData.h"
#include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
+#ifdef PED_SKIN
+#include "PedModelInfo.h"
+#endif
RwInt32 ClumpOffset;
@@ -122,19 +127,59 @@ FrameForAllChildrenFillFrameArrayCallBack(RwFrame *frame, void *data)
return frame;
}
+// FrameInitCallBack on PS2
void
-FrameInitCallBack(AnimBlendFrameData *frameData, void*)
+FrameInitCBnonskin(AnimBlendFrameData *frameData, void*)
{
frameData->flag = 0;
frameData->resetPos = *RwMatrixGetPos(RwFrameGetMatrix(frameData->frame));
}
void
-RpAnimBlendClumpInit(RpClump *clump)
+FrameInitCBskin(AnimBlendFrameData *frameData, void*)
{
+ frameData->flag = 0;
+}
+
#ifdef PED_SKIN
- TODO
-#else
+void
+RpAnimBlendClumpInitSkinned(RpClump *clump)
+{
+ int i;
+ RwV3d boneTab[64];
+ CAnimBlendClumpData *clumpData;
+ RpAtomic *atomic;
+ RpSkin *skin;
+ RpHAnimHierarchy *hier;
+ int numBones;
+
+ RpAnimBlendAllocateData(clump);
+ clumpData = *RPANIMBLENDCLUMPDATA(clump);
+ atomic = IsClumpSkinned(clump);
+ assert(atomic);
+ skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
+ assert(skin);
+ numBones = RpSkinGetNumBones(skin);
+ clumpData->SetNumberOfBones(numBones);
+ hier = GetAnimHierarchyFromSkinClump(clump);
+ assert(hier);
+ memset(boneTab, 0, sizeof(boneTab));
+ SkinGetBonePositionsToTable(clump, boneTab);
+
+ AnimBlendFrameData *frames = clumpData->frames;
+ for(i = 0; i < numBones; i++){
+ frames[i].nodeID = HIERNODEID(hier, i);
+ frames[i].resetPos = boneTab[i];
+ frames[i].hanimFrame = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+ }
+ clumpData->ForAllFrames(FrameInitCBskin, nil);
+ clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
+}
+#endif
+
+void
+RpAnimBlendClumpInitNotSkinned(RpClump *clump)
+{
int numFrames = 0;
CAnimBlendClumpData *clumpData;
RwFrame *root;
@@ -147,9 +192,19 @@ RpAnimBlendClumpInit(RpClump *clump)
clumpData->SetNumberOfFrames(numFrames);
frames = clumpData->frames;
RwFrameForAllChildren(root, FrameForAllChildrenFillFrameArrayCallBack, &frames);
- clumpData->ForAllFrames(FrameInitCallBack, nil);
+ clumpData->ForAllFrames(FrameInitCBnonskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
+}
+
+void
+RpAnimBlendClumpInit(RpClump *clump)
+{
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump))
+ RpAnimBlendClumpInitSkinned(clump);
+ else
#endif
+ RpAnimBlendClumpInitNotSkinned(clump);
}
bool
@@ -298,42 +353,68 @@ RpAnimBlendClumpGetFirstAssociation(RpClump *clump)
return CAnimBlendAssociation::FromLink(clumpData->link.next);
}
+// FillFrameArrayCallBack on PS2
void
-FillFrameArrayCallBack(AnimBlendFrameData *frame, void *arg)
+FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
{
AnimBlendFrameData **frames = (AnimBlendFrameData**)arg;
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
}
+#ifdef PED_SKIN
+void
+RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
+{
+ int i;
+ CAnimBlendClumpData *clumpData = *RPANIMBLENDCLUMPDATA(clump);
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
+ for(i = PED_MID; i < PED_NODE_MAX; i++)
+ frames[i] = &clumpData->frames[RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(i))];
+}
+#endif
+
void
RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames)
{
#ifdef PED_SKIN
- TODO
-#else
- (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCallBack, frames);
+ if(IsClumpSkinned(clump))
+ RpAnimBlendClumpFillFrameArraySkin(clump, frames);
+ else
#endif
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCBnonskin, frames);
}
AnimBlendFrameData *pFrameDataFound;
+// FrameFindCallBack on PS2
void
-FrameFindCallBack(AnimBlendFrameData *frame, void *arg)
+FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
{
char *nodename = GetFrameNodeName(frame->frame);
if(!CGeneral::faststricmp(nodename, (char*)arg))
pFrameDataFound = frame;
}
+#ifdef PED_SKIN
+void
+FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
+{
+ const char *name = ConvertBoneTag2BoneName(frame->nodeID);
+ if(name && CGeneral::faststricmp(name, (char*)arg) == 0)
+ pFrameDataFound = frame;
+}
+#endif
+
AnimBlendFrameData*
RpAnimBlendClumpFindFrame(RpClump *clump, const char *name)
{
pFrameDataFound = nil;
#ifdef PED_SKIN
- TODO
-#else
- (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindCallBack, (void*)name);
+ if(IsClumpSkinned(clump))
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBskin, (void*)name);
+ else
#endif
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBnonskin, (void*)name);
return pFrameDataFound;
}
@@ -369,7 +450,12 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
}
updateData.nodes[i] = nil;
- clumpData->ForAllFrames(FrameUpdateCallBack, &updateData);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
+ else
+#endif
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
for(link = clumpData->link.next; link; link = link->next){
CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h
index ccfa5872..838c8816 100644
--- a/src/animation/RpAnimBlend.h
+++ b/src/animation/RpAnimBlend.h
@@ -7,7 +7,7 @@ struct AnimBlendFrameData;
struct AnimBlendFrameUpdateData
{
- int foobar;
+ int foobar; // TODO: figure out what this actually means
CAnimBlendNode *nodes[16];
};
@@ -38,4 +38,5 @@ void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta);
extern CAnimBlendClumpData *gpAnimBlendClump;
-void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);