SO3Engine
SO3Bone.cpp
Go to the documentation of this file.
1
12
13namespace SO3
14{
15
16 SBone::SBone(SScene* parent, const std::string& boneName, SSkeleton* skeleton, const unsigned short& id) : SNode(parent, boneName, SNode::BONE_TYPE_ID)
17 {
18 parentSkeleton = skeleton;
20 boneIndex = id;
21
22 //Do not get the Ogre::bone pointer here, it can change on resource reload
23
24 /* TODO Jeff: use BaseMeshUtils to generate a mesh corresponding to this bone, to show it with SNode SetVisible function.
25 // Create a visualization for debugging.
26 Ogre::Vector3 parentPosition;
27 Ogre::Bone* ogreParentBone = static_cast <Ogre::Bone*> (O3Bone->getParent());
28 if (ogreParentBone == 0)
29 {
30 parentPosition = Ogre::Vector3::ZERO;
31 // TODO: orientation (bone turned along is local y axis).
32 }
33 else
34 {
35 parentPosition = ogreParentBone->getPosition();
36 // TODO: orientation (bone turned along is local y axis).
37 }
38 float boneLength = parentPosition.distance(O3Bone->getPosition());
39
40 Ogre::Entity* boneHelperEntity = currentScene->GetOgreScenePointer()->createEntity(boneName, "SO3/Bone/Helper/Mesh", SO3_INTERNAL_RESOURCE_GROUP);
41 boneHelperEntity->setMaterialName("SO3/Bone/Helper/Material", SO3_INTERNAL_RESOURCE_GROUP);
42 Ogre::SceneNode* tempNode = currentScene->GetOgreScenePointer()->getRootSceneNode()->createChildSceneNode("test_"+boneName);
43
44 O3SceneNode->attachObject(boneHelperEntity);
45 O3SceneNode->setScale(Ogre::Vector3::UNIT_SCALE * boneLength);
46 O3SceneNode->setVisible(true, true);*/
47 }
48
49 SBone::SBone() : SNode(0, "", SNode::BONE_TYPE_ID)
50 {
51 // Forbiden (private)
52 }
53
55 {
56 // Be sure that skeleton will not have this instance in is list after the deletion.
59
62 }
63
65 {
68 }
69
71 {
73 return NULL;
74
76 }
77
82
83 void SBone::Rotate(const Ogre::Vector3& axis, const float& radianAngle, const SNode::NodeTransformSpace& relativeTo)
84 {
86 return;
87
88 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
89 O3Bone->setManuallyControlled(true);
90 O3Bone->rotate(axis, Ogre::Radian(radianAngle), static_cast <Ogre::Node::TransformSpace> (static_cast<int>(relativeTo)));
91 O3Bone->setInitialState();
92 O3Bone->setManuallyControlled(false);
93 //currentEntity->verticesNeedUpdate = true;
94 UpdateNodeBody(false);
95 }
96
97 void SBone::SetOrientation(const Ogre::Quaternion& quat)
98 {
100 return;
101
102 Ogre::Quaternion tempQuat(quat);
103 tempQuat.normalise();
104
105 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
106 O3Bone->setManuallyControlled(true);
107 O3Bone->setOrientation(tempQuat);
108 O3Bone->setInitialState();
109 O3Bone->setManuallyControlled(false);
110 UpdateNodeBody(false);
111 }
112
113 void SBone::AddOrientation(const Ogre::Quaternion& quat)
114 {
116 return;
117
118 Ogre::Quaternion tempQuat(quat);
119 tempQuat.normalise();
120
121 if (tempQuat != Ogre::Quaternion::ZERO)
122 SetOrientation(GetOrientation() * tempQuat);
123
124 UpdateNodeBody(false);
125 }
126
128 {
130 return;
131
132 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
133
134 O3Bone->setManuallyControlled(true);
135 O3Bone->resetOrientation();
136 O3Bone->setInitialState();
137 O3Bone->setManuallyControlled(false);
138 UpdateNodeBody(false);
139 }
140
141 void SBone::SetPosition(const Ogre::Vector3& pos)
142 {
144 return;
145
146 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
147
148 O3Bone->setManuallyControlled(true);
149 O3Bone->setPosition(pos);
150 O3Bone->setInitialState();
151 O3Bone->setManuallyControlled(false);
152 UpdateNodeBody(false);
153 }
154
155 void SBone::Translate(const Ogre::Vector3& d, const SNode::NodeTransformSpace& relativeTo)
156 {
158 return;
159
160 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
161
162 O3Bone->setManuallyControlled(true);
163 O3Bone->translate(d, static_cast <Ogre::Node::TransformSpace> (static_cast<int>(relativeTo)));
164 O3Bone->setInitialState();
165 O3Bone->setManuallyControlled(false);
166 UpdateNodeBody(false);
167 }
168
169 void SBone::SetScale(const Ogre::Vector3& scale)
170 {
172 return;
173
174 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
175
176 O3Bone->setManuallyControlled(true);
177 O3Bone->setScale(scale);
178 O3Bone->setInitialState();
179 O3Bone->setManuallyControlled(false);
180 UpdateNodeBody(false);
181 }
182
183 Ogre::Vector3 SBone::GetPosition()
184 {
186 return Ogre::Vector3::ZERO;
187
188 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
189 return O3Bone->getPosition();
190 }
191
192 Ogre::Quaternion SBone::GetOrientation()
193 {
195 return Ogre::Quaternion::IDENTITY;
196
197 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
198 return O3Bone->getOrientation();
199 }
200
201 Ogre::Vector3 SBone::GetScale()
202 {
204 return Ogre::Vector3::UNIT_SCALE;
205
206 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
207 return O3Bone->getScale();
208 }
209
211 {
213 return Ogre::Vector3::ZERO;
214
215 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
216 return O3Bone->getInitialPosition();
217 }
218
220 {
222 return Ogre::Quaternion::IDENTITY;
223
224 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
225 return O3Bone->getInitialOrientation();
226 }
227
229 {
231 return Ogre::Vector3::ZERO;
232
233 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
234 return O3Bone->getInitialScale();
235 }
236
237 //VERIFIED OK
239 {
241 return Ogre::Vector3::ZERO;
242
243 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
244 Ogre::SceneNode* parent = ogreLinkedEntity->getParentSceneNode();
245 parent->_update(false, true);
246 Ogre::Quaternion parentQuat = parent->_getDerivedOrientation();
247 Ogre::Vector3 parentPos = parent->_getDerivedPosition();
248 Ogre::Vector3 parentScale = parent->_getDerivedScale();
249 O3Bone->_update(false, true);
250 Ogre::Vector3 bonePos = O3Bone->_getDerivedPosition();
251
252 Ogre::Vector3 globalPosition = parentPos + (parentQuat * (bonePos * parentScale));
253 return globalPosition;
254 }
255
257 {
259 return Ogre::Quaternion::IDENTITY;
260
261 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
262 Ogre::SceneNode* parent = ogreLinkedEntity->getParentSceneNode();
263 parent->_update(false, true);
264 Ogre::Quaternion parentQuat = parent->_getDerivedOrientation();
265 O3Bone->_update(false, true);
266 Ogre::Quaternion boneQuat = O3Bone->_getDerivedOrientation();
267
268 Ogre::Quaternion globalOrientation = parentQuat * boneQuat;
269
270 //Ogre::Quaternion testLocQuat = globalOrientation * parentQuat.Inverse();
271
272 return globalOrientation;
273 }
274
275 Ogre::Vector3 SBone::GetGlobalScale()
276 {
278 return Ogre::Vector3::UNIT_SCALE;
279
280 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
281 Ogre::Matrix4 mat = ogreLinkedEntity->_getParentNodeFullTransform();
282 Ogre::Vector3 col1(mat[0][0], mat[1][0], mat[2][0]);
283 Ogre::Vector3 col2(mat[0][1], mat[1][1], mat[2][1]);
284 Ogre::Vector3 col3(mat[0][2], mat[1][2], mat[2][2]);
285
286 Ogre::Vector3 sc;
287 sc.x = col1.length();
288 sc.y = col2.length();
289 sc.z = col3.length();
290
291 return O3Bone->_getDerivedScale() * sc;
292 }
293
294 //VERIFIED OK
295 void SBone::SetGlobalPosition(const Ogre::Vector3& pos, bool updateBody)
296 {
298 return;
299
300 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
301 Ogre::SceneNode* parent = ogreLinkedEntity->getParentSceneNode();
302 parent->_update(false, true);
303 Ogre::Quaternion parentQuat = parent->_getDerivedOrientation();
304 Ogre::Vector3 parentPos = parent->_getDerivedPosition();
305 Ogre::Vector3 parentScale = parent->_getDerivedScale();
306
307 //to avoid division by 0
308 if (parentScale == Ogre::Vector3::ZERO)
309 parentScale = Ogre::Vector3(0.000001f, 0.000001f, 0.000001f);
310
311 Ogre::Vector3 globalPosition = parentQuat.Inverse() * ((pos - parentPos) * (1.0 / parentScale));
312
313 O3Bone->setManuallyControlled(true);
314
315 //Ogre bug do not verify that a parent is available
316 if (O3Bone->getParent() == 0)
317 O3Bone->setPosition(globalPosition);
318 else
319 O3Bone->_setDerivedPosition(globalPosition);
320
321 O3Bone->setInitialState();
322 O3Bone->setManuallyControlled(false);
323
324 if (updateBody)
325 UpdateNodeBody(false);
326 }
327
328 void SBone::SetGlobalOrientation(const Ogre::Quaternion& quat, bool updateBody)
329 {
331 return;
332
333 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
334 Ogre::SceneNode* parent = ogreLinkedEntity->getParentSceneNode();
335 parent->_update(false, true);
336 Ogre::Quaternion parentQuat = parent->_getDerivedOrientation();
337
338 Ogre::Quaternion globalOrientation = parentQuat.Inverse() * quat;
339
340 O3Bone->setManuallyControlled(true);
341
342 //Ogre bug do not verify that a parent is available
343 if (O3Bone->getParent() == 0)
344 O3Bone->setOrientation(globalOrientation);
345 else
346 O3Bone->_setDerivedOrientation(globalOrientation);
347
348 O3Bone->setInitialState();
349 O3Bone->setManuallyControlled(false);
350
351 if (updateBody)
352 UpdateNodeBody(false);
353 }
354
355 void SBone::SetGlobalScale(const Ogre::Vector3& scale, bool updateBody)
356 {
358 return;
359
360 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
361 Ogre::SceneNode* parent = ogreLinkedEntity->getParentSceneNode();
362 parent->_update(false, true);
363
364 O3Bone->setManuallyControlled(true);
365 if (O3Bone->getParent() == 0)
366 O3Bone->setScale(scale / parent->_getDerivedScale());
367 else
368 O3Bone->setScale(scale / parent->_getDerivedScale() / O3Bone->getParent()->_getDerivedScale());
369
370 O3Bone->setInitialState();
371 O3Bone->setManuallyControlled(false);
372
373 if (updateBody)
374 UpdateNodeBody(false);
375 }
376
378 {
380 return Ogre::Matrix4::IDENTITY;
381
382 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
383 return O3Bone->_getFullTransform();
384 }
385
386 void SBone::Pitch(const float& radianAngle, const SNode::NodeTransformSpace& relativeTo)
387 {
389 return;
390
391 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
392 O3Bone->setManuallyControlled(true);
393 O3Bone->pitch(Ogre::Radian(radianAngle), static_cast <Ogre::Node::TransformSpace> (static_cast<int>(relativeTo)));
394 O3Bone->setInitialState();
395 O3Bone->setManuallyControlled(false);
396 UpdateNodeBody(false);
397 }
398
399 void SBone::Yaw(const float& radianAngle, const SNode::NodeTransformSpace& relativeTo)
400 {
402 return;
403
404 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
405 O3Bone->setManuallyControlled(true);
406 O3Bone->yaw(Ogre::Radian(radianAngle), static_cast <Ogre::Node::TransformSpace> (static_cast<int>(relativeTo)));
407 O3Bone->setInitialState();
408 O3Bone->setManuallyControlled(false);
409 UpdateNodeBody(false);
410 }
411
412 void SBone::Roll(const float& radianAngle, const SNode::NodeTransformSpace& relativeTo)
413 {
415 return;
416
417 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
418 O3Bone->setManuallyControlled(true);
419 O3Bone->roll(Ogre::Radian(radianAngle), static_cast <Ogre::Node::TransformSpace> (static_cast<int>(relativeTo)));
420 O3Bone->setInitialState();
421 O3Bone->setManuallyControlled(false);
422 UpdateNodeBody(false);
423 }
424
426 {
428 return 0;
429
430 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
431 return O3Bone->numChildren();
432 }
433
435 {
437 return;
438
439 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
440 O3Bone->setManuallyControlled(true);
441 O3Bone->setInitialState();
442 O3Bone->setManuallyControlled(false);
443
444 initialPosition = O3Bone->_getDerivedPosition();
445 initialOrientation = O3Bone->_getDerivedOrientation();
447 }
448
450 {
452 return;
453
454 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
455
456 O3Bone->setManuallyControlled(true);
457 //O3Bone->resetToInitialState();
458
459 if (O3Bone->getParent())
460 {
461 O3Bone->_setDerivedPosition(initialPosition);
462 O3Bone->_setDerivedOrientation(initialOrientation);
463 }
464 else
465 {
466 O3Bone->setPosition(initialPosition);
467 O3Bone->setOrientation(initialOrientation);
468 }
469 O3Bone->setInitialState();
470 O3Bone->setManuallyControlled(false);
472 }
473
474 unsigned short SBone::GetIndex()
475 {
476 return boneIndex;
477 }
478
480 {
482 return;
483
484 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
485 Ogre::MovableObject* ogreObject = newChild->GetMovableObjectPointer();
486 if (ogreObject != 0)
487 {
488 // Detach from previous parent
489 // If our ogre is anterior to v1.7
490#if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
491 ogreObject->detatchFromParent();
492#else
493 ogreObject->detachFromParent();
494#endif
495
496 // Re-attach to bone.
497 ogreLinkedEntity->attachObjectToBone(O3Bone->getName(), ogreObject, O3SceneNode->getOrientation(), O3SceneNode->getPosition());
498 }
499 }
500
501 void SBone::DetachFromBone(SNode* existingChild)
502 {
504 return;
505
506 Ogre::MovableObject* ogreObject = existingChild->GetMovableObjectPointer();
507
508 if (ogreObject != 0)
509 {
510 bool isBoneAttached = false;
511
512 // If our ogre is anterior to v1.7
513#if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
514 if (ogreObject->isAttached())
515 {
516 Ogre::Node* np = ogreObject->getParentNode();
517 Ogre::SceneNode* snp = ogreObject->getParentSceneNode();
518
519 if (snp != np) // attached to TagPoint
520 isBoneAttached = true;
521 }
522#else
523 isBoneAttached = ogreObject->isParentTagPoint();
524#endif
525
526 // Check if the entity is really attached to the bone.
527 if (isBoneAttached)
528 {
529 // Detach from bone.
530 ogreLinkedEntity->detachObjectFromBone(ogreObject);
531
532 // Re-attach to the original SNode's ogre scene node
533 existingChild->GetOgreSceneNodePointer()->attachObject(ogreObject);
534 }
535 }
536 }
537
538 void SBone::AttachToBone(Ogre::MovableObject* ogreObject)
539 {
540 if (!ogreLinkedEntity || !parentSkeleton || !ogreObject)
541 return;
542
543 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
544 ogreObject->detachFromParent();
545
546 // Re-attach to bone.
547 ogreLinkedEntity->attachObjectToBone(O3Bone->getName(), ogreObject, Ogre::Quaternion::IDENTITY, Ogre::Vector3::ZERO);
548 }
549
550 void SBone::DetachFromBone(Ogre::MovableObject* ogreObject)
551 {
552 if (!ogreLinkedEntity || !parentSkeleton || !ogreObject)
553 return;
554
555 ogreLinkedEntity->detachObjectFromBone(ogreObject);
556 }
557
558 Ogre::Quaternion SBone::ConvertWorldToLocalOrientation(const Ogre::Quaternion& quat)
559 {
561 return Ogre::Quaternion::IDENTITY;
562
563 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
564 return O3Bone->convertWorldToLocalOrientation(quat);
565 }
566
567 void SBone::SetInheritOrientation(const bool& state)
568 {
570 return;
571
572 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
573 O3Bone->setInheritOrientation(state);
574 }
575
577 {
579 return false;
580
581 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
582 return O3Bone->getInheritOrientation();
583 }
584
586 {
588 return;
589
590 Ogre::Bone* O3Bone = parentSkeleton->GetOgreSkeletonPointer()->getBone(boneIndex);
591 O3Bone->resetOrientation();
592 }
593
594}
virtual void SetOrientation(const Ogre::Quaternion &quat)
Definition SO3Bone.cpp:97
void UnsetSkeleton()
Definition SO3Bone.cpp:64
Ogre::Bone * GetOgreBonePointer()
Definition SO3Bone.cpp:70
unsigned short GetIndex()
Definition SO3Bone.cpp:474
virtual void Pitch(const float &radianAngle, const SNode::NodeTransformSpace &relativeTo=SNode::SO3_LOCAL_TS)
Definition SO3Bone.cpp:386
virtual void SetPosition(const Ogre::Vector3 &pos)
Definition SO3Bone.cpp:141
SSkeleton * GetSkeleton()
Definition SO3Bone.cpp:78
virtual Ogre::Quaternion GetInitialOrientation()
Definition SO3Bone.cpp:219
virtual void SetGlobalPosition(const Ogre::Vector3 &pos, bool updateBody=true)
Definition SO3Bone.cpp:295
virtual void Rotate(const Ogre::Vector3 &axis, const float &radianAngle, const SNode::NodeTransformSpace &relativeTo=SNode::SO3_LOCAL_TS)
Definition SO3Bone.cpp:83
virtual bool GetInheritOrientation()
Definition SO3Bone.cpp:576
unsigned short boneIndex
Definition SO3Bone.h:48
virtual Ogre::Vector3 GetPosition()
Definition SO3Bone.cpp:183
void AttachToBone(Ogre::MovableObject *ogreObject)
Definition SO3Bone.cpp:538
virtual void ResetToInitialOrientation()
Definition SO3Bone.cpp:127
virtual void Roll(const float &radianAngle, const SNode::NodeTransformSpace &relativeTo=SNode::SO3_LOCAL_TS)
Definition SO3Bone.cpp:412
virtual void Translate(const Ogre::Vector3 &d, const SNode::NodeTransformSpace &relativeTo=SNode::SO3_PARENT_TS)
Definition SO3Bone.cpp:155
virtual Ogre::Vector3 GetInitialPosition()
Definition SO3Bone.cpp:210
void DetachFromBone(Ogre::MovableObject *ogreObject)
Definition SO3Bone.cpp:550
virtual void SetGlobalOrientation(const Ogre::Quaternion &quat, bool updateBody=true)
Definition SO3Bone.cpp:328
virtual void AddOrientation(const Ogre::Quaternion &quat)
Definition SO3Bone.cpp:113
virtual void Yaw(const float &radianAngle, const SNode::NodeTransformSpace &relativeTo=SNode::SO3_LOCAL_TS)
Definition SO3Bone.cpp:399
virtual void SetScale(const Ogre::Vector3 &scale)
Definition SO3Bone.cpp:169
virtual void ResetOrientation()
Definition SO3Bone.cpp:585
virtual Ogre::Vector3 GetScale()
Definition SO3Bone.cpp:201
virtual Ogre::Quaternion GetGlobalOrientation()
Definition SO3Bone.cpp:256
virtual void SetInheritOrientation(const bool &state)
Definition SO3Bone.cpp:567
virtual Ogre::Matrix4 GetTransformationMatrix()
Definition SO3Bone.cpp:377
Ogre::Entity * ogreLinkedEntity
Definition SO3Bone.h:47
virtual int GetNumChildren()
Definition SO3Bone.cpp:425
SSkeleton * parentSkeleton
Definition SO3Bone.h:46
virtual Ogre::Vector3 GetGlobalPosition()
Definition SO3Bone.cpp:238
Ogre::Quaternion ConvertWorldToLocalOrientation(const Ogre::Quaternion &quat)
Definition SO3Bone.cpp:558
virtual void SetGlobalScale(const Ogre::Vector3 &pos, bool updateBody=true)
Definition SO3Bone.cpp:355
virtual void ResetToInitialPRS()
Definition SO3Bone.cpp:449
virtual Ogre::Quaternion GetOrientation()
Definition SO3Bone.cpp:192
virtual Ogre::Vector3 GetGlobalScale()
Definition SO3Bone.cpp:275
virtual void StoreInitialPRS()
Definition SO3Bone.cpp:434
virtual Ogre::Vector3 GetInitialScale()
Definition SO3Bone.cpp:228
Ogre::Entity * getOgreEntityPointer()
void UpdateNodeBody(const bool &bScale)
Ogre::SceneNode * O3SceneNode
Definition SO3NodeScol.h:69
Ogre::Vector3 initialPosition
Definition SO3NodeScol.h:75
Ogre::MovableObject * GetMovableObjectPointer()
Ogre::Quaternion initialOrientation
Definition SO3NodeScol.h:76
Ogre::Vector3 initialScale
Definition SO3NodeScol.h:77
Ogre::SceneNode * GetOgreSceneNodePointer()
Ogre::SkeletonInstance * GetOgreSkeletonPointer()
SEntity * GetParentEntity()
void _OnBoneDeletion(SBone *boneInstance)