PageRenderTime 64ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/game-ui-solution/OGRE-1.7.2/OgreMain/src/OgreSkeleton.cpp

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