Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreSkeleton.h @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 24.1 KB
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-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
30#ifndef __Skeleton_H__
31#define __Skeleton_H__
32
33#include "OgrePrerequisites.h"
34#include "OgreResource.h"
35#include "OgreQuaternion.h"
36#include "OgreVector3.h"
37#include "OgreIteratorWrappers.h"
38#include "OgreStringVector.h"
39
40namespace Ogre {
41
42    /**  */
43    enum SkeletonAnimationBlendMode {
44        /// Animations are applied by calculating a weighted average of all animations
45            ANIMBLEND_AVERAGE,
46        /// Animations are applied by calculating a weighted cumulative total
47            ANIMBLEND_CUMULATIVE
48    };
49
50#define OGRE_MAX_NUM_BONES 256
51
52       
53        struct LinkedSkeletonAnimationSource;
54
55    /** A collection of Bone objects used to animate a skinned mesh.
56    @remarks
57        Skeletal animation works by having a collection of 'bones' which are
58        actually just joints with a position and orientation, arranged in a tree structure.
59        For example, the wrist joint is a child of the elbow joint, which in turn is a
60        child of the shoulder joint. Rotating the shoulder automatically moves the elbow
61        and wrist as well due to this hierarchy.
62    @par
63        So how does this animate a mesh? Well every vertex in a mesh is assigned to one or more
64        bones which affects it's position when the bone is moved. If a vertex is assigned to
65        more than one bone, then weights must be assigned to determine how much each bone affects
66        the vertex (actually a weight of 1.0 is used for single bone assignments).
67        Weighted vertex assignments are especially useful around the joints themselves
68        to avoid 'pinching' of the mesh in this region.
69    @par
70        Therefore by moving the skeleton using preset animations, we can animate the mesh. The
71        advantage of using skeletal animation is that you store less animation data, especially
72        as vertex counts increase. In addition, you are able to blend multiple animations together
73        (e.g. walking and looking around, running and shooting) and provide smooth transitions
74        between animations without incurring as much of an overhead as would be involved if you
75        did this on the core vertex data.
76    @par
77        Skeleton definitions are loaded from datafiles, namely the .skeleton file format. They
78        are loaded on demand, especially when referenced by a Mesh.
79    */
80    class _OgreExport Skeleton : public Resource
81    {
82                friend class SkeletonInstance;
83        protected:
84                /// Internal constructor for use by SkeletonInstance only
85                Skeleton();
86
87    public:
88        /** Constructor, don't call directly, use SkeletonManager.
89        @remarks
90            On creation, a Skeleton has a no bones, you should create them and link
91            them together appropriately.
92        */
93        Skeleton(ResourceManager* creator, const String& name, ResourceHandle handle,
94            const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
95        virtual ~Skeleton();
96
97
98        /** Creates a brand new Bone owned by this Skeleton.
99        @remarks
100            This method creates an unattached new Bone for this skeleton.
101                        Unless this is to be a root bone (there may be more than one of
102                        these), you must attach it to another Bone in the skeleton using addChild for it to be any use.
103            For this reason you will likely be better off creating child bones using the
104            Bone::createChild method instead, once you have created the root bone.
105        @par
106            Note that this method automatically generates a handle for the bone, which you
107            can retrieve using Bone::getHandle. If you wish the new Bone to have a specific
108            handle, use the alternate form of this method which takes a handle as a parameter,
109            although you should note the restrictions.
110        */
111        virtual Bone* createBone(void);
112
113        /** Creates a brand new Bone owned by this Skeleton.
114        @remarks
115            This method creates an unattached new Bone for this skeleton and assigns it a
116            specific handle. Unless this is to be a root bone (there may be more than one of
117                        these), you must attach it to another Bone in the skeleton using addChild for it to be any use.
118            For this reason you will likely be better off creating child bones using the
119            Bone::createChild method instead, once you have created a root bone.
120        @param handle The handle to give to this new bone - must be unique within this skeleton.
121            You should also ensure that all bone handles are eventually contiguous (this is to simplify
122            their compilation into an indexed array of transformation matrices). For this reason
123            it is advised that you use the simpler createBone method which automatically assigns a
124            sequential handle starting from 0.
125        */
126        virtual Bone* createBone(unsigned short handle);
127
128        /** Creates a brand new Bone owned by this Skeleton.
129        @remarks
130            This method creates an unattached new Bone for this skeleton and assigns it a
131            specific name.Unless this is to be a root bone (there may be more than one of
132                        these), you must attach it to another Bone in the skeleton using addChild for it to be any use.
133            For this reason you will likely be better off creating child bones using the
134            Bone::createChild method instead, once you have created the root bone.
135        @param name The name to give to this new bone - must be unique within this skeleton.
136            Note that the way OGRE looks up bones is via a numeric handle, so if you name a
137            Bone this way it will be given an automatic sequential handle. The name is just
138            for your convenience, although it is recommended that you only use the handle to
139            retrieve the bone in performance-critical code.
140        */
141        virtual Bone* createBone(const String& name);
142
143        /** Creates a brand new Bone owned by this Skeleton.
144        @remarks
145            This method creates an unattached new Bone for this skeleton and assigns it a
146            specific name and handle. Unless this is to be a root bone (there may be more than one of
147                        these), you must attach it to another Bone in the skeleton using addChild for it to be any use.
148            For this reason you will likely be better off creating child bones using the
149            Bone::createChild method instead, once you have created the root bone.
150        @param name The name to give to this new bone - must be unique within this skeleton.
151        @param handle The handle to give to this new bone - must be unique within this skeleton.
152        */
153        virtual Bone* createBone(const String& name, unsigned short handle);
154
155        /** Returns the number of bones in this skeleton. */
156        virtual unsigned short getNumBones(void) const;
157
158        /** Gets the root bone of the skeleton: deprecated in favour of getRootBoneIterator.
159        @remarks
160            The system derives the root bone the first time you ask for it. The root bone is the
161            only bone in the skeleton which has no parent. The system locates it by taking the
162            first bone in the list and going up the bone tree until there are no more parents,
163            and saves this top bone as the root. If you are building the skeleton manually using
164            createBone then you must ensure there is only one bone which is not a child of
165            another bone, otherwise your skeleton will not work properly. If you use createBone
166            only once, and then use Bone::createChild from then on, then inherently the first
167            bone you create will by default be the root.
168        */
169        virtual Bone* getRootBone(void) const;
170
171        typedef std::vector<Bone*> BoneList;
172        typedef VectorIterator<BoneList> BoneIterator;
173        /// Get an iterator over the root bones in the skeleton, ie those with no parents
174        virtual BoneIterator getRootBoneIterator(void);
175        /// Get an iterator over all the bones in the skeleton
176        virtual BoneIterator getBoneIterator(void);
177
178        /** Gets a bone by it's handle. */
179        virtual Bone* getBone(unsigned short handle) const;
180
181        /** Gets a bone by it's name. */
182        virtual Bone* getBone(const String& name) const;
183
184        /** Sets the current position / orientation to be the 'binding pose' ie the layout in which
185            bones were originally bound to a mesh.
186        */
187        virtual void setBindingPose(void);
188
189        /** Resets the position and orientation of all bones in this skeleton to their original binding position.
190        @remarks
191            A skeleton is bound to a mesh in a binding pose. Bone positions are then modified from this
192            position during animation. This method returns all the bones to their original position and
193            orientation.
194        @param resetManualBones If set to true, causes the state of manual bones to be reset
195            too, which is normally not done to allow the manual state to persist even
196            when keyframe animation is applied.
197        */
198        virtual void reset(bool resetManualBones = false);
199
200        /** Creates a new Animation object for animating this skeleton.
201        @param name The name of this animation
202        @param length The length of the animation in seconds
203        */
204        virtual Animation* createAnimation(const String& name, Real length);
205
206        /** Returns the named Animation object.
207                @remarks
208                        Will pick up animations in linked skeletons
209                        (@see addLinkedSkeletonAnimationSource).
210                @param name The name of the animation
211                @param linker Optional pointer to a pointer to the linked skeleton animation
212                        where this is coming from.
213                */
214        virtual Animation* getAnimation(const String& name, 
215                        const LinkedSkeletonAnimationSource** linker = 0) const;
216
217                /// Internal accessor for animations (returns null if animation does not exist)
218                virtual Animation* _getAnimationImpl(const String& name, 
219                        const LinkedSkeletonAnimationSource** linker = 0) const;
220
221
222                /** Returns whether this skeleton contains the named animation. */
223                virtual bool hasAnimation(const String& name);
224
225        /** Removes an Animation from this skeleton. */
226        virtual void removeAnimation(const String& name);
227
228        /** Changes the state of the skeleton to reflect the application of the passed in collection of animations.
229        @remarks
230            Animating a skeleton involves both interpolating between keyframes of a specific animation,
231            and blending between the animations themselves. Calling this method sets the state of
232            the skeleton so that it reflects the combination of all the passed in animations, at the
233            time index specified for each, using the weights specified. Note that the weights between
234            animations do not have to sum to 1.0, because some animations may affect only subsets
235            of the skeleton. If the weights exceed 1.0 for the same area of the skeleton, the
236            movement will just be exaggerated.
237            @param
238        */
239        virtual void setAnimationState(const AnimationStateSet& animSet);
240
241
242        /** Initialise an animation set suitable for use with this skeleton.
243        @remarks
244            Only recommended for use inside the engine, not by applications.
245        */
246        virtual void _initAnimationState(AnimationStateSet* animSet);
247
248                /** Refresh an animation set suitable for use with this skeleton.
249                @remarks
250                        Only recommended for use inside the engine, not by applications.
251                */
252                virtual void _refreshAnimationState(AnimationStateSet* animSet);
253
254                /** Populates the passed in array with the bone matrices based on the current position.
255        @remarks
256            Internal use only. The array pointed to by the passed in pointer must
257            be at least as large as the number of bones.
258            Assumes animation has already been updated.
259        */
260        virtual void _getBoneMatrices(Matrix4* pMatrices);
261
262        /** Gets the number of animations on this skeleton. */
263        virtual unsigned short getNumAnimations(void) const;
264
265        /** Gets a single animation by index.
266                @remarks
267                        Will NOT pick up animations in linked skeletons
268                        (@see addLinkedSkeletonAnimationSource).
269                */
270        virtual Animation* getAnimation(unsigned short index) const;
271
272
273                /** Gets the animation blending mode which this skeleton will use. */
274        virtual SkeletonAnimationBlendMode getBlendMode() const;
275        /** Sets the animation blending mode this skeleton will use. */
276                virtual void setBlendMode(SkeletonAnimationBlendMode state);
277
278        /// Updates all the derived transforms in the skeleton
279        virtual void _updateTransforms(void);
280
281                /** Optimise all of this skeleton's animations.
282                @see Animation::optimise
283        @param
284            preservingIdentityNodeTracks If true, don't destroy identity node tracks.
285                */
286                virtual void optimiseAllAnimations(bool preservingIdentityNodeTracks = false);
287
288                /** Allows you to use the animations from another Skeleton object to animate
289                        this skeleton.
290                @remarks
291                        If you have skeletons of identical structure (that means identically
292                        named bones with identical handles, and with the same hierarchy), but
293                        slightly different proportions or binding poses, you can re-use animations
294                        from one in the other. Because animations are actually stored as
295                        changes to bones from their bind positions, it's possible to use the
296                        same animation data for different skeletons, provided the skeletal
297                        structure matches and the 'deltas' stored in the keyframes apply
298                        equally well to the other skeletons bind position (so they must be
299                        roughly similar, but don't have to be identical). You can use the
300                        'scale' option to adjust the translation and scale keyframes where
301                        there are large differences in size between the skeletons.
302                @note
303                        This method takes a skeleton name, rather than a more specific
304                        animation name, for two reasons; firstly it allows some validation
305                        of compatibility of skeletal structure, and secondly skeletons are
306                        the unit of loading. Linking a skeleton to another in this way means
307                        that the linkee will be prevented from being destroyed until the
308                        linker is destroyed.
309
310                        You cannot set up cyclic relationships, e.g. SkeletonA uses SkeletonB's
311                        animations, and SkeletonB uses SkeletonA's animations. This is because
312                        it would set up a circular dependency which would prevent proper
313                        unloading - make one of the skeletons the 'master' in this case.
314                @param skelName Name of the skeleton to link animations from. This
315                        skeleton will be loaded immediately if this skeleton is already
316                        loaded, otherwise it will be loaded when this skeleton is.
317                @param scale A scale factor to apply to translation and scaling elements
318                        of the keyframes in the other skeleton when applying the animations
319                        to this one. Compensates for skeleton size differences.
320                */
321                virtual void addLinkedSkeletonAnimationSource(const String& skelName, 
322                        Real scale = 1.0f);
323                /// Remove all links to other skeletons for the purposes of sharing animation
324                virtual void removeAllLinkedSkeletonAnimationSources(void);
325               
326                typedef std::vector<LinkedSkeletonAnimationSource> 
327                        LinkedSkeletonAnimSourceList;
328                typedef ConstVectorIterator<LinkedSkeletonAnimSourceList> 
329                        LinkedSkeletonAnimSourceIterator;
330                /// Get an iterator over the linked skeletons used as animation sources
331                virtual LinkedSkeletonAnimSourceIterator
332                        getLinkedSkeletonAnimationSourceIterator(void) const;
333
334                /// Internal method for marking the manual bones as dirty
335                virtual void _notifyManualBonesDirty(void);
336                /// Internal method for notifying that a bone is manual
337                virtual void _notifyManualBoneStateChange(Bone* bone);
338
339                /// Have manual bones been modified since the skeleton was last updated?
340                virtual bool getManualBonesDirty(void) const { return mManualBonesDirty; }
341                /// Are there any manually controlled bones?
342                virtual bool hasManualBones(void) const { return !mManualBones.empty(); }
343
344        /// Map to translate bone handle from one skeleton to another skeleton.
345        typedef std::vector<ushort> BoneHandleMap;
346
347        /** Merge animations from another Skeleton object into this skeleton.
348        @remarks
349            This function allow merge two structures compatible skeletons. The
350            'compatible' here means identically bones will have same hierarchy,
351            but skeletons are not necessary to have same number of bones (if
352            number bones of source skeleton's more than this skeleton, they will
353            copied as is, except that duplicate names are unallowed; and in the
354            case of bones missing in source skeleton, nothing happen for those
355            bones).
356        @par
357            There are also unnecessary to have same binding poses, this function
358            will adjust keyframes of the source skeleton to match this skeleton
359            automatically.
360        @par
361            It's useful for export skeleton animations seperately. i.e. export
362            mesh and 'master' skeleton at the same time, and then other animations
363            will export seperately (even if used completely difference binding
364            pose), finally, merge seperately exported animations into 'master'
365            skeleton.
366        @param
367            source Pointer to source skeleton. It'll keep unmodified.
368        @param
369            boneHandleMap A map to translate identically bone's handle from source
370            skeleton to this skeleton. If mapped bone handle doesn't exists in this
371            skeleton, it'll created. You can populate bone handle map manually, or
372            use predefined functions build bone handle map for you. (@see
373            _buildMapBoneByHandle, _buildMapBoneByName)
374        @param
375            animations A list name of animations to merge, if empty, all animations
376            of source skeleton are used to merge. Note that the animation names
377            must not presented in this skeleton, and will NOT pick up animations
378            in linked skeletons (@see addLinkedSkeletonAnimationSource).
379        */
380        virtual void _mergeSkeletonAnimations(const Skeleton* source,
381            const BoneHandleMap& boneHandleMap,
382            const StringVector& animations = StringVector());
383
384        /** Build the bone handle map to use with Skeleton::_mergeSkeletonAnimations.
385        @remarks
386            Identically bones are determine by handle.
387        */
388        virtual void _buildMapBoneByHandle(const Skeleton* source,
389            BoneHandleMap& boneHandleMap) const;
390
391        /** Build the bone handle map to use with Skeleton::_mergeSkeletonAnimations.
392        @remarks
393            Identically bones are determine by name.
394        */
395        virtual void _buildMapBoneByName(const Skeleton* source,
396            BoneHandleMap& boneHandleMap) const;
397
398        protected:
399                SkeletonAnimationBlendMode mBlendState;
400        /// Storage of bones, indexed by bone handle
401        BoneList mBoneList;
402        /// Lookup by bone name
403        typedef std::map<String, Bone*> BoneListByName;
404        BoneListByName mBoneListByName;
405
406
407        /// Pointer to root bones (can now have multiple roots)
408        mutable BoneList mRootBones;
409        /// Bone automatic handles
410        unsigned short mNextAutoHandle;
411                typedef std::set<Bone*> BoneSet;
412                /// Manual bones
413                BoneSet mManualBones;
414                /// Manual bones dirty?
415                bool mManualBonesDirty;
416
417
418        /// Storage of animations, lookup by name
419        typedef std::map<String, Animation*> AnimationList;
420        AnimationList mAnimationsList;
421
422                /// List of references to other skeletons to use animations from
423                mutable LinkedSkeletonAnimSourceList mLinkedSkeletonAnimSourceList;
424
425        /** Internal method which parses the bones to derive the root bone.
426        @remarks
427            Must be const because called in getRootBone but mRootBone is mutable
428            since lazy-updated.
429        */
430        void deriveRootBone(void) const;
431
432        /// Debugging method
433        void _dumpContents(const String& filename);
434
435        /** @copydoc Resource::loadImpl
436        */
437        void loadImpl(void);
438
439        /** @copydoc Resource::unloadImpl
440        */
441        void unloadImpl(void);
442                /// @copydoc Resource::calculateSize
443                size_t calculateSize(void) const { return 0; } // TODO
444
445    };
446
447    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to SkeletonPtr
448    @note Has to be a subclass since we need operator=.
449    We could templatise this instead of repeating per Resource subclass,
450    except to do so requires a form VC6 does not support i.e.
451    ResourceSubclassPtr<T> : public SharedPtr<T>
452    */
453    class _OgreExport SkeletonPtr : public SharedPtr<Skeleton> 
454    {
455    public:
456        SkeletonPtr() : SharedPtr<Skeleton>() {}
457        explicit SkeletonPtr(Skeleton* rep) : SharedPtr<Skeleton>(rep) {}
458        SkeletonPtr(const SkeletonPtr& r) : SharedPtr<Skeleton>(r) {} 
459        SkeletonPtr(const ResourcePtr& r) : SharedPtr<Skeleton>()
460        {
461                        // lock & copy other mutex pointer
462            OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
463            {
464                            OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
465                            OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
466                pRep = static_cast<Skeleton*>(r.getPointer());
467                pUseCount = r.useCountPointer();
468                if (pUseCount)
469                {
470                    ++(*pUseCount);
471                }
472            }
473        }
474
475        /// Operator used to convert a ResourcePtr to a SkeletonPtr
476        SkeletonPtr& operator=(const ResourcePtr& r)
477        {
478            if (pRep == static_cast<Skeleton*>(r.getPointer()))
479                return *this;
480            release();
481                        // lock & copy other mutex pointer
482            OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
483            {
484                            OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
485                            OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
486                pRep = static_cast<Skeleton*>(r.getPointer());
487                pUseCount = r.useCountPointer();
488                if (pUseCount)
489                {
490                    ++(*pUseCount);
491                }
492            }
493                        else
494                        {
495                                // RHS must be a null pointer
496                                assert(r.isNull() && "RHS must be null if it has no mutex!");
497                                setNull();
498                        }
499            return *this;
500        }
501    };
502
503        /// Link to another skeleton to share animations
504        struct LinkedSkeletonAnimationSource
505        {
506                String skeletonName;
507                SkeletonPtr pSkeleton;
508                Real scale;
509                LinkedSkeletonAnimationSource(const String& skelName, Real scl)
510                        : skeletonName(skelName), scale(scl) {}
511                        LinkedSkeletonAnimationSource(const String& skelName, Real scl, 
512                                SkeletonPtr skelPtr)
513                                : skeletonName(skelName), pSkeleton(skelPtr), scale(scl) {}
514        };
515}
516
517
518#endif
519
Note: See TracBrowser for help on using the repository browser.