From f03b4eec4c37eab75a5bd639279cfcc615105b01 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 23 Apr 2020 22:25:18 +0200 Subject: implemented skinned peds, no cutscene hands yet --- src/objects/CutsceneHead.cpp | 95 +++++++++++++++++++++++++++++++++++++----- src/objects/CutsceneHead.h | 9 ++++ src/objects/CutsceneObject.cpp | 65 ++++++++++++++++++++++++++++- src/objects/CutsceneObject.h | 16 +++++++ 4 files changed, 174 insertions(+), 11 deletions(-) (limited to 'src/objects') diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp index b716e17e..3ef257d2 100644 --- a/src/objects/CutsceneHead.cpp +++ b/src/objects/CutsceneHead.cpp @@ -5,6 +5,7 @@ #include "RwHelper.h" #include "RpAnimBlend.h" #include "AnimBlendClumpData.h" +#include "Bones.h" #include "Directory.h" #include "CutsceneMgr.h" #include "Streaming.h" @@ -17,11 +18,23 @@ CCutsceneHead::CCutsceneHead(CObject *obj) RpAtomic *atm; assert(RwObjectGetType(obj->m_rwObject) == rpCLUMP); - m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame; - atm = (RpAtomic*)GetFirstObject(m_pHeadNode); - if(atm){ - assert(RwObjectGetType((RwObject*)atm) == rpATOMIC); - RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER); +#ifdef PED_SKIN + unk1 = 0; + bIsSkinned = false; + m_parentObject = (CCutsceneObject*)obj; + // Hide original head + if(IsClumpSkinned(obj->GetClump())){ + m_parentObject->SetRenderHead(false); + bIsSkinned = true; + }else +#endif + { + m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame; + atm = (RpAtomic*)GetFirstObject(m_pHeadNode); + if(atm){ + assert(RwObjectGetType((RwObject*)atm) == rpATOMIC); + RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER); + } } } @@ -48,11 +61,28 @@ CCutsceneHead::ProcessControl(void) RpAtomic *atm; RpHAnimHierarchy *hier; + // android/xbox calls is at the end CPhysical::ProcessControl(); - m_matrix.SetRotateY(PI/2); - m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix; - UpdateRwFrame(); +#ifdef PED_SKIN + if(bIsSkinned){ + UpdateRpHAnim(); + UpdateRwFrame(); + + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump()); + int idx = RpHAnimIDGetIndex(hier, BONE_head); + RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + if(RwV3dLength(&mat->pos) > 100.0f){ + m_matrix.SetRotateY(PI/2); + m_matrix = CMatrix(mat) * m_matrix; + } + }else +#endif + { + m_matrix.SetRotateY(PI/2); + m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix; + UpdateRwFrame(); // android/xbox don't call this + } assert(RwObjectGetType(m_rwObject) == rpCLUMP); atm = GetFirstAtomic((RpClump*)m_rwObject); @@ -65,8 +95,25 @@ CCutsceneHead::Render(void) { RpAtomic *atm; - m_matrix.SetRotateY(PI/2); - m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix; +#ifdef PED_SKIN + if(bIsSkinned){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump()); + RpHAnimHierarchyUpdateMatrices(hier); + int idx = RpHAnimIDGetIndex(hier, BONE_head); + RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + if(RwV3dLength(&mat->pos) > 100.0f){ + m_matrix.SetRotateY(PI/2); + m_matrix = CMatrix(mat) * m_matrix; + } + RenderLimb(BONE_Lhand); + RenderLimb(BONE_Rhand); + }else +#endif + { + m_matrix.SetRotateY(PI/2); + m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix; + } + UpdateRwFrame(); assert(RwObjectGetType(m_rwObject) == rpCLUMP); @@ -76,6 +123,34 @@ CCutsceneHead::Render(void) CObject::Render(); } +#ifdef PED_SKIN +void +CCutsceneHead::RenderLimb(int32 bone) +{ + RpAtomic *atomic; + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump()); + int idx = RpHAnimIDGetIndex(hier, bone); + RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); + CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + switch(bone){ + case BONE_Lhand: + atomic = mi->getLeftHand(); + break; + case BONE_Rhand: + atomic = mi->getRightHand(); + break; + default: + return; + } + if(atomic){ + RwFrame *frame = RpAtomicGetFrame(atomic); + RwMatrixTransform(RwFrameGetMatrix(frame), &mats[idx], rwCOMBINEREPLACE); + RwFrameUpdateObjects(frame); + RpAtomicRender(atomic); + } +} +#endif + void CCutsceneHead::PlayAnimation(const char *animName) { diff --git a/src/objects/CutsceneHead.h b/src/objects/CutsceneHead.h index 52b66ede..0a70353d 100644 --- a/src/objects/CutsceneHead.h +++ b/src/objects/CutsceneHead.h @@ -6,6 +6,12 @@ class CCutsceneHead : public CCutsceneObject { public: RwFrame *m_pHeadNode; +#ifdef PED_SKIN + int32 unk1; + CCutsceneObject *m_parentObject; + int32 unk2; + int32 bIsSkinned; +#endif CCutsceneHead(CObject *obj); @@ -13,7 +19,10 @@ public: void DeleteRwObject(void); void ProcessControl(void); void Render(void); + void RenderLimb(int32 bone); void PlayAnimation(const char *animName); }; +#ifndef PED_SKIN static_assert(sizeof(CCutsceneHead) == 0x19C, "CCutsceneHead: error"); +#endif diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp index cee83848..7b4ae02b 100644 --- a/src/objects/CutsceneObject.cpp +++ b/src/objects/CutsceneObject.cpp @@ -1,10 +1,12 @@ #include "common.h" #include "main.h" +#include "RwHelper.h" #include "Lights.h" #include "PointLights.h" #include "RpAnimBlend.h" #include "AnimBlendClumpData.h" +#include "Bones.h" #include "Renderer.h" #include "ModelIndices.h" #include "Shadows.h" @@ -19,6 +21,12 @@ CCutsceneObject::CCutsceneObject(void) ObjectCreatedBy = CUTSCENE_OBJECT; m_fMass = 1.0f; m_fTurnMass = 1.0f; + +#ifdef PED_SKIN + bRenderHead = true; + bRenderRightHand = true; + bRenderLeftHand = true; +#endif } void @@ -42,12 +50,24 @@ CCutsceneObject::ProcessControl(void) m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep(); ApplyMoveSpeed(); + +#ifdef PED_SKIN + if(IsClumpSkinned(GetClump())) + UpdateRpHAnim(); +#endif +} + +static RpMaterial* +MaterialSetAlpha(RpMaterial *material, void *data) +{ + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data; + return material; } void CCutsceneObject::PreRender(void) { - if(IsPedModel(GetModelIndex())) + if(IsPedModel(GetModelIndex())){ CShadows::StoreShadowForPedObject(this, CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue], @@ -55,14 +75,57 @@ CCutsceneObject::PreRender(void) CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]); + // For some reason xbox/android limbs are transparent here... + RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump())); + RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geometry, MaterialSetAlpha, (void*)255); + } } void CCutsceneObject::Render(void) { +#ifdef PED_SKIN + if(IsClumpSkinned(GetClump())){ + if(bRenderLeftHand) RenderLimb(BONE_Lhand); + if(bRenderRightHand) RenderLimb(BONE_Rhand); + if(bRenderHead) RenderLimb(BONE_head); + } +#endif CObject::Render(); } +#ifdef PED_SKIN +void +CCutsceneObject::RenderLimb(int32 bone) +{ + RpAtomic *atomic; + CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + switch(bone){ + case BONE_head: + atomic = mi->getHead(); + break; + case BONE_Lhand: + atomic = mi->getLeftHand(); + break; + case BONE_Rhand: + atomic = mi->getRightHand(); + break; + default: + return; + } + if(atomic){ + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + int idx = RpHAnimIDGetIndex(hier, bone); + RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwFrame *frame = RpAtomicGetFrame(atomic); + *RwFrameGetMatrix(frame) = *mat; + RwFrameUpdateObjects(frame); + RpAtomicRender(atomic); + } +} +#endif + bool CCutsceneObject::SetupLighting(void) { diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h index 31c3a528..9c4036bf 100644 --- a/src/objects/CutsceneObject.h +++ b/src/objects/CutsceneObject.h @@ -5,13 +5,29 @@ class CCutsceneObject : public CObject { public: +#ifdef PED_SKIN + bool bRenderHead; + bool bRenderRightHand; + bool bRenderLeftHand; + + bool GetRenderHead(void) { return bRenderHead; } + bool GetRenderRightHand(void) { return bRenderRightHand; } + bool GetRenderLeftHand(void) { return bRenderLeftHand; } + void SetRenderHead(bool render) { bRenderHead = render; } + void SetRenderRightHand(bool render) { bRenderRightHand = render; } + void SetRenderLeftHand(bool render) { bRenderLeftHand = render; } +#endif + CCutsceneObject(void); void SetModelIndex(uint32 id); void ProcessControl(void); void PreRender(void); void Render(void); + void RenderLimb(int32 bone); bool SetupLighting(void); void RemoveLighting(bool reset); }; +#ifndef PED_SKIN static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error"); +#endif -- cgit v1.2.3