source: OGRE/trunk/ogrenew/OgreMain/src/OgreSkeletonInstance.cpp @ 692

Revision 692, 8.1 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreSkeletonInstance.h"
27#include "OgreBone.h"
28#include "OgreTagPoint.h"
29
30
31namespace Ogre {
32    //-------------------------------------------------------------------------
33    SkeletonInstance::SkeletonInstance(const SkeletonPtr& masterCopy)
34        : Skeleton(), mSkeleton(masterCopy)
35    {
36        mNextTagPointAutoHandle = 0;
37    }
38    //-------------------------------------------------------------------------
39    SkeletonInstance::~SkeletonInstance()
40    {
41        // have to call this here rather than in Resource destructor
42        // since calling virtual methods in base destructors causes crash
43        // ...and calling it in Skeleton destructor does not unload
44        // SkeletonInstance since it has seized to be by then.
45        unload();
46    }
47    //-------------------------------------------------------------------------
48    unsigned short SkeletonInstance::getNumAnimations(void) const
49    {
50        return mSkeleton->getNumAnimations();
51    }
52    //-------------------------------------------------------------------------
53    Animation* SkeletonInstance::getAnimation(unsigned short index) const
54    {
55        return mSkeleton->getAnimation(index);
56    }
57    //-------------------------------------------------------------------------
58    Animation* SkeletonInstance::createAnimation(const String& name, Real length)
59    {
60        return mSkeleton->createAnimation(name, length);
61    }
62    //-------------------------------------------------------------------------
63    Animation* SkeletonInstance::getAnimation(const String& name,
64                const LinkedSkeletonAnimationSource** linker) const
65    {
66        return mSkeleton->getAnimation(name, linker);
67    }
68    //-------------------------------------------------------------------------
69    void SkeletonInstance::removeAnimation(const String& name)
70    {
71        mSkeleton->removeAnimation(name);
72    }
73        //-------------------------------------------------------------------------
74        void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName,
75                Real scale)
76        {
77                mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale);
78        }
79        //-------------------------------------------------------------------------
80        void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void)
81        {
82                mSkeleton->removeAllLinkedSkeletonAnimationSources();
83        }
84        //-------------------------------------------------------------------------
85        Skeleton::LinkedSkeletonAnimSourceIterator
86        SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const
87        {
88                return mSkeleton->getLinkedSkeletonAnimationSourceIterator();
89        }
90        //-------------------------------------------------------------------------
91        void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet)
92        {
93                mSkeleton->_initAnimationState(animSet);
94        }
95        //-------------------------------------------------------------------------
96        void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet)
97        {
98                mSkeleton->_refreshAnimationState(animSet);
99        }
100    //-------------------------------------------------------------------------
101    void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent)
102    {
103        Bone* newBone;
104        if (source->getName() == "")
105        {
106            newBone = createBone(source->getHandle());
107        }
108        else
109        {
110            newBone = createBone(source->getName(), source->getHandle());
111        }
112        if (parent == NULL)
113        {
114            mRootBones.push_back(newBone);
115        }
116        else
117        {
118            parent->addChild(newBone);
119        }
120        newBone->setOrientation(source->getOrientation());
121        newBone->setPosition(source->getPosition());
122        newBone->setScale(source->getScale());
123
124        // Process children
125        Node::ChildNodeIterator it = source->getChildIterator();
126        while (it.hasMoreElements())
127        {
128            cloneBoneAndChildren(static_cast<Bone*>(it.getNext()), newBone);
129        }
130    }
131    //-------------------------------------------------------------------------
132    void SkeletonInstance::loadImpl(void)
133    {
134        mNextAutoHandle = mSkeleton->mNextAutoHandle;
135        mNextTagPointAutoHandle = 0;
136        // construct self from master
137        mBlendState = mSkeleton->mBlendState;
138        // Copy bones
139        BoneIterator i = mSkeleton->getRootBoneIterator();
140        while (i.hasMoreElements())
141        {
142            Bone* b = i.getNext();
143            cloneBoneAndChildren(b, 0);
144            b->_update(true, false);
145        }
146        setBindingPose();
147    }
148    //-------------------------------------------------------------------------
149    void SkeletonInstance::unloadImpl(void)
150    {
151        Skeleton::unloadImpl();
152
153        // destroy TagPoints
154        for (ActiveTagPointList::const_iterator it = mActiveTagPoints.begin(); it != mActiveTagPoints.end(); ++it)
155        {
156            TagPoint* tagPoint = *it;
157            // Woohoo! The child object all the same attaching this skeleton instance, but is ok we can just
158            // ignore it:
159            //   1. The parent node of the tagPoint already deleted by Skeleton::unload(), nothing need to do now
160            //   2. And the child object relationship already detached by Entity::~Entity()
161            delete tagPoint;
162        }
163        mActiveTagPoints.clear();
164        for (FreeTagPointQueue::const_iterator it2 = mFreeTagPoints.begin(); it2 != mFreeTagPoints.end(); ++it2)
165        {
166            TagPoint* tagPoint = *it2;
167            delete tagPoint;
168        }
169        mFreeTagPoints.clear();
170    }
171
172    //-------------------------------------------------------------------------
173    TagPoint* SkeletonInstance::createTagPointOnBone(Bone* bone,
174        const Quaternion &offsetOrientation,
175        const Vector3 &offsetPosition)
176    {
177        TagPoint* ret;
178        if (mFreeTagPoints.empty()) {
179            ret = new TagPoint(mNextTagPointAutoHandle++, this);
180        } else {
181            ret = mFreeTagPoints.front();
182            mFreeTagPoints.pop_front();
183            // Initial some members ensure identically behavior, avoiding potential bug.
184            ret->setParentEntity(0);
185            ret->setChildObject(0);
186            ret->setInheritOrientation(true);
187            ret->setInheritScale(true);
188        }
189        mActiveTagPoints.push_back(ret);
190
191        ret->setPosition(offsetPosition);
192        ret->setOrientation(offsetOrientation);
193        ret->setScale(Vector3::UNIT_SCALE);
194        ret->setBindingPose();
195        bone->addChild(ret);
196
197        return ret;
198    }
199    //-------------------------------------------------------------------------
200    void SkeletonInstance::freeTagPoint(TagPoint* tagPoint)
201    {
202        assert(std::find(mActiveTagPoints.begin(), mActiveTagPoints.end(), tagPoint) != mActiveTagPoints.end());
203
204        if (tagPoint->getParent())
205            tagPoint->getParent()->removeChild(tagPoint);
206
207        mActiveTagPoints.remove(tagPoint);
208        mFreeTagPoints.push_back(tagPoint);
209    }
210
211}
212
Note: See TracBrowser for help on using the repository browser.