!BI (CE-16391) (3dengine) cl 1643612,1646719 added a flag to suppress warning message...
[CRYENGINE.git] / Code / CryEngine / CryAnimation / Model.cpp
blobe110ce34ac1977315c2c8602ba75483babbcc12c
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "stdafx.h"
4 #include "Model.h"
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;
16 m_pFacialModel = 0;
17 m_ObjectType = type;
18 m_nRefCounter = 0;
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);
25 m_bHasPhysics2 = 0;
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;
36 if (pPhysGeomManager)
38 uint32 numJoints = m_arrModelJoints.size();
39 for (uint32 i = 0; i < numJoints; i++)
41 phys_geometry* pPhysGeom = m_arrModelJoints[i].m_PhysInfo.pPhysGeom;
42 if (pPhysGeom == 0)
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);
61 if (m_nRefCounter)
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();
71 if (pModelMesh)
73 m_pFacialModel = new CFacialModel(this);
74 m_pFacialModel->AddRef();
78 //////////////////////////////////////////////////////////////////////////
79 void CDefaultSkeleton::VerifyHierarchy()
81 struct
83 struct snode
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)
141 m_idxnode++;
142 int32 s = m_arrHierarchy[idx].m_idxNext;
143 int32 c = m_arrHierarchy[idx].m_idxFirst;
144 if (s && c)
146 if (s >= c)
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];
154 uint32 m_idxnode;
155 } vh;
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]);
170 vh.m_idxnode = 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)
180 int flags = 0;
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;
189 return flags;
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)
195 //set children
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;
215 while (parent >= 0)
217 m_arrModelJoints[i].m_numLevels++;
218 parent = m_arrModelJoints[parent].m_idxParent;
222 //return 1;
224 BONE_ENTITY be;
225 memset(&be, 0, sizeof(BONE_ENTITY));
226 be.ParentID = -1;
227 be.phys.nPhysGeom = -1;
228 be.phys.flags = -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;
254 else
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???");
263 f32 mass = 0.0f;
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)
275 return false;
278 IGeomManager* pPhysicalGeometryManager = g_pIPhysicalWorld->GetGeomManager();
279 if (!pPhysicalGeometryManager)
281 return false;
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.");
287 return false;
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)
314 continue;
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);
323 return false;
325 phys_geometry* pg = pPhysicalGeometryManager->RegisterGeometry(pPhysicalGeometry, defSurfaceIdx, &surfaceTypesId[0], numIds);
327 int id = pg->pGeom->GetPrimitiveId(0, 0);
328 if (id < 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++;
335 else
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;
354 if (nHasPhysicsGeom)
356 mesh_data* pmesh;
357 IGeometry* pMeshGeom;
358 const char* pcloth;
359 IGeomManager* pGeoman = g_pIPhysicalWorld->GetGeomManager();
360 for (int i = arrBoneEntitiesSorted.size() - 1; i >= 0; i--)
362 if (arrBoneEntitiesSorted[i].prop[0] == 0)
363 continue;
364 CDefaultSkeleton::SJoint* pBone = &m_arrModelJoints[i];
365 if (pBone->m_PhysInfo.pPhysGeom == 0)
366 continue;
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;
396 continue;
399 int flags = GetMeshApproxFlags(arrBoneEntitiesSorted[i].prop, sizeof(arrBoneEntitiesSorted[i].prop));
400 if (!flags)
401 continue;
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;
418 if (phys.pPhysGeom)
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++;
433 Vec3i lim[2];
434 Ang3 frame0;
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;
453 pSkelCGF->Release();
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;
462 if (idxParent >= 0)
463 *(Matrix33*)m_arrModelJoints[i].m_PhysInfo.framemtx = Matrix33(!GetDefaultAbsJointByID(idxParent).q * GetDefaultAbsJointByID(i).q) * *(Matrix33*)m_arrModelJoints[i].m_PhysInfo.framemtx;
467 return true;
470 bool CDefaultSkeleton::ParsePhysInfoProperties_ROPE(CryBonePhysics& pi, const DynArray<SJointProperty>& props)
472 uint32 numProps = props.size();
473 if (numProps == 0)
474 return 0;
475 if (props[0].type < 2) //the first meber must be a const char*
476 return 0;
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);
521 return true;
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);
567 return true;
570 return false;
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)));
604 if (nRopeOrGrid > 0)
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)));
626 return res;
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");
652 #endif
653 int32 nidx = GetJointIDByCRC32(pCDefaultSkeletonSrc->m_arrModelJoints[idx].m_nJointCRC32Lower);
654 #if !defined(_RELEASE)
655 if (nidx < 0) CryFatalError("index remapping failed");
656 #endif
657 return nidx;
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)
671 return true;
673 currentJoint = pDefaultSkeleton->GetJointParentIDByID(currentJoint);
675 return false;
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;
693 //remap facial model
694 if (pCDefaultSkeletonSrc->m_pFacialModel)
696 m_pFacialModel = pCDefaultSkeletonSrc->m_pFacialModel;
697 m_pFacialModel->AddRef();
700 //remap include list
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]);
715 //remap limb IK
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]);
731 //remap ADIK
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);
740 //adjust recoil
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);
750 //adjust look-ik
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;
781 break;
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;
804 if (pRotName == 0)
805 continue;
806 for (uint32 p = 0; p < numPosLook; p++)
808 const char* pPosName = m_poseBlenderLookDesc.m_positions[p].m_strJointName;
809 if (pPosName == 0)
810 continue;
811 uint32 SameJoint = strcmp(pRotName, pPosName) == 0;
812 if (SameJoint)
814 m_poseBlenderLookDesc.m_rotations[r].m_nPosIndex = p;
815 break;
820 //adjust aim-ik
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;
850 break;
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;
876 if (pRotName == 0)
877 continue;
878 for (uint32 p = 0; p < numPos; p++)
880 const char* pPosName = m_poseBlenderAimDesc.m_positions[p].m_strJointName;
881 if (pPosName == 0)
882 continue;
883 uint32 SameJoint = strcmp(pRotName, pPosName) == 0;
884 if (SameJoint)
886 m_poseBlenderAimDesc.m_rotations[r].m_nPosIndex = p;
887 break;
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() };
901 else
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();
916 if (m_pFacialModel)
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();
951 return nSize;
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
1011 uint32 nSize = 0;
1012 if (pSizer)
1014 if (m_ModelMesh.m_pIRenderMesh)
1015 nSize += (uint32)m_ModelMesh.m_pIRenderMesh->GetTextureMemoryUsage(m_ModelMesh.m_pIDefaultMaterial, pSizer);
1017 else
1019 if (m_ModelMesh.m_pIRenderMesh)
1020 nSize = (uint32)m_ModelMesh.m_pIRenderMesh->GetTextureMemoryUsage(m_ModelMesh.m_pIDefaultMaterial);
1022 return nSize;
1025 //////////////////////////////////////////////////////////////////////////
1026 uint32 CDefaultSkeleton::GetMeshMemoryUsage(ICrySizer* pSizer) const
1028 uint32 nSize = 0;
1029 if (m_ModelMesh.m_pIRenderMesh)
1031 nSize += m_ModelMesh.m_pIRenderMesh->GetMemoryUsage(0, IRenderMesh::MEM_USAGE_ONLY_STREAMS);
1033 return nSize;