PageRenderTime 30ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/Core/Dependencies/OgreSource/OgreMain/src/OgreSkeleton.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 1029 lines | 746 code | 108 blank | 175 comment | 126 complexity | 9b57fa01c5dfbcd459758415fe66d060 MD5 | raw file
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2012 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreStableHeaders.h"
  25. #include "OgreSkeleton.h"
  26. #include "OgreBone.h"
  27. #include "OgreAnimationState.h"
  28. #include "OgreException.h"
  29. #include "OgreLogManager.h"
  30. #include "OgreSkeletonManager.h"
  31. #include "OgreSkeletonSerializer.h"
  32. #include "OgreStringConverter.h"
  33. // Just for logging
  34. #include "OgreAnimationTrack.h"
  35. #include "OgreKeyFrame.h"
  36. namespace Ogre {
  37. //---------------------------------------------------------------------
  38. Skeleton::Skeleton()
  39. : Resource(),
  40. mBlendState(ANIMBLEND_AVERAGE),
  41. mNextAutoHandle(0),
  42. mManualBonesDirty(false)
  43. {
  44. }
  45. //---------------------------------------------------------------------
  46. Skeleton::Skeleton(ResourceManager* creator, const String& name, ResourceHandle handle,
  47. const String& group, bool isManual, ManualResourceLoader* loader)
  48. : Resource(creator, name, handle, group, isManual, loader),
  49. mBlendState(ANIMBLEND_AVERAGE), mNextAutoHandle(0)
  50. // set animation blending to weighted, not cumulative
  51. {
  52. if (createParamDictionary("Skeleton"))
  53. {
  54. // no custom params
  55. }
  56. }
  57. //---------------------------------------------------------------------
  58. Skeleton::~Skeleton()
  59. {
  60. // have to call this here reather than in Resource destructor
  61. // since calling virtual methods in base destructors causes crash
  62. unload();
  63. }
  64. //---------------------------------------------------------------------
  65. void Skeleton::loadImpl(void)
  66. {
  67. SkeletonSerializer serializer;
  68. LogManager::getSingleton().stream()
  69. << "Skeleton: Loading " << mName;
  70. DataStreamPtr stream =
  71. ResourceGroupManager::getSingleton().openResource(
  72. mName, mGroup, true, this);
  73. serializer.importSkeleton(stream, this);
  74. // Load any linked skeletons
  75. LinkedSkeletonAnimSourceList::iterator i;
  76. for (i = mLinkedSkeletonAnimSourceList.begin();
  77. i != mLinkedSkeletonAnimSourceList.end(); ++i)
  78. {
  79. i->pSkeleton = SkeletonManager::getSingleton().load(
  80. i->skeletonName, mGroup);
  81. }
  82. }
  83. //---------------------------------------------------------------------
  84. void Skeleton::unloadImpl(void)
  85. {
  86. // destroy bones
  87. BoneList::iterator i;
  88. for (i = mBoneList.begin(); i != mBoneList.end(); ++i)
  89. {
  90. OGRE_DELETE *i;
  91. }
  92. mBoneList.clear();
  93. mBoneListByName.clear();
  94. mRootBones.clear();
  95. mManualBones.clear();
  96. mManualBonesDirty = false;
  97. // Destroy animations
  98. AnimationList::iterator ai;
  99. for (ai = mAnimationsList.begin(); ai != mAnimationsList.end(); ++ai)
  100. {
  101. OGRE_DELETE ai->second;
  102. }
  103. mAnimationsList.clear();
  104. // Remove all linked skeletons
  105. mLinkedSkeletonAnimSourceList.clear();
  106. }
  107. //---------------------------------------------------------------------
  108. Bone* Skeleton::createBone(void)
  109. {
  110. // use autohandle
  111. return createBone(mNextAutoHandle++);
  112. }
  113. //---------------------------------------------------------------------
  114. Bone* Skeleton::createBone(const String& name)
  115. {
  116. return createBone(name, mNextAutoHandle++);
  117. }
  118. //---------------------------------------------------------------------
  119. Bone* Skeleton::createBone(unsigned short handle)
  120. {
  121. if (handle >= OGRE_MAX_NUM_BONES)
  122. {
  123. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Exceeded the maximum number of bones per skeleton.",
  124. "Skeleton::createBone");
  125. }
  126. // Check handle not used
  127. if (handle < mBoneList.size() && mBoneList[handle] != NULL)
  128. {
  129. OGRE_EXCEPT(
  130. Exception::ERR_DUPLICATE_ITEM,
  131. "A bone with the handle " + StringConverter::toString(handle) + " already exists",
  132. "Skeleton::createBone" );
  133. }
  134. Bone* ret = OGRE_NEW Bone(handle, this);
  135. assert(mBoneListByName.find(ret->getName()) == mBoneListByName.end());
  136. if (mBoneList.size() <= handle)
  137. {
  138. mBoneList.resize(handle+1);
  139. }
  140. mBoneList[handle] = ret;
  141. mBoneListByName[ret->getName()] = ret;
  142. return ret;
  143. }
  144. //---------------------------------------------------------------------
  145. Bone* Skeleton::createBone(const String& name, unsigned short handle)
  146. {
  147. if (handle >= OGRE_MAX_NUM_BONES)
  148. {
  149. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Exceeded the maximum number of bones per skeleton.",
  150. "Skeleton::createBone");
  151. }
  152. // Check handle not used
  153. if (handle < mBoneList.size() && mBoneList[handle] != NULL)
  154. {
  155. OGRE_EXCEPT(
  156. Exception::ERR_DUPLICATE_ITEM,
  157. "A bone with the handle " + StringConverter::toString(handle) + " already exists",
  158. "Skeleton::createBone" );
  159. }
  160. // Check name not used
  161. if (mBoneListByName.find(name) != mBoneListByName.end())
  162. {
  163. OGRE_EXCEPT(
  164. Exception::ERR_DUPLICATE_ITEM,
  165. "A bone with the name " + name + " already exists",
  166. "Skeleton::createBone" );
  167. }
  168. Bone* ret = OGRE_NEW Bone(name, handle, this);
  169. if (mBoneList.size() <= handle)
  170. {
  171. mBoneList.resize(handle+1);
  172. }
  173. mBoneList[handle] = ret;
  174. mBoneListByName[name] = ret;
  175. return ret;
  176. }
  177. //---------------------------------------------------------------------
  178. Bone* Skeleton::getRootBone(void) const
  179. {
  180. if (mRootBones.empty())
  181. {
  182. deriveRootBone();
  183. }
  184. return mRootBones[0];
  185. }
  186. //---------------------------------------------------------------------
  187. void Skeleton::setAnimationState(const AnimationStateSet& animSet)
  188. {
  189. /*
  190. Algorithm:
  191. 1. Reset all bone positions
  192. 2. Iterate per AnimationState, if enabled get Animation and call Animation::apply
  193. */
  194. // Reset bones
  195. reset();
  196. Real weightFactor = 1.0f;
  197. if (mBlendState == ANIMBLEND_AVERAGE)
  198. {
  199. // Derive total weights so we can rebalance if > 1.0f
  200. Real totalWeights = 0.0f;
  201. ConstEnabledAnimationStateIterator stateIt =
  202. animSet.getEnabledAnimationStateIterator();
  203. while (stateIt.hasMoreElements())
  204. {
  205. const AnimationState* animState = stateIt.getNext();
  206. // Make sure we have an anim to match implementation
  207. const LinkedSkeletonAnimationSource* linked = 0;
  208. if (_getAnimationImpl(animState->getAnimationName(), &linked))
  209. {
  210. totalWeights += animState->getWeight();
  211. }
  212. }
  213. // Allow < 1.0f, allows fade out of all anims if required
  214. if (totalWeights > 1.0f)
  215. {
  216. weightFactor = 1.0f / totalWeights;
  217. }
  218. }
  219. // Per enabled animation state
  220. ConstEnabledAnimationStateIterator stateIt =
  221. animSet.getEnabledAnimationStateIterator();
  222. while (stateIt.hasMoreElements())
  223. {
  224. const AnimationState* animState = stateIt.getNext();
  225. const LinkedSkeletonAnimationSource* linked = 0;
  226. Animation* anim = _getAnimationImpl(animState->getAnimationName(), &linked);
  227. // tolerate state entries for animations we're not aware of
  228. if (anim)
  229. {
  230. if(animState->hasBlendMask())
  231. {
  232. anim->apply(this, animState->getTimePosition(), animState->getWeight() * weightFactor,
  233. animState->getBlendMask(), linked ? linked->scale : 1.0f);
  234. }
  235. else
  236. {
  237. anim->apply(this, animState->getTimePosition(),
  238. animState->getWeight() * weightFactor, linked ? linked->scale : 1.0f);
  239. }
  240. }
  241. }
  242. }
  243. //---------------------------------------------------------------------
  244. void Skeleton::setBindingPose(void)
  245. {
  246. // Update the derived transforms
  247. _updateTransforms();
  248. BoneList::iterator i;
  249. for (i = mBoneList.begin(); i != mBoneList.end(); ++i)
  250. {
  251. (*i)->setBindingPose();
  252. }
  253. }
  254. //---------------------------------------------------------------------
  255. void Skeleton::reset(bool resetManualBones)
  256. {
  257. BoneList::iterator i;
  258. for (i = mBoneList.begin(); i != mBoneList.end(); ++i)
  259. {
  260. if(!(*i)->isManuallyControlled() || resetManualBones)
  261. (*i)->reset();
  262. }
  263. }
  264. //---------------------------------------------------------------------
  265. Animation* Skeleton::createAnimation(const String& name, Real length)
  266. {
  267. // Check name not used
  268. if (mAnimationsList.find(name) != mAnimationsList.end())
  269. {
  270. OGRE_EXCEPT(
  271. Exception::ERR_DUPLICATE_ITEM,
  272. "An animation with the name " + name + " already exists",
  273. "Skeleton::createAnimation");
  274. }
  275. Animation* ret = OGRE_NEW Animation(name, length);
  276. ret->_notifyContainer(this);
  277. // Add to list
  278. mAnimationsList[name] = ret;
  279. return ret;
  280. }
  281. //---------------------------------------------------------------------
  282. Animation* Skeleton::getAnimation(const String& name,
  283. const LinkedSkeletonAnimationSource** linker) const
  284. {
  285. Animation* ret = _getAnimationImpl(name, linker);
  286. if (!ret)
  287. {
  288. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name,
  289. "Skeleton::getAnimation");
  290. }
  291. return ret;
  292. }
  293. //---------------------------------------------------------------------
  294. Animation* Skeleton::getAnimation(const String& name) const
  295. {
  296. return getAnimation(name, 0);
  297. }
  298. //---------------------------------------------------------------------
  299. bool Skeleton::hasAnimation(const String& name) const
  300. {
  301. return _getAnimationImpl(name) != 0;
  302. }
  303. //---------------------------------------------------------------------
  304. Animation* Skeleton::_getAnimationImpl(const String& name,
  305. const LinkedSkeletonAnimationSource** linker) const
  306. {
  307. Animation* ret = 0;
  308. AnimationList::const_iterator i = mAnimationsList.find(name);
  309. if (i == mAnimationsList.end())
  310. {
  311. LinkedSkeletonAnimSourceList::const_iterator it;
  312. for (it = mLinkedSkeletonAnimSourceList.begin();
  313. it != mLinkedSkeletonAnimSourceList.end() && !ret; ++it)
  314. {
  315. if (!it->pSkeleton.isNull())
  316. {
  317. ret = it->pSkeleton->_getAnimationImpl(name);
  318. if (ret && linker)
  319. {
  320. *linker = &(*it);
  321. }
  322. }
  323. }
  324. }
  325. else
  326. {
  327. if (linker)
  328. *linker = 0;
  329. ret = i->second;
  330. }
  331. return ret;
  332. }
  333. //---------------------------------------------------------------------
  334. void Skeleton::removeAnimation(const String& name)
  335. {
  336. AnimationList::iterator i = mAnimationsList.find(name);
  337. if (i == mAnimationsList.end())
  338. {
  339. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name,
  340. "Skeleton::getAnimation");
  341. }
  342. OGRE_DELETE i->second;
  343. mAnimationsList.erase(i);
  344. }
  345. //-----------------------------------------------------------------------
  346. void Skeleton::_initAnimationState(AnimationStateSet* animSet)
  347. {
  348. animSet->removeAllAnimationStates();
  349. AnimationList::iterator i;
  350. for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i)
  351. {
  352. Animation* anim = i->second;
  353. // Create animation at time index 0, default params mean this has weight 1 and is disabled
  354. const String& animName = anim->getName();
  355. animSet->createAnimationState(animName, 0.0, anim->getLength());
  356. }
  357. // Also iterate over linked animation
  358. LinkedSkeletonAnimSourceList::iterator li;
  359. for (li = mLinkedSkeletonAnimSourceList.begin();
  360. li != mLinkedSkeletonAnimSourceList.end(); ++li)
  361. {
  362. if (!li->pSkeleton.isNull())
  363. {
  364. li->pSkeleton->_refreshAnimationState(animSet);
  365. }
  366. }
  367. }
  368. //-----------------------------------------------------------------------
  369. void Skeleton::_refreshAnimationState(AnimationStateSet* animSet)
  370. {
  371. // Merge in any new animations
  372. AnimationList::iterator i;
  373. for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i)
  374. {
  375. Animation* anim = i->second;
  376. // Create animation at time index 0, default params mean this has weight 1 and is disabled
  377. const String& animName = anim->getName();
  378. if (!animSet->hasAnimationState(animName))
  379. {
  380. animSet->createAnimationState(animName, 0.0, anim->getLength());
  381. }
  382. else
  383. {
  384. // Update length incase changed
  385. AnimationState* animState = animSet->getAnimationState(animName);
  386. animState->setLength(anim->getLength());
  387. animState->setTimePosition(std::min(anim->getLength(), animState->getTimePosition()));
  388. }
  389. }
  390. // Also iterate over linked animation
  391. LinkedSkeletonAnimSourceList::iterator li;
  392. for (li = mLinkedSkeletonAnimSourceList.begin();
  393. li != mLinkedSkeletonAnimSourceList.end(); ++li)
  394. {
  395. if (!li->pSkeleton.isNull())
  396. {
  397. li->pSkeleton->_refreshAnimationState(animSet);
  398. }
  399. }
  400. }
  401. //-----------------------------------------------------------------------
  402. void Skeleton::_notifyManualBonesDirty(void)
  403. {
  404. mManualBonesDirty = true;
  405. }
  406. //-----------------------------------------------------------------------
  407. void Skeleton::_notifyManualBoneStateChange(Bone* bone)
  408. {
  409. if (bone->isManuallyControlled())
  410. mManualBones.insert(bone);
  411. else
  412. mManualBones.erase(bone);
  413. }
  414. //-----------------------------------------------------------------------
  415. unsigned short Skeleton::getNumBones(void) const
  416. {
  417. return (unsigned short)mBoneList.size();
  418. }
  419. //-----------------------------------------------------------------------
  420. void Skeleton::_getBoneMatrices(Matrix4* pMatrices)
  421. {
  422. // Update derived transforms
  423. _updateTransforms();
  424. /*
  425. Calculating the bone matrices
  426. -----------------------------
  427. Now that we have the derived scaling factors, orientations & positions in the
  428. Bone nodes, we have to compute the Matrix4 to apply to the vertices of a mesh.
  429. Because any modification of a vertex has to be relative to the bone, we must
  430. first reverse transform by the Bone's original derived position/orientation/scale,
  431. then transform by the new derived position/orientation/scale.
  432. Also note we combine scale as equivalent axes, no shearing.
  433. */
  434. BoneList::const_iterator i, boneend;
  435. boneend = mBoneList.end();
  436. for (i = mBoneList.begin();i != boneend; ++i)
  437. {
  438. Bone* pBone = *i;
  439. pBone->_getOffsetTransform(*pMatrices);
  440. pMatrices++;
  441. }
  442. }
  443. //---------------------------------------------------------------------
  444. unsigned short Skeleton::getNumAnimations(void) const
  445. {
  446. return (unsigned short)mAnimationsList.size();
  447. }
  448. //---------------------------------------------------------------------
  449. Animation* Skeleton::getAnimation(unsigned short index) const
  450. {
  451. // If you hit this assert, then the index is out of bounds.
  452. assert( index < mAnimationsList.size() );
  453. AnimationList::const_iterator i = mAnimationsList.begin();
  454. std::advance(i, index);
  455. return i->second;
  456. }
  457. //---------------------------------------------------------------------
  458. Bone* Skeleton::getBone(unsigned short handle) const
  459. {
  460. assert(handle < mBoneList.size() && "Index out of bounds");
  461. return mBoneList[handle];
  462. }
  463. //---------------------------------------------------------------------
  464. Bone* Skeleton::getBone(const String& name) const
  465. {
  466. BoneListByName::const_iterator i = mBoneListByName.find(name);
  467. if (i == mBoneListByName.end())
  468. {
  469. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Bone named '" + name + "' not found.",
  470. "Skeleton::getBone");
  471. }
  472. return i->second;
  473. }
  474. //---------------------------------------------------------------------
  475. bool Skeleton::hasBone(const String& name) const
  476. {
  477. return mBoneListByName.find(name) != mBoneListByName.end();
  478. }
  479. //---------------------------------------------------------------------
  480. void Skeleton::deriveRootBone(void) const
  481. {
  482. // Start at the first bone and work up
  483. if (mBoneList.empty())
  484. {
  485. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot derive root bone as this "
  486. "skeleton has no bones!", "Skeleton::deriveRootBone");
  487. }
  488. mRootBones.clear();
  489. Bone* currentBone;
  490. BoneList::const_iterator i;
  491. BoneList::const_iterator iend = mBoneList.end();
  492. for (i = mBoneList.begin(); i != iend; ++i)
  493. {
  494. currentBone = *i;
  495. if (currentBone->getParent() == 0)
  496. {
  497. // This is a root
  498. mRootBones.push_back(currentBone);
  499. }
  500. }
  501. }
  502. //---------------------------------------------------------------------
  503. void Skeleton::_dumpContents(const String& filename)
  504. {
  505. std::ofstream of;
  506. Quaternion q;
  507. Radian angle;
  508. Vector3 axis;
  509. of.open(filename.c_str());
  510. of << "-= Debug output of skeleton " << mName << " =-" << std::endl << std::endl;
  511. of << "== Bones ==" << std::endl;
  512. of << "Number of bones: " << (unsigned int)mBoneList.size() << std::endl;
  513. BoneList::iterator bi;
  514. for (bi = mBoneList.begin(); bi != mBoneList.end(); ++bi)
  515. {
  516. Bone* bone = *bi;
  517. of << "-- Bone " << bone->getHandle() << " --" << std::endl;
  518. of << "Position: " << bone->getPosition();
  519. q = bone->getOrientation();
  520. of << "Rotation: " << q;
  521. q.ToAngleAxis(angle, axis);
  522. of << " = " << angle.valueRadians() << " radians around axis " << axis << std::endl << std::endl;
  523. }
  524. of << "== Animations ==" << std::endl;
  525. of << "Number of animations: " << (unsigned int)mAnimationsList.size() << std::endl;
  526. AnimationList::iterator ai;
  527. for (ai = mAnimationsList.begin(); ai != mAnimationsList.end(); ++ai)
  528. {
  529. Animation* anim = ai->second;
  530. of << "-- Animation '" << anim->getName() << "' (length " << anim->getLength() << ") --" << std::endl;
  531. of << "Number of tracks: " << anim->getNumNodeTracks() << std::endl;
  532. for (unsigned short ti = 0; ti < anim->getNumNodeTracks(); ++ti)
  533. {
  534. NodeAnimationTrack* track = anim->getNodeTrack(ti);
  535. of << " -- AnimationTrack " << ti << " --" << std::endl;
  536. of << " Affects bone: " << ((Bone*)track->getAssociatedNode())->getHandle() << std::endl;
  537. of << " Number of keyframes: " << track->getNumKeyFrames() << std::endl;
  538. for (unsigned short ki = 0; ki < track->getNumKeyFrames(); ++ki)
  539. {
  540. TransformKeyFrame* key = track->getNodeKeyFrame(ki);
  541. of << " -- KeyFrame " << ki << " --" << std::endl;
  542. of << " Time index: " << key->getTime();
  543. of << " Translation: " << key->getTranslate() << std::endl;
  544. q = key->getRotation();
  545. of << " Rotation: " << q;
  546. q.ToAngleAxis(angle, axis);
  547. of << " = " << angle.valueRadians() << " radians around axis " << axis << std::endl;
  548. }
  549. }
  550. }
  551. }
  552. //---------------------------------------------------------------------
  553. SkeletonAnimationBlendMode Skeleton::getBlendMode() const
  554. {
  555. return mBlendState;
  556. }
  557. //---------------------------------------------------------------------
  558. void Skeleton::setBlendMode(SkeletonAnimationBlendMode state)
  559. {
  560. mBlendState = state;
  561. }
  562. //---------------------------------------------------------------------
  563. Skeleton::BoneIterator Skeleton::getRootBoneIterator(void)
  564. {
  565. if (mRootBones.empty())
  566. {
  567. deriveRootBone();
  568. }
  569. return BoneIterator(mRootBones.begin(), mRootBones.end());
  570. }
  571. //---------------------------------------------------------------------
  572. Skeleton::BoneIterator Skeleton::getBoneIterator(void)
  573. {
  574. return BoneIterator(mBoneList.begin(), mBoneList.end());
  575. }
  576. //---------------------------------------------------------------------
  577. void Skeleton::_updateTransforms(void)
  578. {
  579. BoneList::iterator i, iend;
  580. iend = mRootBones.end();
  581. for (i = mRootBones.begin(); i != iend; ++i)
  582. {
  583. (*i)->_update(true, false);
  584. }
  585. mManualBonesDirty = false;
  586. }
  587. //---------------------------------------------------------------------
  588. void Skeleton::optimiseAllAnimations(bool preservingIdentityNodeTracks)
  589. {
  590. AnimationList::iterator ai, aiend;
  591. aiend = mAnimationsList.end();
  592. if (!preservingIdentityNodeTracks)
  593. {
  594. Animation::TrackHandleList tracksToDestroy;
  595. // Assume all node tracks are identity
  596. ushort numBones = getNumBones();
  597. for (ushort h = 0; h < numBones; ++h)
  598. {
  599. tracksToDestroy.insert(h);
  600. }
  601. // Collect identity node tracks for all animations
  602. for (ai = mAnimationsList.begin(); ai != aiend; ++ai)
  603. {
  604. ai->second->_collectIdentityNodeTracks(tracksToDestroy);
  605. }
  606. // Destroy identity node tracks
  607. for (ai = mAnimationsList.begin(); ai != aiend; ++ai)
  608. {
  609. ai->second->_destroyNodeTracks(tracksToDestroy);
  610. }
  611. }
  612. for (ai = mAnimationsList.begin(); ai != aiend; ++ai)
  613. {
  614. // Don't discard identity node tracks here
  615. ai->second->optimise(false);
  616. }
  617. }
  618. //---------------------------------------------------------------------
  619. void Skeleton::addLinkedSkeletonAnimationSource(const String& skelName,
  620. Real scale)
  621. {
  622. // Check not already linked
  623. LinkedSkeletonAnimSourceList::iterator i;
  624. for (i = mLinkedSkeletonAnimSourceList.begin();
  625. i != mLinkedSkeletonAnimSourceList.end(); ++i)
  626. {
  627. if (skelName == i->skeletonName)
  628. return; // don't bother
  629. }
  630. if (isLoaded())
  631. {
  632. // Load immediately
  633. SkeletonPtr skelPtr =
  634. SkeletonManager::getSingleton().load(skelName, mGroup);
  635. mLinkedSkeletonAnimSourceList.push_back(
  636. LinkedSkeletonAnimationSource(skelName, scale, skelPtr));
  637. }
  638. else
  639. {
  640. // Load later
  641. mLinkedSkeletonAnimSourceList.push_back(
  642. LinkedSkeletonAnimationSource(skelName, scale));
  643. }
  644. }
  645. //---------------------------------------------------------------------
  646. void Skeleton::removeAllLinkedSkeletonAnimationSources(void)
  647. {
  648. mLinkedSkeletonAnimSourceList.clear();
  649. }
  650. //---------------------------------------------------------------------
  651. Skeleton::LinkedSkeletonAnimSourceIterator
  652. Skeleton::getLinkedSkeletonAnimationSourceIterator(void) const
  653. {
  654. return LinkedSkeletonAnimSourceIterator(
  655. mLinkedSkeletonAnimSourceList.begin(),
  656. mLinkedSkeletonAnimSourceList.end());
  657. }
  658. //---------------------------------------------------------------------
  659. struct DeltaTransform
  660. {
  661. Vector3 translate;
  662. Quaternion rotate;
  663. Vector3 scale;
  664. bool isIdentity;
  665. };
  666. void Skeleton::_mergeSkeletonAnimations(const Skeleton* src,
  667. const BoneHandleMap& boneHandleMap,
  668. const StringVector& animations)
  669. {
  670. ushort handle;
  671. ushort numSrcBones = src->getNumBones();
  672. ushort numDstBones = this->getNumBones();
  673. if (boneHandleMap.size() != numSrcBones)
  674. {
  675. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  676. "Number of bones in the bone handle map must equal to "
  677. "number of bones in the source skeleton.",
  678. "Skeleton::_mergeSkeletonAnimations");
  679. }
  680. bool existsMissingBone = false;
  681. // Check source skeleton structures compatible with ourself (that means
  682. // identically bones with identical handles, and with same hierarchy, but
  683. // not necessary to have same number of bones and bone names).
  684. for (handle = 0; handle < numSrcBones; ++handle)
  685. {
  686. const Bone* srcBone = src->getBone(handle);
  687. ushort dstHandle = boneHandleMap[handle];
  688. // Does it exists in target skeleton?
  689. if (dstHandle < numDstBones)
  690. {
  691. Bone* destBone = this->getBone(dstHandle);
  692. // Check both bones have identical parent, or both are root bone.
  693. const Bone* srcParent = static_cast<Bone*>(srcBone->getParent());
  694. Bone* destParent = static_cast<Bone*>(destBone->getParent());
  695. if ((srcParent || destParent) &&
  696. (!srcParent || !destParent ||
  697. boneHandleMap[srcParent->getHandle()] != destParent->getHandle()))
  698. {
  699. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  700. "Source skeleton incompatible with this skeleton: "
  701. "difference hierarchy between bone '" + srcBone->getName() +
  702. "' and '" + destBone->getName() + "'.",
  703. "Skeleton::_mergeSkeletonAnimations");
  704. }
  705. }
  706. else
  707. {
  708. existsMissingBone = true;
  709. }
  710. }
  711. // Clone bones if need
  712. if (existsMissingBone)
  713. {
  714. // Create missing bones
  715. for (handle = 0; handle < numSrcBones; ++handle)
  716. {
  717. const Bone* srcBone = src->getBone(handle);
  718. ushort dstHandle = boneHandleMap[handle];
  719. // The bone is missing in target skeleton?
  720. if (dstHandle >= numDstBones)
  721. {
  722. Bone* dstBone = this->createBone(srcBone->getName(), dstHandle);
  723. // Sets initial transform
  724. dstBone->setPosition(srcBone->getInitialPosition());
  725. dstBone->setOrientation(srcBone->getInitialOrientation());
  726. dstBone->setScale(srcBone->getInitialScale());
  727. dstBone->setInitialState();
  728. }
  729. }
  730. // Link new bones to parent
  731. for (handle = 0; handle < numSrcBones; ++handle)
  732. {
  733. const Bone* srcBone = src->getBone(handle);
  734. ushort dstHandle = boneHandleMap[handle];
  735. // Is new bone?
  736. if (dstHandle >= numDstBones)
  737. {
  738. const Bone* srcParent = static_cast<Bone*>(srcBone->getParent());
  739. if (srcParent)
  740. {
  741. Bone* destParent = this->getBone(boneHandleMap[srcParent->getHandle()]);
  742. Bone* dstBone = this->getBone(dstHandle);
  743. destParent->addChild(dstBone);
  744. }
  745. }
  746. }
  747. // Derive root bones in case it was changed
  748. this->deriveRootBone();
  749. // Reset binding pose for new bones
  750. this->reset(true);
  751. this->setBindingPose();
  752. }
  753. //
  754. // We need to adapt animations from source to target skeleton, but since source
  755. // and target skeleton bones bind transform might difference, so we need to alter
  756. // keyframes in source to suit to target skeleton.
  757. //
  758. // For any given animation time, formula:
  759. //
  760. // LocalTransform = BindTransform * KeyFrame;
  761. // DerivedTransform = ParentDerivedTransform * LocalTransform
  762. //
  763. // And all derived transforms should be keep identically after adapt to
  764. // target skeleton, Then:
  765. //
  766. // DestDerivedTransform == SrcDerivedTransform
  767. // DestParentDerivedTransform == SrcParentDerivedTransform
  768. // ==>
  769. // DestLocalTransform = SrcLocalTransform
  770. // ==>
  771. // DestBindTransform * DestKeyFrame = SrcBindTransform * SrcKeyFrame
  772. // ==>
  773. // DestKeyFrame = inverse(DestBindTransform) * SrcBindTransform * SrcKeyFrame
  774. //
  775. // We define (inverse(DestBindTransform) * SrcBindTransform) as 'delta-transform' here.
  776. //
  777. // Calculate delta-transforms for all source bones.
  778. vector<DeltaTransform>::type deltaTransforms(numSrcBones);
  779. for (handle = 0; handle < numSrcBones; ++handle)
  780. {
  781. const Bone* srcBone = src->getBone(handle);
  782. DeltaTransform& deltaTransform = deltaTransforms[handle];
  783. ushort dstHandle = boneHandleMap[handle];
  784. if (dstHandle < numDstBones)
  785. {
  786. // Common bone, calculate delta-transform
  787. Bone* dstBone = this->getBone(dstHandle);
  788. deltaTransform.translate = srcBone->getInitialPosition() - dstBone->getInitialPosition();
  789. deltaTransform.rotate = dstBone->getInitialOrientation().Inverse() * srcBone->getInitialOrientation();
  790. deltaTransform.scale = srcBone->getInitialScale() / dstBone->getInitialScale();
  791. // Check whether or not delta-transform is identity
  792. const Real tolerance = 1e-3f;
  793. Vector3 axis;
  794. Radian angle;
  795. deltaTransform.rotate.ToAngleAxis(angle, axis);
  796. deltaTransform.isIdentity =
  797. deltaTransform.translate.positionEquals(Vector3::ZERO, tolerance) &&
  798. deltaTransform.scale.positionEquals(Vector3::UNIT_SCALE, tolerance) &&
  799. Math::RealEqual(angle.valueRadians(), 0.0f, tolerance);
  800. }
  801. else
  802. {
  803. // New bone, the delta-transform is identity
  804. deltaTransform.translate = Vector3::ZERO;
  805. deltaTransform.rotate = Quaternion::IDENTITY;
  806. deltaTransform.scale = Vector3::UNIT_SCALE;
  807. deltaTransform.isIdentity = true;
  808. }
  809. }
  810. // Now copy animations
  811. ushort numAnimations;
  812. if (animations.empty())
  813. numAnimations = src->getNumAnimations();
  814. else
  815. numAnimations = static_cast<ushort>(animations.size());
  816. for (ushort i = 0; i < numAnimations; ++i)
  817. {
  818. const Animation* srcAnimation;
  819. if (animations.empty())
  820. {
  821. // Get animation of source skeleton by the given index
  822. srcAnimation = src->getAnimation(i);
  823. }
  824. else
  825. {
  826. // Get animation of source skeleton by the given name
  827. const LinkedSkeletonAnimationSource* linker;
  828. srcAnimation = src->_getAnimationImpl(animations[i], &linker);
  829. if (!srcAnimation || linker)
  830. {
  831. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
  832. "No animation entry found named " + animations[i],
  833. "Skeleton::_mergeSkeletonAnimations");
  834. }
  835. }
  836. // Create target animation
  837. Animation* dstAnimation = this->createAnimation(srcAnimation->getName(), srcAnimation->getLength());
  838. // Copy interpolation modes
  839. dstAnimation->setInterpolationMode(srcAnimation->getInterpolationMode());
  840. dstAnimation->setRotationInterpolationMode(srcAnimation->getRotationInterpolationMode());
  841. // Copy track for each bone
  842. for (handle = 0; handle < numSrcBones; ++handle)
  843. {
  844. const DeltaTransform& deltaTransform = deltaTransforms[handle];
  845. ushort dstHandle = boneHandleMap[handle];
  846. if (srcAnimation->hasNodeTrack(handle))
  847. {
  848. // Clone track from source animation
  849. const NodeAnimationTrack* srcTrack = srcAnimation->getNodeTrack(handle);
  850. NodeAnimationTrack* dstTrack = dstAnimation->createNodeTrack(dstHandle, this->getBone(dstHandle));
  851. dstTrack->setUseShortestRotationPath(srcTrack->getUseShortestRotationPath());
  852. ushort numKeyFrames = srcTrack->getNumKeyFrames();
  853. for (ushort k = 0; k < numKeyFrames; ++k)
  854. {
  855. const TransformKeyFrame* srcKeyFrame = srcTrack->getNodeKeyFrame(k);
  856. TransformKeyFrame* dstKeyFrame = dstTrack->createNodeKeyFrame(srcKeyFrame->getTime());
  857. // Adjust keyframes to match target binding pose
  858. if (deltaTransform.isIdentity)
  859. {
  860. dstKeyFrame->setTranslate(srcKeyFrame->getTranslate());
  861. dstKeyFrame->setRotation(srcKeyFrame->getRotation());
  862. dstKeyFrame->setScale(srcKeyFrame->getScale());
  863. }
  864. else
  865. {
  866. dstKeyFrame->setTranslate(deltaTransform.translate + srcKeyFrame->getTranslate());
  867. dstKeyFrame->setRotation(deltaTransform.rotate * srcKeyFrame->getRotation());
  868. dstKeyFrame->setScale(deltaTransform.scale * srcKeyFrame->getScale());
  869. }
  870. }
  871. }
  872. else if (!deltaTransform.isIdentity)
  873. {
  874. // Create 'static' track for this bone
  875. NodeAnimationTrack* dstTrack = dstAnimation->createNodeTrack(dstHandle, this->getBone(dstHandle));
  876. TransformKeyFrame* dstKeyFrame;
  877. dstKeyFrame = dstTrack->createNodeKeyFrame(0);
  878. dstKeyFrame->setTranslate(deltaTransform.translate);
  879. dstKeyFrame->setRotation(deltaTransform.rotate);
  880. dstKeyFrame->setScale(deltaTransform.scale);
  881. dstKeyFrame = dstTrack->createNodeKeyFrame(dstAnimation->getLength());
  882. dstKeyFrame->setTranslate(deltaTransform.translate);
  883. dstKeyFrame->setRotation(deltaTransform.rotate);
  884. dstKeyFrame->setScale(deltaTransform.scale);
  885. }
  886. }
  887. }
  888. }
  889. //---------------------------------------------------------------------
  890. void Skeleton::_buildMapBoneByHandle(const Skeleton* src,
  891. BoneHandleMap& boneHandleMap) const
  892. {
  893. ushort numSrcBones = src->getNumBones();
  894. boneHandleMap.resize(numSrcBones);
  895. for (ushort handle = 0; handle < numSrcBones; ++handle)
  896. {
  897. boneHandleMap[handle] = handle;
  898. }
  899. }
  900. //---------------------------------------------------------------------
  901. void Skeleton::_buildMapBoneByName(const Skeleton* src,
  902. BoneHandleMap& boneHandleMap) const
  903. {
  904. ushort numSrcBones = src->getNumBones();
  905. boneHandleMap.resize(numSrcBones);
  906. ushort newBoneHandle = this->getNumBones();
  907. for (ushort handle = 0; handle < numSrcBones; ++handle)
  908. {
  909. const Bone* srcBone = src->getBone(handle);
  910. BoneListByName::const_iterator i = this->mBoneListByName.find(srcBone->getName());
  911. if (i == mBoneListByName.end())
  912. boneHandleMap[handle] = newBoneHandle++;
  913. else
  914. boneHandleMap[handle] = i->second->getHandle();
  915. }
  916. }
  917. }