1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
6 #include "FacialAnimation/FacialInstance.h"
7 #include "CharacterManager.h"
8 #include <CryString/StringUtils.h>
10 uint
CDefaultSkeleton::s_guidLast
= 0;
12 CDefaultSkeleton::CDefaultSkeleton(const char* pSkeletonFilePath
, uint32 type
, uint64 nCRC64
) : m_strFilePath(pSkeletonFilePath
), m_nKeepInMemory(0), m_nFilePathCRC64(nCRC64
)
14 m_guid
= ++s_guidLast
;
19 m_nInstanceCounter
= 0;
20 m_arrAnimationLOD
.reserve(8);
22 m_pJointsCRCToIDMap
= NULL
;
23 m_AABBExtension
.min
= Vec3(ZERO
);
24 m_AABBExtension
.max
= Vec3(ZERO
);
26 m_usePhysProxyBBox
= 0;
28 m_ModelMeshEnabled
= false;
31 CDefaultSkeleton::~CDefaultSkeleton()
33 m_ModelMesh
.AbortStream();
34 IPhysicalWorld
* pIPhysicalWorld
= g_pIPhysicalWorld
;
35 IGeomManager
* pPhysGeomManager
= pIPhysicalWorld
? pIPhysicalWorld
->GetGeomManager() : NULL
;
38 uint32 numJoints
= m_arrModelJoints
.size();
39 for (uint32 i
= 0; i
< numJoints
; i
++)
41 phys_geometry
* pPhysGeom
= m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
;
43 continue; //joint is not physical geometry
44 if ((INT_PTR
)pPhysGeom
== -1)
45 CryFatalError("Joint '%s' (model '%s') was physicalized but failed to load geometry for some reason. Please check the setup", m_arrModelJoints
[i
].m_strJointName
.c_str(), GetModelFilePath());
46 else if ((UINT_PTR
)pPhysGeom
< 0x400)
47 CryFatalError("Joint '%s' (model '%s') somehow didn't get geometry index processing. At a certain stage the pointer holds an index of a mesh in cgf, and it is supposed to be processed and converted to a geometry pointer", m_arrModelJoints
[i
].m_strJointName
.c_str(), GetModelFilePath());
49 PREFAST_ASSUME(pPhysGeom
); // would be skipped if null
50 if (pPhysGeom
->pForeignData
)
51 pPhysGeomManager
->UnregisterGeometry((phys_geometry
*)pPhysGeom
->pForeignData
);
52 pPhysGeomManager
->UnregisterGeometry(pPhysGeom
);
54 if (m_pJointsCRCToIDMap
)
55 delete m_pJointsCRCToIDMap
;
58 SAFE_RELEASE(m_pFacialModel
);
59 if (m_nInstanceCounter
)
60 CryFatalError("The model '%s' still has %d skel-instances. Something went wrong with the ref-counting", m_strFilePath
.c_str(), m_nInstanceCounter
);
62 CryFatalError("The model '%s' has the value %d in the m_nRefCounter, while calling the destructor. Something went wrong with the ref-counting", m_strFilePath
.c_str(), m_nRefCounter
);
63 g_pILog
->LogToFile("CDefaultSkeleton Release: %s", m_strFilePath
.c_str());
64 g_pCharacterManager
->UnregisterModelSKEL(this);
67 //////////////////////////////////////////////////////////////////////////
68 void CDefaultSkeleton::CreateFacialInstance()
70 CModelMesh
* pModelMesh
= GetModelMesh();
73 m_pFacialModel
= new CFacialModel(this);
74 m_pFacialModel
->AddRef();
78 //////////////////////////////////////////////////////////////////////////
79 void CDefaultSkeleton::VerifyHierarchy()
85 uint32 m_nJointCRC32Lower
; //CRC32 of lowercase of the joint-name.
86 int32 m_nOffsetChildren
; //this is 0 if there are no children
87 uint16 m_numChildren
; //how many children does this joint have
88 int16 m_idxParent
; //index of parent-joint. if the idx==-1 then this joint is the root. Usually this values are > 0
89 int16 m_idxFirst
; //first child of this joint
90 int16 m_idxNext
; //sibling of this joint
93 void rebuild(uint32 numJoints
, CDefaultSkeleton::SJoint
* pModelJoints
)
95 for (uint32 j
= 0; j
< numJoints
; j
++)
97 m_arrHierarchy
[j
].m_nJointCRC32Lower
= pModelJoints
[j
].m_nJointCRC32Lower
;
98 m_arrHierarchy
[j
].m_idxParent
= pModelJoints
[j
].m_idxParent
;
99 m_arrHierarchy
[j
].m_nOffsetChildren
= 0;
100 m_arrHierarchy
[j
].m_numChildren
= 0;
101 m_arrHierarchy
[j
].m_idxFirst
= 0; //first child of this joint
102 m_arrHierarchy
[j
].m_idxNext
= 0; //sibling of this joint
104 for (uint32 j
= 1; j
< numJoints
; j
++)
106 int16 p
= m_arrHierarchy
[j
].m_idxParent
;
107 m_arrHierarchy
[p
].m_numChildren
++;
108 if (m_arrHierarchy
[p
].m_nOffsetChildren
== 0)
109 m_arrHierarchy
[p
].m_nOffsetChildren
= j
- p
;
110 if (m_arrHierarchy
[p
].m_idxFirst
== 0)
111 m_arrHierarchy
[p
].m_idxFirst
= j
; //this is the first born child
113 for (uint32 j
= 0; j
< numJoints
; j
++)
115 uint32 numOffset
= m_arrHierarchy
[j
].m_nOffsetChildren
;
116 uint32 numChildren
= m_arrHierarchy
[j
].m_numChildren
;
117 for (uint32 s
= 1; s
< numChildren
; s
++)
118 m_arrHierarchy
[numOffset
+ j
+ s
- 1].m_idxNext
= numOffset
+ j
+ s
; //and here come all its little brothers & sisters
120 for (uint32 j
= 0; j
< numJoints
; j
++)
122 int32 nOffsetChildren1
= pModelJoints
[j
].m_nOffsetChildren
; //this is 0 if there are no children
123 uint16 numChildren1
= pModelJoints
[j
].m_numChildren
; //how many children does this joint have
124 int32 nOffsetChildren2
= m_arrHierarchy
[j
].m_nOffsetChildren
; //this is 0 if there are no children
125 uint16 numChildren2
= m_arrHierarchy
[j
].m_numChildren
; //how many children does this joint have
126 if (numChildren1
!= numChildren2
)
127 CryFatalError("ModelError: numChildren must be identical");
128 if (nOffsetChildren1
!= nOffsetChildren2
)
129 CryFatalError("ModelError: child offset must be identical");
130 if (nOffsetChildren1
< 0 || nOffsetChildren2
< 0)
131 CryFatalError("ModelError: offset must be nonnegative");
132 if (numChildren1
&& nOffsetChildren1
== 0)
133 CryFatalError("ModelError: nOffsetChildren1 invalid");
134 if (numChildren1
== 0 && nOffsetChildren1
)
135 CryFatalError("ModelError: child offset not initialized");
139 void parse(int32 idx
, CDefaultSkeleton::SJoint
* pModelJoints
)
142 int32 s
= m_arrHierarchy
[idx
].m_idxNext
;
143 int32 c
= m_arrHierarchy
[idx
].m_idxFirst
;
147 CryFatalError("ModelError: offset for siblings must be higher than first child");
149 if (s
) parse(s
, pModelJoints
);
150 if (c
) parse(c
, pModelJoints
);
153 snode m_arrHierarchy
[MAX_JOINT_AMOUNT
];
157 //check that there are no duplicated CRC32s
158 uint32 numJoints
= m_arrModelJoints
.size();
159 for (uint32 i
= 1; i
< numJoints
; i
++)
161 uint32 nCRC32low
= m_arrModelJoints
[i
].m_nJointCRC32Lower
;
162 for (uint32 j
= 0; j
< i
; j
++)
164 if (m_arrModelJoints
[j
].m_nJointCRC32Lower
== nCRC32low
)
165 CryFatalError("ModelError: duplicated CRC32 in SKEL");
168 //check the integrity of the skeleton structure
169 vh
.rebuild(numJoints
, &m_arrModelJoints
[0]);
171 vh
.parse(0, &m_arrModelJoints
[0]);
172 if (vh
.m_idxnode
!= numJoints
)
173 CryFatalError("ModelError:: node-count must be identical");
176 //////////////////////////////////////////////////////////////////////////
178 int GetMeshApproxFlags(const char* str
, int len
)
181 if (CryStringUtils::strnstr(str
, "box", len
))
182 flags
|= mesh_approx_box
;
183 else if (CryStringUtils::strnstr(str
, "cylinder", len
))
184 flags
|= mesh_approx_cylinder
;
185 else if (CryStringUtils::strnstr(str
, "capsule", len
))
186 flags
|= mesh_approx_capsule
;
187 else if (CryStringUtils::strnstr(str
, "sphere", len
))
188 flags
|= mesh_approx_sphere
;
191 template<class T
> void _swap(T
& op1
, T
& op2
) { T tmp
= op1
; op1
= op2
; op2
= tmp
; }
193 bool CDefaultSkeleton::SetupPhysicalProxies(const DynArray
<PhysicalProxy
>& arrPhyBoneMeshes
, const DynArray
<BONE_ENTITY
>& arrBoneEntitiesSrc
, IMaterial
* pIMaterial
, const char* filename
)
196 m_bHasPhysics2
= false;
197 uint32 numBoneEntities
= arrBoneEntitiesSrc
.size();
198 uint32 numJoints
= m_arrModelJoints
.size();
199 if (numBoneEntities
> numJoints
)
200 CryFatalError("numBoneEntities must <= numJoints");
202 for (uint32 j
= 0; j
< numJoints
; j
++)
203 m_arrModelJoints
[j
].m_numLevels
= 0, m_arrModelJoints
[j
].m_numChildren
= 0, m_arrModelJoints
[j
].m_nOffsetChildren
= 0;
204 for (uint32 j
= 1; j
< numJoints
; j
++)
206 int16 p
= m_arrModelJoints
[j
].m_idxParent
;
207 m_arrModelJoints
[p
].m_numChildren
++;
208 if (m_arrModelJoints
[p
].m_nOffsetChildren
== 0)
209 m_arrModelJoints
[p
].m_nOffsetChildren
= j
- p
;
211 //set deepness-level inside hierarchy
212 for (uint32 i
= 0; i
< numJoints
; i
++)
214 int32 parent
= m_arrModelJoints
[i
].m_idxParent
;
217 m_arrModelJoints
[i
].m_numLevels
++;
218 parent
= m_arrModelJoints
[parent
].m_idxParent
;
225 memset(&be
, 0, sizeof(BONE_ENTITY
));
227 be
.phys
.nPhysGeom
= -1;
229 DynArray
<BONE_ENTITY
> arrBoneEntitiesSorted
;
230 arrBoneEntitiesSorted
.resize(numJoints
);
231 float dfltApproxTol
= 0.2f
;
232 for (uint32 id
= 0; id
< numJoints
; id
++)
234 arrBoneEntitiesSorted
[id
] = be
;
235 uint32 nCRC32
= m_arrModelJoints
[id
].m_nJointCRC32
;
236 for (uint32 e
= 0; e
< numBoneEntities
; e
++)
237 if (arrBoneEntitiesSrc
[e
].ControllerID
== nCRC32
) { arrBoneEntitiesSorted
[id
] = arrBoneEntitiesSrc
[e
]; break; }
238 arrBoneEntitiesSorted
[id
].BoneID
= id
;
239 arrBoneEntitiesSorted
[id
].ParentID
= m_arrModelJoints
[id
].m_idxParent
;
240 arrBoneEntitiesSorted
[id
].nChildren
= m_arrModelJoints
[id
].m_numChildren
;
241 arrBoneEntitiesSorted
[id
].ControllerID
= m_arrModelJoints
[id
].m_nJointCRC32
;
242 if (GetMeshApproxFlags(arrBoneEntitiesSorted
[id
].prop
, strnlen(arrBoneEntitiesSorted
[id
].prop
, sizeof(arrBoneEntitiesSorted
[id
].prop
))))
243 dfltApproxTol
= 0.05f
;
246 //loop over all BoneEntities and set the flags "joint_no_gravity" and "joint_isolated_accelerations" in m_PhysInfo.flags
247 for (uint32 i
= 0; i
< numBoneEntities
; i
++)
249 m_arrModelJoints
[i
].m_PhysInfo
.flags
&= ~(joint_no_gravity
| joint_isolated_accelerations
);
250 if (arrBoneEntitiesSorted
[i
].prop
[0] == 0)
252 m_arrModelJoints
[i
].m_PhysInfo
.flags
|= joint_no_gravity
| joint_isolated_accelerations
;
256 if (!CryStringUtils::strnstr(arrBoneEntitiesSorted
[i
].prop
, "gravity", sizeof(arrBoneEntitiesSorted
[i
].prop
)))
257 m_arrModelJoints
[i
].m_PhysInfo
.flags
|= joint_no_gravity
;
258 if (!CryStringUtils::strnstr(arrBoneEntitiesSorted
[i
].prop
, "active_phys", sizeof(arrBoneEntitiesSorted
[i
].prop
)))
259 m_arrModelJoints
[i
].m_PhysInfo
.flags
|= joint_isolated_accelerations
;
260 if (const char* ptr
= CryStringUtils::strnstr(arrBoneEntitiesSorted
[i
].prop
, "mass", sizeof(arrBoneEntitiesSorted
[i
].prop
)))
262 //CryFatalError("did we ever use this path???");
264 for (ptr
+= 4; *ptr
&& !(*ptr
>= '0' && *ptr
<= '9'); ptr
++)
266 if (*ptr
) mass
= (float)atof(ptr
);
267 m_arrModelJoints
[i
].m_fMass
= max(m_arrModelJoints
[i
].m_fMass
, mass
);
272 //link the proxies to the joints
273 if (!g_pIPhysicalWorld
)
278 IGeomManager
* pPhysicalGeometryManager
= g_pIPhysicalWorld
->GetGeomManager();
279 if (!pPhysicalGeometryManager
)
284 if (!arrPhyBoneMeshes
.empty() && !pIMaterial
)
286 g_pISystem
->Warning(VALIDATOR_MODULE_ANIMATION
, VALIDATOR_WARNING
, VALIDATOR_FLAG_FILE
, filename
, "Error loading skeleton: material definition is missing for physical proxies.");
290 //link the proxies to the joints
291 int useOnlyBoxes
= 0;
292 uint32 nHasPhysicsGeom
= 0;
293 uint32 numPBM
= arrPhyBoneMeshes
.size();
294 for (uint32 p
= 0; p
< numPBM
; p
++)
296 // the chunks from which the physical geometry is read are the bone mesh chunks.
297 PhysicalProxy pbm
= arrPhyBoneMeshes
[p
];
298 uint32 numFaces
= pbm
.m_arrMaterials
.size();
299 uint32 flags
= (numFaces
<= 20 ? mesh_SingleBB
: mesh_OBB
| mesh_AABB
| mesh_AABB_rotated
) | mesh_multicontact0
;
300 const uint32 flagsAllPrim
= mesh_approx_box
| ((mesh_approx_sphere
| mesh_approx_cylinder
| mesh_approx_capsule
) & (useOnlyBoxes
- 1));
302 // Assign custom material to physics.
303 int defSurfaceIdx
= pbm
.m_arrMaterials
.empty() ? 0 : pbm
.m_arrMaterials
[0];
304 int surfaceTypesId
[MAX_SUB_MATERIALS
];
305 memset(surfaceTypesId
, 0, sizeof(surfaceTypesId
));
306 int numIds
= pIMaterial
->FillSurfaceTypeIds(surfaceTypesId
);
308 //After loading, pPhysGeom is set to the value equal to the ChunkID in the file where the physical geometry (BoneMesh) chunk is kept.
309 //To initialize a bone with a proxy, we loop over all joints and replace the ChunkID in pPhysGeom with the actual physical geometry object pointers.
310 for (uint32 i
= 0; i
< numJoints
; ++i
)
312 INT_PTR cid
= INT_PTR(m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
);
313 if (pbm
.ChunkID
!= cid
)
316 uint32 flagsPrim
= GetMeshApproxFlags(arrBoneEntitiesSorted
[i
].prop
, strnlen(arrBoneEntitiesSorted
[i
].prop
, sizeof(arrBoneEntitiesSorted
[i
].prop
)));
317 IGeometry
* pPhysicalGeometry
= pPhysicalGeometryManager
->CreateMesh(&pbm
.m_arrPoints
[0], &pbm
.m_arrIndices
[0], &pbm
.m_arrMaterials
[0], 0, numFaces
,
318 flags
| (flagsPrim
? flagsPrim
: flagsAllPrim
), ((useOnlyBoxes
|flagsPrim
) ? 1.5f
: dfltApproxTol
));
319 if (pPhysicalGeometry
== 0)
321 g_pISystem
->Warning(VALIDATOR_MODULE_ANIMATION
, VALIDATOR_WARNING
, VALIDATOR_FLAG_FILE
, filename
, "Physics: Failed to create phys mesh");
322 assert(pPhysicalGeometry
);
325 phys_geometry
* pg
= pPhysicalGeometryManager
->RegisterGeometry(pPhysicalGeometry
, defSurfaceIdx
, &surfaceTypesId
[0], numIds
);
327 int id
= pg
->pGeom
->GetPrimitiveId(0, 0);
329 id
= pg
->surface_idx
;
330 if (uint32(id
) < uint32(pg
->nMats
))
331 id
= pg
->pMatMapping
[id
];
332 *(int*)(m_arrModelJoints
[i
].m_PhysInfo
.spring_angle
+ 1) = id
; //surface type index for rope physicalization (it's not ready at rc stage)
333 if (strnicmp(m_arrModelJoints
[i
].m_strJointName
.c_str(), "rope", 4))
334 m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
= pg
, nHasPhysicsGeom
++;
336 g_pIPhysicalWorld
->GetGeomManager()->UnregisterGeometry(pg
), m_arrModelJoints
[i
].m_PhysInfo
.flags
= -1;
337 pPhysicalGeometry
->Release();
341 for (uint32 i
= 0; i
< numJoints
; ++i
)
343 INT_PTR cid
= INT_PTR(m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
);
344 if (cid
>= -1 && cid
< 0x400)
345 m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
= 0;
347 for (int j
= 0; m_arrModelJoints
[i
].m_PhysInfo
.flags
!= -1 && m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
&& j
< 3; j
++)
349 // lock axes with 0 limits range
350 m_arrModelJoints
[i
].m_PhysInfo
.flags
|= (m_arrModelJoints
[i
].m_PhysInfo
.max
[j
] - m_arrModelJoints
[i
].m_PhysInfo
.min
[j
] <= 0.0f
) * angle0_locked
<< j
;
357 IGeometry
* pMeshGeom
;
359 IGeomManager
* pGeoman
= g_pIPhysicalWorld
->GetGeomManager();
360 for (int i
= arrBoneEntitiesSorted
.size() - 1; i
>= 0; i
--)
362 if (arrBoneEntitiesSorted
[i
].prop
[0] == 0)
364 CDefaultSkeleton::SJoint
* pBone
= &m_arrModelJoints
[i
];
365 if (pBone
->m_PhysInfo
.pPhysGeom
== 0)
367 uint32 type
= pBone
->m_PhysInfo
.pPhysGeom
->pGeom
->GetType();
368 if (type
== GEOM_TRIMESH
)
370 pmesh
= (mesh_data
*)(pMeshGeom
= pBone
->m_PhysInfo
.pPhysGeom
->pGeom
)->GetData();
371 if (pmesh
->nIslands
== 2 && (pcloth
= CryStringUtils::strnstr(arrBoneEntitiesSorted
[i
].prop
, "cloth_proxy", sizeof(arrBoneEntitiesSorted
[i
].prop
))))
373 //CryFatalError("cloth proxy found");
374 int itri
, j
, isle
= isneg(pmesh
->pIslands
[1].V
- pmesh
->pIslands
[0].V
);
375 for (itri
= pmesh
->pIslands
[isle
].itri
, j
= 0; j
< pmesh
->pIslands
[isle
].nTris
; itri
= pmesh
->pTri2Island
[isle
].inext
, j
++)
377 for (int ivtx
= 0; ivtx
< 3; ivtx
++)
378 _swap(pmesh
->pIndices
[itri
* 3 + ivtx
], pmesh
->pIndices
[j
* 3 + 2 - ivtx
]);
379 _swap(pmesh
->pMats
[itri
], pmesh
->pMats
[j
]);
382 phys_geometry
* pgeomMain
, * pgeomCloth
;
383 int flags
= GetMeshApproxFlags(arrBoneEntitiesSorted
[i
].prop
, static_cast<int>(pcloth
- arrBoneEntitiesSorted
[i
].prop
));
384 flags
|= (flags
|| pmesh
->pIslands
[isle
^ 1].nTris
< 20) ? mesh_SingleBB
: mesh_OBB
;
385 pMeshGeom
= pGeoman
->CreateMesh(pmesh
->pVertices
, pmesh
->pIndices
+ j
, pmesh
->pMats
+ j
, 0, pmesh
->pIslands
[isle
^ 1].nTris
, flags
, 1.0f
);
386 pgeomMain
= pGeoman
->RegisterGeometry(pMeshGeom
, pBone
->m_PhysInfo
.pPhysGeom
->surface_idx
, pBone
->m_PhysInfo
.pPhysGeom
->pMatMapping
, pBone
->m_PhysInfo
.pPhysGeom
->nMats
);
388 flags
= GetMeshApproxFlags(pcloth
, sizeof(arrBoneEntitiesSorted
[i
].prop
) - (pcloth
- arrBoneEntitiesSorted
[i
].prop
));
389 flags
|= (flags
|| pmesh
->pIslands
[isle
].nTris
< 20) ? mesh_SingleBB
: mesh_OBB
;
390 pMeshGeom
= pGeoman
->CreateMesh(pmesh
->pVertices
, pmesh
->pIndices
, pmesh
->pMats
, 0, j
, flags
, 1.0f
);
391 pgeomCloth
= pGeoman
->RegisterGeometry(pMeshGeom
, pBone
->m_PhysInfo
.pPhysGeom
->surface_idx
, pBone
->m_PhysInfo
.pPhysGeom
->pMatMapping
, pBone
->m_PhysInfo
.pPhysGeom
->nMats
);
392 pgeomMain
->pForeignData
= pgeomCloth
;
394 pGeoman
->UnregisterGeometry(pBone
->m_PhysInfo
.pPhysGeom
);
395 pBone
->m_PhysInfo
.pPhysGeom
= pgeomMain
;
399 int flags
= GetMeshApproxFlags(arrBoneEntitiesSorted
[i
].prop
, sizeof(arrBoneEntitiesSorted
[i
].prop
));
403 pBone
->m_PhysInfo
.pPhysGeom
->pGeom
= pGeoman
->CreateMesh(pmesh
->pVertices
, pmesh
->pIndices
, pmesh
->pMats
, 0, pmesh
->nTris
, flags
| mesh_SingleBB
, 1.0f
);
404 pMeshGeom
->Release();
407 m_bHasPhysics2
= true;
410 IStatObj
*pSkelCGF
= gEnv
->p3DEngine
->LoadStatObj(string(filename
) + ".cgf", nullptr, nullptr, false, IStatObj::ELoadingFlagsNoErrorIfFail
);
411 if (pSkelCGF
&& !pSkelCGF
->IsDefaultObject())
413 std::map
<uint32
,int> mapJoints
;
414 for(uint32 i
= 0; i
< numJoints
; i
++)
416 mapJoints
.insert(std::pair
<uint32
,int>(CCrc32::ComputeLowercase(m_arrModelJoints
[i
].m_strJointName
), i
));
417 CryBonePhysics
& phys
= m_arrModelJoints
[i
].m_PhysInfo
;
420 gEnv
->pPhysicalWorld
->GetGeomManager()->UnregisterGeometry(phys
.pPhysGeom
);
421 phys
.pPhysGeom
= nullptr;
424 m_bHasPhysics2
= true;
425 for(int i
= 0; i
< pSkelCGF
->GetSubObjectCount(); i
++)
427 IStatObj::SSubObject
& slot
= *pSkelCGF
->GetSubObject(i
);
428 auto idx
= mapJoints
.find(CCrc32::ComputeLowercase(slot
.name
));
429 if (idx
!= mapJoints
.end() && !slot
.name
.compareNoCase(m_arrModelJoints
[idx
->second
].m_strJointName
) && slot
.pStatObj
&& slot
.pStatObj
->GetPhysGeom())
431 CryBonePhysics
& phys
= m_arrModelJoints
[idx
->second
].m_PhysInfo
;
432 (phys
.pPhysGeom
= slot
.pStatObj
->GetPhysGeom())->nRefCount
++;
435 sscanf_s(slot
.properties
.c_str(), "%d %d %d %d %d %d %f %f %f %f %f %f %f %f %f",
436 &lim
[0].x
, &lim
[0].y
, &lim
[0].z
, &lim
[1].x
, &lim
[1].y
, &lim
[1].z
,
437 &phys
.spring_tension
[0], &phys
.spring_tension
[1], &phys
.spring_tension
[2],
438 &phys
.damping
[0], &phys
.damping
[1], &phys
.damping
[2],
439 &frame0
.x
, &frame0
.y
, &frame0
.z
);
440 *(Vec3
*)phys
.min
= DEG2RAD(Vec3(lim
[0]));
441 *(Vec3
*)phys
.max
= DEG2RAD(Vec3(lim
[1]));
442 phys
.flags
= joint_no_gravity
| joint_isolated_accelerations
;
443 for(int j
= 0; j
< 3; j
++)
445 phys
.flags
|= (angle0_locked
<< j
) * isneg(phys
.max
[j
] - phys
.min
[j
] - 0.01f
);
446 float unlim
= 1.0f
+ isneg(gf_PI
*1.999f
- phys
.max
[j
] + phys
.min
[j
]);
447 phys
.max
[j
] *= unlim
; phys
.min
[j
] *= unlim
;
449 *(Matrix33
*)phys
.framemtx
= Matrix33(DEG2RAD(frame0
));
450 m_bHasPhysics2
= true;
455 // transform framemtx from child frame to phys parent frame
456 for(uint32 i
= 0; i
< numJoints
; i
++)
457 if (m_arrModelJoints
[i
].m_PhysInfo
.pPhysGeom
)
459 int idxParent
= m_arrModelJoints
[i
].m_idxParent
;
460 while (idxParent
>= 0 && !m_arrModelJoints
[idxParent
].m_PhysInfo
.pPhysGeom
)
461 idxParent
= m_arrModelJoints
[idxParent
].m_idxParent
;
463 *(Matrix33
*)m_arrModelJoints
[i
].m_PhysInfo
.framemtx
= Matrix33(!GetDefaultAbsJointByID(idxParent
).q
* GetDefaultAbsJointByID(i
).q
) * *(Matrix33
*)m_arrModelJoints
[i
].m_PhysInfo
.framemtx
;
470 bool CDefaultSkeleton::ParsePhysInfoProperties_ROPE(CryBonePhysics
& pi
, const DynArray
<SJointProperty
>& props
)
472 uint32 numProps
= props
.size();
475 if (props
[0].type
< 2) //the first meber must be a const char*
478 if (!strcmp(props
[0].strval
, "Rope"))
480 *(alias_cast
<int*>(pi
.spring_angle
)) = 0x12345678;
482 pi
.flags
&= ~joint_isolated_accelerations
;
483 for (uint32 i
= 0; i
< numProps
; i
++)
485 if (!strcmp(props
[i
].name
, "Gravity"))
486 pi
.framemtx
[1][0] = props
[i
].fval
== 1.0f
? 9.81f
: props
[i
].fval
;
487 if (!strcmp(props
[i
].name
, "JointLimit"))
488 pi
.min
[0] = -DEG2RAD(props
[i
].fval
), pi
.spring_tension
[0] = 0;
489 if (!strcmp(props
[i
].name
, "JointLimitIncrease"))
490 pi
.spring_angle
[2] = props
[i
].fval
;
491 if (!strcmp(props
[i
].name
, "MaxTimestep"))
492 pi
.spring_tension
[1] = props
[i
].fval
;
493 if (!strcmp(props
[i
].name
, "Stiffness"))
494 pi
.max
[0] = DEG2RAD(props
[i
].fval
);
495 if (!strcmp(props
[i
].name
, "StiffnessDecay"))
496 pi
.max
[1] = DEG2RAD(props
[i
].fval
);
497 if (!strcmp(props
[i
].name
, "Damping"))
498 pi
.max
[2] = DEG2RAD(props
[i
].fval
);
499 if (!strcmp(props
[i
].name
, "Friction"))
500 pi
.spring_tension
[2] = props
[i
].fval
;
501 if (!strcmp(props
[i
].name
, "SimpleBlending"))
502 (pi
.flags
&= ~4) |= (props
[i
].bval
? 0 : 4);
503 if (!strcmp(props
[i
].name
, "Mass"))
504 pi
.min
[1] = DEG2RAD(-props
[i
].fval
);
505 if (!strcmp(props
[i
].name
, "Thickness"))
506 pi
.min
[2] = DEG2RAD(-props
[i
].fval
);
507 if (!strcmp(props
[i
].name
, "StiffnessControlBone"))
508 pi
.framemtx
[0][1] = props
[i
].fval
+ (props
[i
].fval
> 0.0f
);
509 if (!strcmp(props
[i
].name
, "SleepSpeed"))
510 pi
.damping
[0] = props
[i
].fval
+ 1.0f
;
511 else if (!strcmp(props
[i
].name
, "HingeY"))
512 (pi
.flags
&= ~8) |= (props
[i
].bval
? 8 : 0);
513 else if (!strcmp(props
[i
].name
, "HingeZ"))
514 (pi
.flags
&= ~16) |= (props
[i
].bval
? 16 : 0);
516 if (!strcmp(props
[i
].name
, "EnvCollisions"))
517 (pi
.flags
&= ~1) |= (props
[i
].bval
? 0 : 1);
518 if (!strcmp(props
[i
].name
, "BodyCollisions"))
519 (pi
.flags
&= ~2) |= (props
[i
].bval
? 0 : 2);
524 if (!strcmp(props
[0].strval
, "Cloth"))
526 *(alias_cast
<int*>(pi
.spring_angle
)) = 0x12345678;
528 pi
.flags
|= joint_isolated_accelerations
;
529 for (uint32 i
= 0; i
< numProps
; i
++)
531 if (!strcmp(props
[i
].name
, "MaxTimestep"))
532 pi
.damping
[0] = props
[i
].fval
;
533 if (!strcmp(props
[i
].name
, "MaxStretch"))
534 pi
.damping
[1] = props
[i
].fval
;
535 if (!strcmp(props
[i
].name
, "Stiffness"))
536 pi
.max
[2] = DEG2RAD(props
[i
].fval
);
537 if (!strcmp(props
[i
].name
, "Thickness"))
538 pi
.damping
[2] = props
[i
].fval
;
539 if (!strcmp(props
[i
].name
, "Friction"))
540 pi
.spring_tension
[2] = props
[i
].fval
;
541 if (!strcmp(props
[i
].name
, "StiffnessNorm"))
542 pi
.max
[0] = DEG2RAD(props
[i
].fval
);
543 if (!strcmp(props
[i
].name
, "StiffnessTang"))
544 pi
.max
[1] = DEG2RAD(props
[i
].fval
);
545 if (!strcmp(props
[i
].name
, "Damping"))
546 pi
.spring_tension
[0] = props
[i
].fval
;
547 if (!strcmp(props
[i
].name
, "AirResistance"))
548 pi
.spring_tension
[1] = props
[i
].fval
;
549 if (!strcmp(props
[i
].name
, "StiffnessAnim"))
550 pi
.min
[0] = props
[i
].fval
;
551 if (!strcmp(props
[i
].name
, "StiffnessDecayAnim"))
552 pi
.min
[1] = props
[i
].fval
;
553 if (!strcmp(props
[i
].name
, "DampingAnim"))
554 pi
.min
[2] = props
[i
].fval
;
555 else if (!strcmp(props
[i
].name
, "MaxIters"))
556 pi
.framemtx
[0][2] = props
[i
].fval
;
557 else if (!strcmp(props
[i
].name
, "MaxDistAnim"))
558 pi
.spring_angle
[2] = props
[i
].fval
;
559 else if (!strcmp(props
[i
].name
, "CharacterSpace"))
560 pi
.framemtx
[0][1] = props
[i
].fval
;
562 if (!strcmp(props
[i
].name
, "EnvCollisions"))
563 (pi
.flags
&= ~1) |= (props
[i
].bval
? 0 : 1);
564 if (!strcmp(props
[i
].name
, "BodyCollisions"))
565 (pi
.flags
&= ~2) |= (props
[i
].bval
? 0 : 2);
573 DynArray
<SJointProperty
> CDefaultSkeleton::GetPhysInfoProperties_ROPE(const CryBonePhysics
& pi
, int32 nRopeOrGrid
)
575 DynArray
<SJointProperty
> res
;
576 if (nRopeOrGrid
== 0)
578 res
.push_back(SJointProperty("Type", "Rope"));
579 res
.push_back(SJointProperty("Gravity", pi
.framemtx
[1][0]));
581 float jl
= pi
.spring_tension
[0];
582 if (pi
.min
[0] != 0) jl
= RAD2DEG(fabs_tpl(pi
.min
[0]));
583 res
.push_back(SJointProperty("JointLimit", jl
));
584 res
.push_back(SJointProperty("JointLimitIncrease", pi
.spring_angle
[2]));
586 float jli
= pi
.spring_tension
[1];
587 if (jli
<= 0 || jli
>= 1) jli
= 0.02f
;
588 res
.push_back(SJointProperty("MaxTimestep", jli
));
589 res
.push_back(SJointProperty("Stiffness", max(0.001f
, RAD2DEG(pi
.max
[0]))));
590 res
.push_back(SJointProperty("StiffnessDecay", RAD2DEG(pi
.max
[1])));
591 res
.push_back(SJointProperty("Damping", RAD2DEG(pi
.max
[2])));
592 res
.push_back(SJointProperty("Friction", pi
.spring_tension
[2]));
593 res
.push_back(SJointProperty("SimpleBlending", !(pi
.flags
& 4)));
594 res
.push_back(SJointProperty("Mass", RAD2DEG(fabs_tpl(pi
.min
[1]))));
595 res
.push_back(SJointProperty("Thickness", RAD2DEG(fabs_tpl(pi
.min
[2]))));
596 res
.push_back(SJointProperty("SleepSpeed", pi
.damping
[0] - 1.0f
));
597 res
.push_back(SJointProperty("HingeY", (pi
.flags
& 8) != 0));
598 res
.push_back(SJointProperty("HingeZ", (pi
.flags
& 16) != 0));
599 res
.push_back(SJointProperty("StiffnessControlBone", (float)FtoI(pi
.framemtx
[0][1] - 1.0f
) * (pi
.framemtx
[0][1] >= 2.0f
&& pi
.framemtx
[0][1] < 100.0f
)));
600 res
.push_back(SJointProperty("EnvCollisions", !(pi
.flags
& 1)));
601 res
.push_back(SJointProperty("BodyCollisions", !(pi
.flags
& 2)));
606 res
.push_back(SJointProperty("Type", "Cloth"));
607 res
.push_back(SJointProperty("MaxTimestep", pi
.damping
[0]));
608 res
.push_back(SJointProperty("MaxStretch", pi
.damping
[1]));
609 res
.push_back(SJointProperty("Stiffness", RAD2DEG(pi
.max
[2])));
610 res
.push_back(SJointProperty("Thickness", pi
.damping
[2]));
611 res
.push_back(SJointProperty("Friction", pi
.spring_tension
[2]));
612 res
.push_back(SJointProperty("StiffnessNorm", RAD2DEG(pi
.max
[0])));
613 res
.push_back(SJointProperty("StiffnessTang", RAD2DEG(pi
.max
[1])));
614 res
.push_back(SJointProperty("Damping", pi
.spring_tension
[0]));
615 res
.push_back(SJointProperty("AirResistance", pi
.spring_tension
[1]));
616 res
.push_back(SJointProperty("StiffnessAnim", pi
.min
[0]));
617 res
.push_back(SJointProperty("StiffnessDecayAnim", pi
.min
[1]));
618 res
.push_back(SJointProperty("DampingAnim", pi
.min
[2]));
619 res
.push_back(SJointProperty("MaxIters", (float)FtoI(pi
.framemtx
[0][2])));
620 res
.push_back(SJointProperty("MaxDistAnim", pi
.spring_angle
[2]));
621 res
.push_back(SJointProperty("CharacterSpace", pi
.framemtx
[0][1]));
623 res
.push_back(SJointProperty("EnvCollisions", !(pi
.flags
& 1)));
624 res
.push_back(SJointProperty("BodyCollisions", !(pi
.flags
& 2)));
629 // TODO: All the hard codednames need to be refactored away.
630 void CDefaultSkeleton::InitializeHardcodedJointsProperty()
632 uint32 numJoints
= m_arrModelJoints
.size();
633 for (uint32 i
= 0; i
< numJoints
; i
++)
635 const char* BoneName
= m_arrModelJoints
[i
].m_strJointName
.c_str();
636 // NOTE: Needed by CSkeletonPhysics to build the Articulated Entity
637 // self-collision properties.
638 if (strstr(BoneName
, "Forearm"))
639 m_arrModelJoints
[i
].m_flags
|= eJointFlag_NameHasForearm
;
640 if (strstr(BoneName
, "Calf"))
641 m_arrModelJoints
[i
].m_flags
|= eJointFlag_NameHasCalf
;
642 if (strstr(BoneName
, "Pelvis") || strstr(BoneName
, "Head") || strstr(BoneName
, "Spine") || strstr(BoneName
, "Thigh"))
643 m_arrModelJoints
[i
].m_flags
|= eJointFlag_NameHasPelvisOrHeadOrSpineOrThigh
;
647 //-----------------------------------------------------------------------------
648 int32
CDefaultSkeleton::RemapIdx(const CDefaultSkeleton
* pCDefaultSkeletonSrc
, const int32 idx
)
650 #if !defined(_RELEASE)
651 if (idx
< 0) CryFatalError("can't remap negative index");
653 int32 nidx
= GetJointIDByCRC32(pCDefaultSkeletonSrc
->m_arrModelJoints
[idx
].m_nJointCRC32Lower
);
654 #if !defined(_RELEASE)
655 if (nidx
< 0) CryFatalError("index remapping failed");
660 bool FindJointInParentHierarchy(const CDefaultSkeleton
* const pDefaultSkeleton
, const int32 jointIdToSearch
, const int16 jointIdToStartSearchFrom
)
662 CRY_ASSERT(pDefaultSkeleton
);
663 CRY_ASSERT(0 <= jointIdToSearch
);
664 CRY_ASSERT(0 <= jointIdToStartSearchFrom
);
666 int32 currentJoint
= jointIdToStartSearchFrom
;
667 while (currentJoint
!= -1)
669 if (currentJoint
== jointIdToSearch
)
673 currentJoint
= pDefaultSkeleton
->GetJointParentIDByID(currentJoint
);
678 void CDefaultSkeleton::CopyAndAdjustSkeletonParams(const CDefaultSkeleton
* pCDefaultSkeletonSrc
)
680 m_pAnimationSet
= pCDefaultSkeletonSrc
->m_pAnimationSet
;
681 m_animListIDs
= pCDefaultSkeletonSrc
->m_animListIDs
;
682 //m_ModelMesh = pCDefaultSkeletonSrc->m_ModelMesh; //just forget the Modelmesh
684 m_ModelAABB
= pCDefaultSkeletonSrc
->m_ModelAABB
;
685 m_AABBExtension
= pCDefaultSkeletonSrc
->m_AABBExtension
;
687 for (uint32 i
= 0; i
< MAX_FEET_AMOUNT
; i
++)
688 m_strFeetLockIKHandle
[i
] = pCDefaultSkeletonSrc
->m_strFeetLockIKHandle
[i
];
690 //remap animation lod
691 m_arrAnimationLOD
= pCDefaultSkeletonSrc
->m_arrAnimationLOD
;
694 if (pCDefaultSkeletonSrc
->m_pFacialModel
)
696 m_pFacialModel
= pCDefaultSkeletonSrc
->m_pFacialModel
;
697 m_pFacialModel
->AddRef();
701 m_BBoxIncludeList
= pCDefaultSkeletonSrc
->m_BBoxIncludeList
;
702 uint32 numIncludeList
= m_BBoxIncludeList
.size();
703 for (uint32 i
= 0; i
< numIncludeList
; i
++)
704 m_BBoxIncludeList
[i
] = RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_BBoxIncludeList
[i
]);
706 m_usePhysProxyBBox
= pCDefaultSkeletonSrc
->m_usePhysProxyBBox
;
708 //remap capsule shadow list
709 m_ShadowCapsulesList
= pCDefaultSkeletonSrc
->m_ShadowCapsulesList
;
710 uint32 numShadowCapsulesList
= m_ShadowCapsulesList
.size();
711 for (uint32 i
= 0; i
< numShadowCapsulesList
; i
++)
712 for (uint32 n
= 0; n
< 2; n
++)
713 m_ShadowCapsulesList
[i
].arrJoints
[n
] = RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_ShadowCapsulesList
[i
].arrJoints
[n
]);
716 m_IKLimbTypes
= pCDefaultSkeletonSrc
->m_IKLimbTypes
;
717 uint32 numLimbTypes
= m_IKLimbTypes
.size();
718 for (uint32 i
= 0; i
< numLimbTypes
; i
++)
720 uint32 numJointChain
= pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrJointChain
.size();
721 for (uint32 j
= 0; j
< numJointChain
; j
++)
722 m_IKLimbTypes
[i
].m_arrJointChain
[j
].m_idxJoint
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrJointChain
[j
].m_idxJoint
);
723 uint32 numLimbChildren
= pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrLimbChildren
.size();
724 for (uint32 j
= 0; j
< numLimbChildren
; j
++)
725 m_IKLimbTypes
[i
].m_arrLimbChildren
[j
] = RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrLimbChildren
[j
]);
726 uint32 numRootToEndEffector
= pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrRootToEndEffector
.size();
727 for (uint32 j
= 0; j
< numRootToEndEffector
; j
++)
728 m_IKLimbTypes
[i
].m_arrRootToEndEffector
[j
] = RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_IKLimbTypes
[i
].m_arrRootToEndEffector
[j
]);
732 m_ADIKTargets
= pCDefaultSkeletonSrc
->m_ADIKTargets
;
733 uint32 numADIKTargets
= pCDefaultSkeletonSrc
->m_ADIKTargets
.size();
734 for (uint32 i
= 0; i
< numADIKTargets
; i
++)
736 m_ADIKTargets
[i
].m_idxWeight
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_ADIKTargets
[i
].m_idxWeight
);
737 m_ADIKTargets
[i
].m_idxTarget
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_ADIKTargets
[i
].m_idxTarget
);
741 m_recoilDesc
= pCDefaultSkeletonSrc
->m_recoilDesc
;
742 if (pCDefaultSkeletonSrc
->m_recoilDesc
.m_weaponRightJointIndex
> 0)
743 m_recoilDesc
.m_weaponRightJointIndex
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_recoilDesc
.m_weaponRightJointIndex
);
744 if (pCDefaultSkeletonSrc
->m_recoilDesc
.m_weaponLeftJointIndex
> 0)
745 m_recoilDesc
.m_weaponLeftJointIndex
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_recoilDesc
.m_weaponLeftJointIndex
);
746 uint32 numRecoilJoints
= m_recoilDesc
.m_joints
.size();
747 for (uint32 i
= 0; i
< numRecoilJoints
; i
++)
748 m_recoilDesc
.m_joints
[i
].m_nIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_recoilDesc
.m_joints
[i
].m_nIdx
);
751 m_poseBlenderLookDesc
= pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
;
752 uint32 numBlendsLook
= m_poseBlenderLookDesc
.m_blends
.size();
753 for (uint32 i
= 0; i
< numBlendsLook
; i
++)
755 m_poseBlenderLookDesc
.m_blends
[i
].m_nParaJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
.m_blends
[i
].m_nParaJointIdx
);
756 m_poseBlenderLookDesc
.m_blends
[i
].m_nStartJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
.m_blends
[i
].m_nStartJointIdx
);
757 m_poseBlenderLookDesc
.m_blends
[i
].m_nReferenceJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
.m_blends
[i
].m_nReferenceJointIdx
);
758 m_poseBlenderLookDesc
.m_blends
[i
].m_nRotParaJointIdx
= -1;
759 m_poseBlenderLookDesc
.m_blends
[i
].m_nRotStartJointIdx
= -1;
762 uint32 numRotationsLook
= m_poseBlenderLookDesc
.m_rotations
.size();
763 for (uint32 i
= 0; i
< numRotationsLook
; i
++)
765 m_poseBlenderLookDesc
.m_rotations
[i
].m_nPosIndex
= -1;
766 int32 jidx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
.m_rotations
[i
].m_nJointIdx
);
767 m_poseBlenderLookDesc
.m_rotations
[i
].m_nJointIdx
= jidx
;
768 const int32 parentJointIndex
= GetJointParentIDByID(m_poseBlenderLookDesc
.m_rotations
[i
].m_nJointIdx
);
769 for (uint32 p
= 0; p
< numRotationsLook
; ++p
)
771 const SJointsAimIK_Rot
& otherAimIkRot
= m_poseBlenderLookDesc
.m_rotations
[p
];
772 if (m_poseBlenderLookDesc
.m_rotations
[i
].m_nPreEvaluate
&& otherAimIkRot
.m_nPreEvaluate
)
774 const bool isCurrentJointParentOfPreviousJoint
= FindJointInParentHierarchy(this, jidx
, otherAimIkRot
.m_nJointIdx
);
775 if (isCurrentJointParentOfPreviousJoint
)
776 m_poseBlenderLookDesc
.m_error
++;
778 if (otherAimIkRot
.m_nJointIdx
== parentJointIndex
)
780 m_poseBlenderLookDesc
.m_rotations
[i
].m_nRotJointParentIdx
= p
;
785 uint32 numPositionLook
= m_poseBlenderLookDesc
.m_positions
.size();
786 for (uint32 i
= 0; i
< numPositionLook
; i
++)
787 m_poseBlenderLookDesc
.m_positions
[i
].m_nJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderLookDesc
.m_positions
[i
].m_nJointIdx
);
788 for (uint32 i
= 0; i
< numBlendsLook
; ++i
)
790 for (uint32 r
= 0; r
< numRotationsLook
; ++r
)
792 const int32 jointIndex
= m_poseBlenderLookDesc
.m_rotations
[r
].m_nJointIdx
;
793 if (jointIndex
== m_poseBlenderLookDesc
.m_blends
[i
].m_nParaJointIdx
)
794 m_poseBlenderLookDesc
.m_blends
[i
].m_nRotParaJointIdx
= r
;
795 if (jointIndex
== m_poseBlenderLookDesc
.m_blends
[i
].m_nStartJointIdx
)
796 m_poseBlenderLookDesc
.m_blends
[i
].m_nRotStartJointIdx
= r
;
799 uint32 numRotLook
= m_poseBlenderLookDesc
.m_rotations
.size();
800 uint32 numPosLook
= m_poseBlenderLookDesc
.m_positions
.size();
801 for (uint32 r
= 0; r
< numRotLook
; r
++)
803 const char* pRotName
= m_poseBlenderLookDesc
.m_rotations
[r
].m_strJointName
;
806 for (uint32 p
= 0; p
< numPosLook
; p
++)
808 const char* pPosName
= m_poseBlenderLookDesc
.m_positions
[p
].m_strJointName
;
811 uint32 SameJoint
= strcmp(pRotName
, pPosName
) == 0;
814 m_poseBlenderLookDesc
.m_rotations
[r
].m_nPosIndex
= p
;
821 m_poseBlenderAimDesc
= pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
;
822 uint32 numBlends
= m_poseBlenderAimDesc
.m_blends
.size();
823 for (uint32 i
= 0; i
< numBlends
; i
++)
825 m_poseBlenderAimDesc
.m_blends
[i
].m_nParaJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_blends
[i
].m_nParaJointIdx
);
826 m_poseBlenderAimDesc
.m_blends
[i
].m_nStartJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_blends
[i
].m_nStartJointIdx
);
827 m_poseBlenderAimDesc
.m_blends
[i
].m_nReferenceJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_blends
[i
].m_nReferenceJointIdx
);
828 m_poseBlenderAimDesc
.m_blends
[i
].m_nRotParaJointIdx
= -1;
829 m_poseBlenderAimDesc
.m_blends
[i
].m_nRotStartJointIdx
= -1;
831 uint32 numRotations
= m_poseBlenderAimDesc
.m_rotations
.size();
832 for (uint32 i
= 0; i
< numRotations
; i
++)
834 m_poseBlenderAimDesc
.m_rotations
[i
].m_nPosIndex
= -1;
835 int32 jidx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_rotations
[i
].m_nJointIdx
);
836 m_poseBlenderAimDesc
.m_rotations
[i
].m_nJointIdx
= jidx
;
837 const int32 parentJointIndex
= GetJointParentIDByID(m_poseBlenderAimDesc
.m_rotations
[i
].m_nJointIdx
);
838 for (uint32 p
= 0; p
< numRotations
; ++p
)
840 const SJointsAimIK_Rot
& otherAimIkRot
= m_poseBlenderAimDesc
.m_rotations
[p
];
841 if (m_poseBlenderAimDesc
.m_rotations
[i
].m_nPreEvaluate
&& otherAimIkRot
.m_nPreEvaluate
)
843 const bool isCurrentJointParentOfPreviousJoint
= FindJointInParentHierarchy(this, jidx
, otherAimIkRot
.m_nJointIdx
);
844 if (isCurrentJointParentOfPreviousJoint
)
845 m_poseBlenderAimDesc
.m_error
++;
847 if (otherAimIkRot
.m_nJointIdx
== parentJointIndex
)
849 m_poseBlenderAimDesc
.m_rotations
[i
].m_nRotJointParentIdx
= p
;
854 uint32 numPosition
= m_poseBlenderAimDesc
.m_positions
.size();
855 for (uint32 i
= 0; i
< numPosition
; i
++)
856 m_poseBlenderAimDesc
.m_positions
[i
].m_nJointIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_positions
[i
].m_nJointIdx
);
857 uint32 numProcAdjust
= m_poseBlenderAimDesc
.m_procAdjustments
.size();
858 for (uint32 i
= 0; i
< numProcAdjust
; i
++)
859 m_poseBlenderAimDesc
.m_procAdjustments
[i
].m_nIdx
= RemapIdx(pCDefaultSkeletonSrc
, pCDefaultSkeletonSrc
->m_poseBlenderAimDesc
.m_procAdjustments
[i
].m_nIdx
);
860 for (uint32 i
= 0; i
< numBlends
; ++i
)
862 for (uint32 r
= 0; r
< numRotations
; ++r
)
864 const int32 jointIndex
= m_poseBlenderAimDesc
.m_rotations
[r
].m_nJointIdx
;
865 if (jointIndex
== m_poseBlenderAimDesc
.m_blends
[i
].m_nParaJointIdx
)
866 m_poseBlenderAimDesc
.m_blends
[i
].m_nRotParaJointIdx
= r
;
867 if (jointIndex
== m_poseBlenderAimDesc
.m_blends
[i
].m_nStartJointIdx
)
868 m_poseBlenderAimDesc
.m_blends
[i
].m_nRotStartJointIdx
= r
;
871 uint32 numRot
= m_poseBlenderAimDesc
.m_rotations
.size();
872 uint32 numPos
= m_poseBlenderAimDesc
.m_positions
.size();
873 for (uint32 r
= 0; r
< numRot
; r
++)
875 const char* pRotName
= m_poseBlenderAimDesc
.m_rotations
[r
].m_strJointName
;
878 for (uint32 p
= 0; p
< numPos
; p
++)
880 const char* pPosName
= m_poseBlenderAimDesc
.m_positions
[p
].m_strJointName
;
883 uint32 SameJoint
= strcmp(pRotName
, pPosName
) == 0;
886 m_poseBlenderAimDesc
.m_rotations
[r
].m_nPosIndex
= p
;
893 std::pair
<const uint32
*, const uint32
*> CDefaultSkeleton::FindClosestAnimationLod(const int lodValue
) const
895 const auto maxLod
= m_arrAnimationLOD
.size();
896 if (lodValue
> 0 && maxLod
> 0)
898 const auto lodIndex
= std::min
<int>(lodValue
, maxLod
) - 1;
899 return{ &m_arrAnimationLOD
[lodIndex
][0], &m_arrAnimationLOD
[lodIndex
][0] + m_arrAnimationLOD
[lodIndex
].size() };
903 return{ nullptr, nullptr };
907 uint32
CDefaultSkeleton::SizeOfDefaultSkeleton() const
909 uint32 nSize
= sizeof(CDefaultSkeleton
);
911 nSize
+= m_ModelMesh
.SizeOfModelMesh();
912 nSize
+= m_arrAnimationLOD
.get_alloc_size();
913 uint32 numAnimLOD
= m_arrAnimationLOD
.size();
914 for (uint32 i
= 0; i
< numAnimLOD
; i
++)
915 nSize
+= m_arrAnimationLOD
[i
].get_alloc_size();
917 nSize
+= m_pFacialModel
->SizeOfThis();
919 nSize
+= m_poseDefaultData
.GetAllocationLength();
920 nSize
+= m_arrModelJoints
.get_alloc_size();
921 uint32 numModelJoints
= m_arrModelJoints
.size();
922 for (uint32 i
= 0; i
< numModelJoints
; i
++)
923 nSize
+= m_arrModelJoints
[i
].m_strJointName
.capacity();
925 for (uint32 i
= 0; i
< MAX_FEET_AMOUNT
; i
++)
926 nSize
+= m_strFeetLockIKHandle
[i
].capacity();
928 nSize
+= m_recoilDesc
.m_joints
.get_alloc_size();
929 nSize
+= m_recoilDesc
.m_ikHandleLeft
.capacity();
930 nSize
+= m_recoilDesc
.m_ikHandleRight
.capacity();
932 nSize
+= m_poseBlenderLookDesc
.m_eyeAttachmentLeftName
.capacity(); //left eyeball attachment
933 nSize
+= m_poseBlenderLookDesc
.m_eyeAttachmentRightName
.capacity(); //right eyeball attachment
934 nSize
+= m_poseBlenderLookDesc
.m_blends
.get_alloc_size(); //parameters for aiming
935 nSize
+= m_poseBlenderLookDesc
.m_rotations
.get_alloc_size(); //rotational joints used for Look-IK
936 nSize
+= m_poseBlenderLookDesc
.m_positions
.get_alloc_size(); //positional joints used for Look-IK
938 nSize
+= m_poseBlenderAimDesc
.m_blends
.get_alloc_size(); //parameters for aiming
939 nSize
+= m_poseBlenderAimDesc
.m_rotations
.get_alloc_size(); //rotational joints used for Aim-IK
940 nSize
+= m_poseBlenderAimDesc
.m_positions
.get_alloc_size(); //positional joints used for Aim-IK
942 nSize
+= m_ADIKTargets
.get_alloc_size(); //array with Animation Driven IK-Targets
944 nSize
+= m_IKLimbTypes
.get_alloc_size(); //array with limbs we can apply a two-bone solver
945 uint32 numLimb
= m_IKLimbTypes
.size();
946 for (uint32 i
= 0; i
< numLimb
; i
++)
948 nSize
+= m_IKLimbTypes
[i
].m_arrJointChain
.get_alloc_size();
949 nSize
+= m_IKLimbTypes
[i
].m_arrLimbChildren
.get_alloc_size();
954 void CDefaultSkeleton::GetMemoryUsage(ICrySizer
* pSizer
) const
956 pSizer
->AddObject(this, sizeof(*this));
957 pSizer
->AddObject(m_strAnimEventFilePath
);
960 SIZER_COMPONENT_NAME(pSizer
, "CModelMesh");
961 pSizer
->AddObject(m_ModelMesh
);
965 SIZER_SUBCOMPONENT_NAME(pSizer
, "FacialModel");
966 pSizer
->AddObject(m_pFacialModel
);
970 SIZER_SUBCOMPONENT_NAME(pSizer
, "SkeletonData");
971 pSizer
->AddObject(m_poseDefaultData
);
972 pSizer
->AddObject(m_arrModelJoints
);
974 for (uint32 i
= 0; i
< MAX_FEET_AMOUNT
; i
++)
975 pSizer
->AddObject(m_strFeetLockIKHandle
[i
]);
977 pSizer
->AddObject(m_recoilDesc
.m_joints
);
978 pSizer
->AddObject(m_recoilDesc
.m_ikHandleLeft
);
979 pSizer
->AddObject(m_recoilDesc
.m_ikHandleRight
);
981 pSizer
->AddObject(m_poseBlenderLookDesc
.m_eyeAttachmentLeftName
);
982 pSizer
->AddObject(m_poseBlenderLookDesc
.m_eyeAttachmentRightName
);
983 pSizer
->AddObject(m_poseBlenderLookDesc
.m_blends
);
984 pSizer
->AddObject(m_poseBlenderLookDesc
.m_rotations
);
985 pSizer
->AddObject(m_poseBlenderLookDesc
.m_positions
);
987 pSizer
->AddObject(m_poseBlenderAimDesc
.m_blends
);
988 pSizer
->AddObject(m_poseBlenderAimDesc
.m_rotations
);
989 pSizer
->AddObject(m_poseBlenderAimDesc
.m_positions
);
991 pSizer
->AddObject(m_ADIKTargets
);
992 pSizer
->AddObject(m_IKLimbTypes
);
996 //#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
997 //----> CModelMesh, CGAs and all interfaces to access the mesh and the IMaterials will be removed in the future
998 //#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
999 void CDefaultSkeleton::PrecacheMesh(bool bFullUpdate
, int nRoundId
, int nLod
)
1001 if (CModelMesh
* pModelMesh
= GetModelMesh())
1003 const int nZoneIdx
= bFullUpdate
? 0 : 1;
1004 pModelMesh
->m_stream
.nRoundIds
[nZoneIdx
] = nRoundId
;
1008 //////////////////////////////////////////////////////////////////////////
1009 uint32
CDefaultSkeleton::GetTextureMemoryUsage2(ICrySizer
* pSizer
) const
1014 if (m_ModelMesh
.m_pIRenderMesh
)
1015 nSize
+= (uint32
)m_ModelMesh
.m_pIRenderMesh
->GetTextureMemoryUsage(m_ModelMesh
.m_pIDefaultMaterial
, pSizer
);
1019 if (m_ModelMesh
.m_pIRenderMesh
)
1020 nSize
= (uint32
)m_ModelMesh
.m_pIRenderMesh
->GetTextureMemoryUsage(m_ModelMesh
.m_pIDefaultMaterial
);
1025 //////////////////////////////////////////////////////////////////////////
1026 uint32
CDefaultSkeleton::GetMeshMemoryUsage(ICrySizer
* pSizer
) const
1029 if (m_ModelMesh
.m_pIRenderMesh
)
1031 nSize
+= m_ModelMesh
.m_pIRenderMesh
->GetMemoryUsage(0, IRenderMesh::MEM_USAGE_ONLY_STREAMS
);