summaryrefslogtreecommitdiffstats
path: root/src/modelinfo/ClumpModelInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/modelinfo/ClumpModelInfo.cpp101
1 files changed, 70 insertions, 31 deletions
diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp
index c6a6d5d0..44faf3c5 100644
--- a/src/modelinfo/ClumpModelInfo.cpp
+++ b/src/modelinfo/ClumpModelInfo.cpp
@@ -1,5 +1,6 @@
#include "common.h"
-#include "patcher.h"
+
+#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
@@ -15,12 +16,40 @@ CClumpModelInfo::DeleteRwObject(void)
}
}
+#ifdef PED_SKIN
+static RpAtomic*
+SetHierarchyForSkinAtomic(RpAtomic *atomic, void *data)
+{
+ RpSkinAtomicSetHAnimHierarchy(atomic, (RpHAnimHierarchy*)data);
+ return nil;
+}
+#endif
+
RwObject*
CClumpModelInfo::CreateInstance(void)
{
- if(m_clump)
- return (RwObject*)RpClumpClone(m_clump);
- return nil;
+ if(m_clump == nil)
+ return nil;
+ RpClump *clone = RpClumpClone(m_clump);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clone)){
+ RpHAnimHierarchy *hier;
+ RpHAnimAnimation *anim;
+
+ hier = GetAnimHierarchyFromClump(clone);
+ assert(hier);
+ // This seems dangerous as only the first atomic will get a hierarchy
+ // can we guarantee this if hands and head are also in the clump?
+ RpClumpForAllAtomics(clone, SetHierarchyForSkinAtomic, hier);
+ anim = HAnimAnimationCreateForHierarchy(hier);
+ RpHAnimHierarchySetCurrentAnim(hier, anim);
+// RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
+ // the rest is xbox only:
+ // RpSkinGetNumBones(RpSkinGeometryGetSkin(RpAtomicGetGeometry(IsClumpSkinned(clone))));
+ RpHAnimHierarchyUpdateMatrices(hier);
+ }
+#endif
+ return (RwObject*)clone;
}
RwObject*
@@ -48,8 +77,45 @@ CClumpModelInfo::SetClump(RpClump *clump)
CVisibilityPlugins::SetClumpModelInfo(m_clump, this);
AddTexDictionaryRef();
RpClumpForAllAtomics(clump, SetAtomicRendererCB, nil);
+
+ // TODO: also set for player?
if(strncmp(GetName(), "playerh", 8) == 0)
RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump)){
+ int i;
+ RpHAnimHierarchy *hier;
+ RpAtomic *skinAtomic;
+ RpSkin *skin;
+
+ // mobile:
+// hier = nil;
+// RwFrameForAllChildren(RpClumpGetFrame(clump), GetHierarchyFromChildNodesCB, &hier);
+// assert(hier);
+// RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
+// skinAtomic = GetFirstAtomic(clump);
+
+ // xbox:
+ hier = GetAnimHierarchyFromClump(clump);
+ assert(hier);
+ RpSkinAtomicSetHAnimHierarchy(IsClumpSkinned(clump), hier);
+ skinAtomic = IsClumpSkinned(clump);
+
+ assert(skinAtomic);
+ skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(skinAtomic));
+ // ignore const
+ for(i = 0; i < RpGeometryGetNumVertices(RpAtomicGetGeometry(skinAtomic)); i++){
+ RwMatrixWeights *weights = (RwMatrixWeights*)&RpSkinGetVertexBoneWeights(skin)[i];
+ float sum = weights->w0 + weights->w1 + weights->w2 + weights->w3;
+ weights->w0 /= sum;
+ weights->w1 /= sum;
+ weights->w2 /= sum;
+ weights->w3 /= sum;
+ }
+// RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
+ }
+#endif
}
void
@@ -138,30 +204,3 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id)
RwFrameForAllChildren(RpClumpGetFrame(clump), FindFrameFromIdCB, &assoc);
return assoc.frame;
}
-
-
-class CClumpModelInfo_ : public CClumpModelInfo
-{
-public:
- void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); }
- RwObject *CreateInstance_1(void) { return CClumpModelInfo::CreateInstance(); }
- RwObject *CreateInstance_2(RwMatrix *m) { return CClumpModelInfo::CreateInstance(m); }
- RwObject *GetRwObject_(void) { return CClumpModelInfo::GetRwObject(); }
- void SetClump_(RpClump *clump) { CClumpModelInfo::SetClump(clump); }
-};
-
-STARTPATCHES
- InjectHook(0x4F8800, &CClumpModelInfo_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x4F8920, &CClumpModelInfo_::CreateInstance_1, PATCH_JUMP);
- InjectHook(0x4F88A0, &CClumpModelInfo_::CreateInstance_2, PATCH_JUMP);
- InjectHook(0x50C1C0, &CClumpModelInfo_::GetRwObject_, PATCH_JUMP);
- InjectHook(0x4F8830, &CClumpModelInfo_::SetClump_, PATCH_JUMP);
- InjectHook(0x4F8940, &CClumpModelInfo::SetAtomicRendererCB, PATCH_JUMP);
- InjectHook(0x4F8960, &CClumpModelInfo::FindFrameFromNameCB, PATCH_JUMP);
- InjectHook(0x4F8A10, &CClumpModelInfo::FindFrameFromNameWithoutIdCB, PATCH_JUMP);
- InjectHook(0x4F8AD0, &CClumpModelInfo::FindFrameFromIdCB, PATCH_JUMP);
- InjectHook(0x4F8BB0, &CClumpModelInfo::SetFrameIds, PATCH_JUMP);
- InjectHook(0x4F8B20, &CClumpModelInfo::FillFrameArrayCB, PATCH_JUMP);
- InjectHook(0x4F8B90, &CClumpModelInfo::FillFrameArray, PATCH_JUMP);
- InjectHook(0x4F8B50, &CClumpModelInfo::GetFrameFromId, PATCH_JUMP);
-ENDPATCHES