Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreSkeletonInstance.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004 (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2004 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 #include "OgreSkeletonInstance.h"
00027 #include "OgreBone.h"
00028 #include "OgreTagPoint.h"
00029 
00030 
00031 namespace Ogre {
00032     //-------------------------------------------------------------------------
00033     SkeletonInstance::SkeletonInstance(Skeleton* masterCopy) 
00034         : Skeleton(""), mSkeleton(masterCopy)
00035     {
00036         mNextTagPointAutoHandle = 0;
00037     }
00038     //-------------------------------------------------------------------------
00039     SkeletonInstance::~SkeletonInstance()
00040     {
00041         unload();
00042     }
00043     //-------------------------------------------------------------------------
00044     unsigned short SkeletonInstance::getNumAnimations(void) const
00045     {
00046         return mSkeleton->getNumAnimations();
00047     }
00048     //-------------------------------------------------------------------------
00049     Animation* SkeletonInstance::getAnimation(unsigned short index) const
00050     {
00051         return mSkeleton->getAnimation(index);
00052     }
00053     //-------------------------------------------------------------------------
00054     Animation* SkeletonInstance::createAnimation(const String& name, Real length)
00055     {
00056         return mSkeleton->createAnimation(name, length);
00057     }
00058     //-------------------------------------------------------------------------
00059     Animation* SkeletonInstance::getAnimation(const String& name) const
00060     {
00061         return mSkeleton->getAnimation(name);
00062     }
00063     //-------------------------------------------------------------------------
00064     void SkeletonInstance::removeAnimation(const String& name)
00065     {
00066         mSkeleton->removeAnimation(name);
00067     }
00068     //-------------------------------------------------------------------------
00069     void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent)
00070     {
00071         Bone* newBone;
00072         if (source->getName() == "")
00073         {
00074             newBone = createBone(source->getHandle());
00075         }
00076         else
00077         {
00078             newBone = createBone(source->getName(), source->getHandle());
00079         }
00080         if (parent == NULL)
00081         {
00082             mRootBones.push_back(newBone);
00083         }
00084         else
00085         {
00086             parent->addChild(newBone);
00087         }
00088         newBone->setOrientation(source->getOrientation());
00089         newBone->setPosition(source->getPosition());
00090         newBone->setScale(source->getScale());
00091 
00092         // Process children
00093         Node::ChildNodeIterator it = source->getChildIterator();
00094         while (it.hasMoreElements())
00095         {
00096             cloneBoneAndChildren(static_cast<Bone*>(it.getNext()), newBone);
00097         }
00098     }
00099     //-------------------------------------------------------------------------
00100     void SkeletonInstance::load(void)
00101     {
00102         assert(!mIsLoaded && "skeleton instance can not load more than once!");
00103 
00104         mNextAutoHandle = mSkeleton->mNextAutoHandle;
00105         mNextTagPointAutoHandle = 0;
00106         // construct self from master
00107         mBlendState = mSkeleton->mBlendState;
00108         // Copy bones
00109         BoneIterator i = mSkeleton->getRootBoneIterator();
00110         while (i.hasMoreElements())
00111         {
00112             Bone* b = i.getNext();
00113             cloneBoneAndChildren(b, 0);
00114             b->_update(true, false);
00115         }
00116         setBindingPose();
00117         mIsLoaded = true;
00118     }
00119     //-------------------------------------------------------------------------
00120     void SkeletonInstance::unload(void)
00121     {
00122         Skeleton::unload();
00123 
00124         // destroy TagPoints
00125         for (ActiveTagPointList::const_iterator it = mActiveTagPoints.begin(); it != mActiveTagPoints.end(); ++it)
00126         {
00127             TagPoint* tagPoint = *it;
00128             // Woohoo! The child object all the same attaching this skeleton instance, but is ok we can just
00129             // ignore it:
00130             //   1. The parent node of the tagPoint already deleted by Skeleton::unload(), nothing need to do now
00131             //   2. And the child object relationship already detached by Entity::~Entity()
00132             delete tagPoint;
00133         }
00134         mActiveTagPoints.clear();
00135         for (FreeTagPointQueue::const_iterator it2 = mFreeTagPoints.begin(); it2 != mFreeTagPoints.end(); ++it2)
00136         {
00137             TagPoint* tagPoint = *it2;
00138             delete tagPoint;
00139         }
00140         mFreeTagPoints.clear();
00141     }
00142 
00143     //-------------------------------------------------------------------------
00144     TagPoint* SkeletonInstance::createTagPointOnBone(Bone* bone,
00145         const Quaternion &offsetOrientation, 
00146         const Vector3 &offsetPosition)
00147     {
00148         TagPoint* ret;
00149         if (mFreeTagPoints.empty()) {
00150             ret = new TagPoint(mNextTagPointAutoHandle++, this);
00151         } else {
00152             ret = mFreeTagPoints.front();
00153             mFreeTagPoints.pop_front();
00154         }
00155         mActiveTagPoints.push_back(ret);
00156 
00157         ret->setPosition(offsetPosition);
00158         ret->setOrientation(offsetOrientation);
00159         ret->setScale(Vector3::UNIT_SCALE);
00160         ret->setBindingPose();
00161         bone->addChild(ret);
00162 
00163         return ret;
00164     }
00165     //-------------------------------------------------------------------------
00166     void SkeletonInstance::freeTagPoint(TagPoint* tagPoint)
00167     {
00168         assert(std::find(mActiveTagPoints.begin(), mActiveTagPoints.end(), tagPoint) != mActiveTagPoints.end());
00169 
00170         if (tagPoint->getParent())
00171             tagPoint->getParent()->removeChild(tagPoint);
00172 
00173         mActiveTagPoints.remove(tagPoint);
00174         mFreeTagPoints.push_back(tagPoint);
00175     }
00176 
00177 }
00178 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:47 2004