diff options
Diffstat (limited to 'src/modelinfo/ClumpModelInfo.cpp')
-rw-r--r-- | src/modelinfo/ClumpModelInfo.cpp | 101 |
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 |