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

Revision 692, 16.2 KB checked in by mattausch, 18 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 "OgreAnimation.h"
27#include "OgreKeyFrame.h"
28#include "OgreException.h"
29#include "OgreSkeleton.h"
30#include "OgreBone.h"
31#include "OgreEntity.h"
32#include "OgreSubEntity.h"
33#include "OgreMesh.h"
34#include "OgreSubMesh.h"
35
36namespace Ogre {
37
38    Animation::InterpolationMode Animation::msDefaultInterpolationMode = Animation::IM_LINEAR;
39    Animation::RotationInterpolationMode
40        Animation::msDefaultRotationInterpolationMode = Animation::RIM_LINEAR;
41    //---------------------------------------------------------------------
42    Animation::Animation(const String& name, Real length) : mName(name), mLength(length)
43    {
44        mInterpolationMode = Animation::msDefaultInterpolationMode;
45        mRotationInterpolationMode = Animation::msDefaultRotationInterpolationMode;
46    }
47    //---------------------------------------------------------------------
48    Animation::~Animation()
49    {
50        destroyAllTracks();
51    }
52    //---------------------------------------------------------------------
53    Real Animation::getLength(void) const
54    {
55        return mLength;
56    }
57    //---------------------------------------------------------------------
58    NodeAnimationTrack* Animation::createNodeTrack(unsigned short handle)
59    {
60        NodeAnimationTrack* ret = new NodeAnimationTrack(this, handle);
61
62        mNodeTrackList[handle] = ret;
63        return ret;
64    }
65    //---------------------------------------------------------------------
66    NodeAnimationTrack* Animation::createNodeTrack(unsigned short handle, Node* node)
67    {
68        NodeAnimationTrack* ret = createNodeTrack(handle);
69
70        ret->setAssociatedNode(node);
71
72        return ret;
73    }
74    //---------------------------------------------------------------------
75    unsigned short Animation::getNumNodeTracks(void) const
76    {
77        return (unsigned short)mNodeTrackList.size();
78    }
79        //---------------------------------------------------------------------
80        bool Animation::hasNodeTrack(unsigned short handle) const
81        {
82                return (mNodeTrackList.find(handle) != mNodeTrackList.end());
83        }
84    //---------------------------------------------------------------------
85    NodeAnimationTrack* Animation::getNodeTrack(unsigned short handle) const
86    {
87        NodeTrackList::const_iterator i = mNodeTrackList.find(handle);
88
89        if (i == mNodeTrackList.end())
90        {
91            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
92                "Cannot find node track with the specified handle",
93                "Animation::getNodeTrack");
94        }
95
96        return i->second;
97
98    }
99    //---------------------------------------------------------------------
100    void Animation::destroyNodeTrack(unsigned short handle)
101    {
102        NodeTrackList::iterator i = mNodeTrackList.find(handle);
103
104                if (i != mNodeTrackList.end())
105                {
106                        delete i->second;
107                        mNodeTrackList.erase(i);
108                }
109    }
110    //---------------------------------------------------------------------
111    void Animation::destroyAllNodeTracks(void)
112    {
113        NodeTrackList::iterator i;
114        for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i)
115        {
116            delete i->second;
117        }
118        mNodeTrackList.clear();
119    }
120        //---------------------------------------------------------------------
121        NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle)
122        {
123                NumericAnimationTrack* ret = new NumericAnimationTrack(this, handle);
124
125                mNumericTrackList[handle] = ret;
126                return ret;
127        }
128        //---------------------------------------------------------------------
129        NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle,
130                const AnimableValuePtr& anim)
131        {
132                NumericAnimationTrack* ret = createNumericTrack(handle);
133
134                ret->setAssociatedAnimable(anim);
135
136                return ret;
137        }
138        //---------------------------------------------------------------------
139        unsigned short Animation::getNumNumericTracks(void) const
140        {
141                return (unsigned short)mNumericTrackList.size();
142        }
143        //---------------------------------------------------------------------
144        bool Animation::hasNumericTrack(unsigned short handle) const
145        {
146                return (mNumericTrackList.find(handle) != mNumericTrackList.end());
147        }
148        //---------------------------------------------------------------------
149        NumericAnimationTrack* Animation::getNumericTrack(unsigned short handle) const
150        {
151                NumericTrackList::const_iterator i = mNumericTrackList.find(handle);
152
153                if (i == mNumericTrackList.end())
154                {
155                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
156                                "Cannot find Numeric track with the specified handle",
157                                "Animation::getNumericTrack");
158                }
159
160                return i->second;
161
162        }
163        //---------------------------------------------------------------------
164        void Animation::destroyNumericTrack(unsigned short handle)
165        {
166                NumericTrackList::iterator i = mNumericTrackList.find(handle);
167
168                if (i != mNumericTrackList.end())
169                {
170                        delete i->second;
171                        mNumericTrackList.erase(i);
172                }
173        }
174        //---------------------------------------------------------------------
175        void Animation::destroyAllNumericTracks(void)
176        {
177                NumericTrackList::iterator i;
178                for (i = mNumericTrackList.begin(); i != mNumericTrackList.end(); ++i)
179                {
180                        delete i->second;
181                }
182                mNumericTrackList.clear();
183        }
184        //---------------------------------------------------------------------
185        VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle,
186                VertexAnimationType animType)
187        {
188                VertexAnimationTrack* ret = new VertexAnimationTrack(this, handle, animType);
189
190                mVertexTrackList[handle] = ret;
191                return ret;
192
193        }
194        //---------------------------------------------------------------------
195        VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle,
196                VertexData* data, VertexAnimationType animType)
197        {
198                VertexAnimationTrack* ret = createVertexTrack(handle, animType);
199
200                ret->setAssociatedVertexData(data);
201
202                return ret;
203        }
204        //---------------------------------------------------------------------
205        unsigned short Animation::getNumVertexTracks(void) const
206        {
207                return (unsigned short)mVertexTrackList.size();
208        }
209        //---------------------------------------------------------------------
210        bool Animation::hasVertexTrack(unsigned short handle) const
211        {
212                return (mVertexTrackList.find(handle) != mVertexTrackList.end());
213        }
214        //---------------------------------------------------------------------
215        VertexAnimationTrack* Animation::getVertexTrack(unsigned short handle) const
216        {
217                VertexTrackList::const_iterator i = mVertexTrackList.find(handle);
218
219                if (i == mVertexTrackList.end())
220                {
221                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
222                                "Cannot find Vertex track with the specified handle",
223                                "Animation::getVertexTrack");
224                }
225
226                return i->second;
227
228        }
229        //---------------------------------------------------------------------
230        void Animation::destroyVertexTrack(unsigned short handle)
231        {
232                VertexTrackList::iterator i = mVertexTrackList.find(handle);
233
234                if (i != mVertexTrackList.end())
235                {
236                        delete i->second;
237                        mVertexTrackList.erase(i);
238                }
239        }
240        //---------------------------------------------------------------------
241        void Animation::destroyAllVertexTracks(void)
242        {
243                VertexTrackList::iterator i;
244                for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i)
245                {
246                        delete i->second;
247                }
248                mVertexTrackList.clear();
249        }
250        //---------------------------------------------------------------------
251        void Animation::destroyAllTracks(void)
252        {
253                destroyAllNodeTracks();
254                destroyAllNumericTracks();
255                destroyAllVertexTracks();
256        }
257    //---------------------------------------------------------------------
258    const String& Animation::getName(void) const
259    {
260        return mName;
261    }
262    //---------------------------------------------------------------------
263        void Animation::apply(Real timePos, Real weight, bool accumulate, Real scale)
264    {
265        NodeTrackList::iterator i;
266        for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i)
267        {
268            i->second->apply(timePos, weight, accumulate, scale);
269        }
270                NumericTrackList::iterator j;
271                for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j)
272                {
273                        j->second->apply(timePos, weight, accumulate, scale);
274                }
275                VertexTrackList::iterator k;
276                for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k)
277                {
278                        k->second->apply(timePos, weight, accumulate, scale);
279                }
280
281    }
282    //---------------------------------------------------------------------
283    void Animation::apply(Skeleton* skel, Real timePos, Real weight,
284                bool accumulate, Real scale)
285    {
286        NodeTrackList::iterator i;
287        for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i)
288        {
289            // get bone to apply to
290            Bone* b = skel->getBone(i->first);
291            i->second->applyToNode(b, timePos, weight, accumulate, scale);
292        }
293
294
295    }
296        //---------------------------------------------------------------------
297        void Animation::apply(Entity* entity, Real timePos, Real weight,
298                bool software, bool hardware)
299        {
300                VertexTrackList::iterator i;
301                for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i)
302                {
303                        unsigned short handle = i->first;
304                        VertexAnimationTrack* track = i->second;
305
306                        VertexData* swVertexData;
307                        VertexData* hwVertexData;
308                        VertexData* origVertexData;
309                        bool firstAnim = false;
310                        if (handle == 0)
311                        {
312                                // shared vertex data
313                                firstAnim = !entity->_getBuffersMarkedForAnimation();
314                                swVertexData = entity->_getSoftwareVertexAnimVertexData();
315                                hwVertexData = entity->_getHardwareVertexAnimVertexData();
316                                origVertexData = entity->getMesh()->sharedVertexData;
317                                entity->_markBuffersUsedForAnimation();
318                        }
319                        else
320                        {
321                                // sub entity vertex data (-1)
322                                SubEntity* s = entity->getSubEntity(handle - 1);
323                                firstAnim = !s->_getBuffersMarkedForAnimation();
324                                swVertexData = s->_getSoftwareVertexAnimVertexData();
325                                hwVertexData = s->_getHardwareVertexAnimVertexData();
326                                origVertexData = s->getSubMesh()->vertexData;
327                                s->_markBuffersUsedForAnimation();
328                        }
329                        // Apply to both hardware and software, if requested
330                        if (software)
331                        {
332                                if (firstAnim && track->getAnimationType() == VAT_POSE)
333                                {
334                                        // First time through for a piece of pose animated vertex data
335                                        // We need to copy the original position values to the temp accumulator
336                                        const VertexElement* origelem =
337                                                origVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
338                                        const VertexElement* destelem =
339                                                swVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
340                                        HardwareVertexBufferSharedPtr origBuffer =
341                                                origVertexData->vertexBufferBinding->getBuffer(origelem->getSource());
342                                        HardwareVertexBufferSharedPtr destBuffer =
343                                                swVertexData->vertexBufferBinding->getBuffer(destelem->getSource());
344                                        destBuffer->copyData(*origBuffer.get(), 0, 0, destBuffer->getSizeInBytes(), true);
345                                }
346                                track->setTargetMode(VertexAnimationTrack::TM_SOFTWARE);
347                                track->applyToVertexData(swVertexData, timePos, weight,
348                                        &(entity->getMesh()->getPoseList()));
349                        }
350                        if (hardware)
351                        {
352                                track->setTargetMode(VertexAnimationTrack::TM_HARDWARE);
353                                track->applyToVertexData(hwVertexData, timePos, weight,
354                                        &(entity->getMesh()->getPoseList()));
355                        }
356                }
357
358        }
359    //---------------------------------------------------------------------
360    void Animation::setInterpolationMode(InterpolationMode im)
361    {
362        mInterpolationMode = im;
363    }
364    //---------------------------------------------------------------------
365    Animation::InterpolationMode Animation::getInterpolationMode(void) const
366    {
367        return mInterpolationMode;
368    }
369    //---------------------------------------------------------------------
370    void Animation::setDefaultInterpolationMode(InterpolationMode im)
371    {
372        msDefaultInterpolationMode = im;
373    }
374    //---------------------------------------------------------------------
375    Animation::InterpolationMode Animation::getDefaultInterpolationMode(void)
376    {
377        return msDefaultInterpolationMode;
378    }
379    //---------------------------------------------------------------------
380    const Animation::NodeTrackList& Animation::_getNodeTrackList(void) const
381    {
382        return mNodeTrackList;
383
384    }
385        //---------------------------------------------------------------------
386        const Animation::NumericTrackList& Animation::_getNumericTrackList(void) const
387        {
388                return mNumericTrackList;
389        }
390    //---------------------------------------------------------------------
391    void Animation::setRotationInterpolationMode(RotationInterpolationMode im)
392    {
393        mRotationInterpolationMode = im;
394    }
395    //---------------------------------------------------------------------
396    Animation::RotationInterpolationMode Animation::getRotationInterpolationMode(void) const
397    {
398        return mRotationInterpolationMode;
399    }
400    //---------------------------------------------------------------------
401    void Animation::setDefaultRotationInterpolationMode(RotationInterpolationMode im)
402    {
403        msDefaultRotationInterpolationMode = im;
404    }
405    //---------------------------------------------------------------------
406    Animation::RotationInterpolationMode Animation::getDefaultRotationInterpolationMode(void)
407    {
408        return msDefaultRotationInterpolationMode;
409    }
410    //---------------------------------------------------------------------
411        void Animation::optimise(void)
412        {
413                optimiseNodeTracks();
414                optimiseVertexTracks();
415               
416        }
417        //-----------------------------------------------------------------------
418        void Animation::optimiseNodeTracks(void)
419        {
420                // Iterate over the node tracks and identify those with no useful keyframes
421                std::list<unsigned short> tracksToDestroy;
422                NodeTrackList::iterator i;
423                for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i)
424                {
425                        NodeAnimationTrack* track = i->second;
426                        if (!track->hasNonZeroKeyFrames())
427                        {
428                                // mark the entire track for destruction
429                                tracksToDestroy.push_back(i->first);
430                        }
431                        else
432                        {
433                                track->optimise();
434                        }
435
436                }
437
438                // Now destroy the tracks we marked for death
439                for(std::list<unsigned short>::iterator h = tracksToDestroy.begin();
440                        h != tracksToDestroy.end(); ++h)
441                {
442                        destroyNodeTrack(*h);
443                }
444        }
445        //-----------------------------------------------------------------------
446        void Animation::optimiseVertexTracks(void)
447        {
448                // Iterate over the node tracks and identify those with no useful keyframes
449                std::list<unsigned short> tracksToDestroy;
450                VertexTrackList::iterator i;
451                for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i)
452                {
453                        VertexAnimationTrack* track = i->second;
454                        if (!track->hasNonZeroKeyFrames())
455                        {
456                                // mark the entire track for destruction
457                                tracksToDestroy.push_back(i->first);
458                        }
459                        else
460                        {
461                                track->optimise();
462                        }
463
464                }
465
466                // Now destroy the tracks we marked for death
467                for(std::list<unsigned short>::iterator h = tracksToDestroy.begin();
468                        h != tracksToDestroy.end(); ++h)
469                {
470                        destroyVertexTrack(*h);
471                }
472
473        }
474
475}
476
477
Note: See TracBrowser for help on using the repository browser.