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