summaryrefslogtreecommitdiff
path: root/src/objects
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2020-04-23 22:25:18 +0200
committeraap <aap@papnet.eu>2020-04-24 11:42:38 +0200
commitf03b4eec4c37eab75a5bd639279cfcc615105b01 (patch)
treec4be4fa57b16c61d45e8156a51dd07b11e049bba /src/objects
parent6467e2003a0fc9f6bb5f8b86dd699b674f5e5b9a (diff)
implemented skinned peds, no cutscene hands yet
Diffstat (limited to 'src/objects')
-rw-r--r--src/objects/CutsceneHead.cpp95
-rw-r--r--src/objects/CutsceneHead.h9
-rw-r--r--src/objects/CutsceneObject.cpp65
-rw-r--r--src/objects/CutsceneObject.h16
4 files changed, 174 insertions, 11 deletions
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