Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreAnimationState.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 13.0 KB
RevLine 
[1]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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30
31#include "OgreAnimationState.h"
32#include "OgreException.h"
33
34namespace Ogre
35{
36
37        //---------------------------------------------------------------------
38        AnimationState::AnimationState(AnimationStateSet* parent, const AnimationState &rhs)
39        : mAnimationName(rhs.mAnimationName)
40        , mParent(parent)
41        , mTimePos(rhs.mTimePos)
42        , mLength(rhs.mLength)
43        , mWeight(rhs.mWeight)
44        , mEnabled(rhs.mEnabled)
45        , mLoop(rhs.mLoop)
46        {
47                mParent->_notifyDirty();
48        }
49        //---------------------------------------------------------------------
50        AnimationState::~AnimationState()
51        {
52        }
53    //---------------------------------------------------------------------
54    AnimationState::AnimationState(const String& animName, 
55                AnimationStateSet *parent, Real timePos, Real length, Real weight, 
56                bool enabled)
57        : mAnimationName(animName)
58        , mParent(parent)
59        , mTimePos(timePos)
60        , mLength(length)
61        , mWeight(weight)
62        , mEnabled(enabled)
63        , mLoop(true)
64    {
65                mParent->_notifyDirty();
66    }
67    //---------------------------------------------------------------------
68    const String& AnimationState::getAnimationName() const
69    {
70        return mAnimationName;
71    }
72    //---------------------------------------------------------------------
73    Real AnimationState::getTimePosition(void) const
74    {
75        return mTimePos;
76    }
77    //---------------------------------------------------------------------
78    void AnimationState::setTimePosition(Real timePos)
79    {
80                if (timePos != mTimePos)
81                {
82                        mTimePos = timePos;
83                        if (mLoop)
84                        {
85                                // Wrap
86                                mTimePos = fmod(mTimePos, mLength);
87                                if(mTimePos < 0)
88                                        mTimePos += mLength;     
89                        }
90                        else
91                        {
92                                // Clamp
93                                if(mTimePos < 0)
94                                        mTimePos = 0;
95                                else if (mTimePos > mLength)
96                                        mTimePos = mLength;
97                        }
98
99            if (mEnabled)
100                mParent->_notifyDirty();
101        }
102
103    }
104    //---------------------------------------------------------------------
105    Real AnimationState::getLength() const
106    {
107        return mLength;
108    }
109    //---------------------------------------------------------------------
110    void AnimationState::setLength(Real len)
111    {
112        mLength = len;
113    }
114    //---------------------------------------------------------------------
115    Real AnimationState::getWeight(void) const
116    {
117        return mWeight;
118    }
119    //---------------------------------------------------------------------
120    void AnimationState::setWeight(Real weight)
121    {
122        mWeight = weight;
123
124        if (mEnabled)
125            mParent->_notifyDirty();
126    }
127    //---------------------------------------------------------------------
128    void AnimationState::addTime(Real offset)
129    {
130        setTimePosition(mTimePos + offset);
131    }
132    //---------------------------------------------------------------------
133        bool AnimationState::hasEnded(void) const
134        {
135                return (mTimePos == mLength && !mLoop);
136        }
137    //---------------------------------------------------------------------
138    bool AnimationState::getEnabled(void) const
139    {
140        return mEnabled;
141    }
142    //---------------------------------------------------------------------
143    void AnimationState::setEnabled(bool enabled)
144    {
145        mEnabled = enabled;
146        mParent->_notifyAnimationStateEnabled(this, enabled);
147    }
148    //---------------------------------------------------------------------
149    bool AnimationState::operator==(const AnimationState& rhs) const
150    {
151        if (mAnimationName == rhs.mAnimationName &&
152            mEnabled == rhs.mEnabled &&
153            mTimePos == rhs.mTimePos &&
154            mWeight == rhs.mWeight &&
155            mLength == rhs.mLength && 
156            mLoop == rhs.mLoop)
157        {
158            return true;
159        }
160        else
161        {
162            return false;
163        }
164    }
165    //---------------------------------------------------------------------
166    bool AnimationState::operator!=(const AnimationState& rhs) const
167    {
168        return !(*this == rhs);
169    }
170    //---------------------------------------------------------------------
171    void AnimationState::copyStateFrom(const AnimationState& animState)
172    {
173        mTimePos = animState.mTimePos;
174        mLength = animState.mLength;
175        mWeight = animState.mWeight;
176        mEnabled = animState.mEnabled;
177        mLoop = animState.mLoop;
178                mParent->_notifyDirty();
179
180    }
181        //---------------------------------------------------------------------
182        //---------------------------------------------------------------------
183        AnimationStateSet::AnimationStateSet()
184                : mDirtyFrameNumber(std::numeric_limits<unsigned long>::max())
185        {
186        }
187        //---------------------------------------------------------------------
188        AnimationStateSet::AnimationStateSet(const AnimationStateSet& rhs)
189                : mDirtyFrameNumber(std::numeric_limits<unsigned long>::max())
190        {
191                // lock rhs
192                OGRE_LOCK_MUTEX(rhs.OGRE_AUTO_MUTEX_NAME)
193
194                for (AnimationStateMap::const_iterator i = rhs.mAnimationStates.begin();
195                        i != rhs.mAnimationStates.end(); ++i)
196                {
197                        AnimationState* src = i->second;
198                        mAnimationStates[src->getAnimationName()] = 
199                                new AnimationState(this, *src);
200                }
201
202        // Clone enabled animation state list
203        for (EnabledAnimationStateList::const_iterator it = rhs.mEnabledAnimationStates.begin();
204            it != rhs.mEnabledAnimationStates.end(); ++it)
205        {
206            const AnimationState* src = *it;
207            mEnabledAnimationStates.push_back(getAnimationState(src->getAnimationName()));
208        }
209        }
210        //---------------------------------------------------------------------
211        AnimationStateSet::~AnimationStateSet()
212        {
213                // Destroy
214                removeAllAnimationStates();
215        }
216        //---------------------------------------------------------------------
217        void AnimationStateSet::removeAnimationState(const String& name)
218        {
219                OGRE_LOCK_AUTO_MUTEX
220
221                AnimationStateMap::iterator i = mAnimationStates.find(name);
222                if (i != mAnimationStates.end())
223                {
224            mEnabledAnimationStates.remove(i->second);
225
226                        delete i->second;
227                        mAnimationStates.erase(i);
228                }
229        }
230        //---------------------------------------------------------------------
231        void AnimationStateSet::removeAllAnimationStates(void)
232        {
233                OGRE_LOCK_AUTO_MUTEX
234
235                for (AnimationStateMap::iterator i = mAnimationStates.begin();
236                        i != mAnimationStates.end(); ++i)
237                {
238                        delete i->second;
239                }
240                mAnimationStates.clear();
241        mEnabledAnimationStates.clear();
242
243        }
244        //---------------------------------------------------------------------
245        AnimationState* AnimationStateSet::createAnimationState(const String& name, 
246                Real timePos, Real length, Real weight, bool enabled)
247        {
248                OGRE_LOCK_AUTO_MUTEX
249
250                AnimationStateMap::iterator i = mAnimationStates.find(name);
251                if (i != mAnimationStates.end())
252                {
253                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 
254                                "State for animation named '" + name + "' already exists.", 
255                                "AnimationStateSet::createAnimationState");
256                }
257
258                AnimationState* newState = new AnimationState(name, this, timePos, 
259                        length, weight, enabled);
260                mAnimationStates[name] = newState;
261
262                return newState;
263
264        }
265        //---------------------------------------------------------------------
266        AnimationState* AnimationStateSet::getAnimationState(const String& name) const
267        {
268                OGRE_LOCK_AUTO_MUTEX
269
270                AnimationStateMap::const_iterator i = mAnimationStates.find(name);
271                if (i == mAnimationStates.end())
272                {
273                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
274                                "No state found for animation named '" + name + "'", 
275                                "AnimationStateSet::getAnimationState");
276                }
277                return i->second;
278        }
279        //---------------------------------------------------------------------
280        bool AnimationStateSet::hasAnimationState(const String& name) const
281        {
282                OGRE_LOCK_AUTO_MUTEX
283
284                return mAnimationStates.find(name) != mAnimationStates.end();
285        }
286        //---------------------------------------------------------------------
287        AnimationStateIterator AnimationStateSet::getAnimationStateIterator(void)
288        {
289                OGRE_LOCK_AUTO_MUTEX
290                // returned iterator not threadsafe, noted in header
291                return AnimationStateIterator(
292                        mAnimationStates.begin(), mAnimationStates.end());
293        }
294        //---------------------------------------------------------------------
295        ConstAnimationStateIterator AnimationStateSet::getAnimationStateIterator(void) const
296        {
297                OGRE_LOCK_AUTO_MUTEX
298                // returned iterator not threadsafe, noted in header
299                return ConstAnimationStateIterator(
300                        mAnimationStates.begin(), mAnimationStates.end());
301        }
302        //---------------------------------------------------------------------
303        void AnimationStateSet::copyMatchingState(AnimationStateSet* target) const
304        {
305                // lock target
306                OGRE_LOCK_MUTEX(target->OGRE_AUTO_MUTEX_NAME)
307                // lock source
308                OGRE_LOCK_AUTO_MUTEX
309
310                AnimationStateMap::iterator i, iend;
311        iend = target->mAnimationStates.end();
312        for (i = target->mAnimationStates.begin(); i != iend; ++i) {
313            AnimationStateMap::const_iterator iother = mAnimationStates.find(i->first);
314            if (iother == mAnimationStates.end()) {
315                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + i->first, 
316                    "AnimationStateSet::copyMatchingState");
317            } else {
318                i->second->copyStateFrom(*(iother->second));
319            }
320        }
321
322        // Copy matching enabled animation state list
323        target->mEnabledAnimationStates.clear();
324
325        EnabledAnimationStateList::const_iterator it, itend;
326        itend = mEnabledAnimationStates.end();
327        for (it = mEnabledAnimationStates.begin(); it != itend; ++it)
328        {
329            const AnimationState* src = *it;
330            AnimationStateMap::const_iterator itarget = target->mAnimationStates.find(src->getAnimationName());
331            if (itarget != target->mAnimationStates.end())
332            {
333                target->mEnabledAnimationStates.push_back(itarget->second);
334            }
335        }
336
337        target->mDirtyFrameNumber = mDirtyFrameNumber;
338    }
339    //---------------------------------------------------------------------
340    void AnimationStateSet::_notifyDirty(void)
341    {
342                OGRE_LOCK_AUTO_MUTEX
343        ++mDirtyFrameNumber;
344    }
345    //---------------------------------------------------------------------
346    void AnimationStateSet::_notifyAnimationStateEnabled(AnimationState* target, bool enabled)
347    {
348                OGRE_LOCK_AUTO_MUTEX
349                // Remove from enabled animation state list first
350        mEnabledAnimationStates.remove(target);
351
352        // Add to enabled animation state list if need
353        if (enabled)
354        {
355            mEnabledAnimationStates.push_back(target);
356        }
357
358        // Set the dirty frame number
359        _notifyDirty();
360    }
361    //---------------------------------------------------------------------
362    ConstEnabledAnimationStateIterator AnimationStateSet::getEnabledAnimationStateIterator(void) const
363    {
364                OGRE_LOCK_AUTO_MUTEX
365                // returned iterator not threadsafe, noted in header
366        return ConstEnabledAnimationStateIterator(
367            mEnabledAnimationStates.begin(), mEnabledAnimationStates.end());
368    }
369        //---------------------------------------------------------------------
370        //---------------------------------------------------------------------
371        Real AnimationStateControllerValue::getValue(void) const
372        {
373                return mTargetAnimationState->getTimePosition() / mTargetAnimationState->getLength();
374        }
375        //---------------------------------------------------------------------
376        void AnimationStateControllerValue::setValue(Real value)
377        {
378                mTargetAnimationState->setTimePosition(value * mTargetAnimationState->getLength());
379        }
380
381
382}
383
Note: See TracBrowser for help on using the repository browser.