Coverage Report

Created: 2025-11-11 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/include/OgreAnimationState.h
Line
Count
Source
1
/*
2
-----------------------------------------------------------------------------
3
This source file is part of OGRE
4
    (Object-oriented Graphics Rendering Engine)
5
For the latest info, see http://www.ogre3d.org/
6
7
Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
THE SOFTWARE.
26
-----------------------------------------------------------------------------
27
*/
28
29
#ifndef __AnimationState_H__
30
#define __AnimationState_H__
31
32
#include "OgrePrerequisites.h"
33
34
#include "OgreCommon.h"
35
#include "OgreController.h"
36
#include "OgreControllerManager.h"
37
#include "Threading/OgreThreadHeaders.h"
38
#include "OgreHeaderPrefix.h"
39
40
namespace Ogre {
41
42
    template <typename T> class MapIterator;
43
    template <typename T> class ConstMapIterator;
44
    template <typename T> class ConstVectorIterator;
45
46
    /** \addtogroup Core
47
    *  @{
48
    */
49
    /** \addtogroup Animation
50
    *  @{
51
    */
52
53
    /** Represents the state of an animation and the weight of its influence. 
54
55
        Other classes can hold instances of this class to store the state of any animations
56
        they are using.
57
    */
58
    class _OgreExport AnimationState : public AnimationAlloc
59
    {
60
    public:
61
62
        /// Typedef for an array of float values used as a bone blend mask
63
        typedef std::vector<float> BoneBlendMask;
64
65
        /** Normal constructor with all params supplied
66
            @param
67
                animName The name of this state.
68
            @param
69
                parent The parent AnimationStateSet that this state will belong to.
70
            @param
71
                timePos The position, in seconds, where this state will begin.
72
            @param
73
                length The length, in seconds, of this animation state.
74
            @param
75
                weight Weight to apply the animation state with.
76
            @param
77
                enabled Whether the animation state is enabled.
78
        */
79
        AnimationState(const String& animName, AnimationStateSet *parent, 
80
            Real timePos, Real length, Real weight = 1.0, bool enabled = false);
81
        /// Constructor to copy from an existing state with new parent
82
        AnimationState(AnimationStateSet* parent, const AnimationState &rhs);
83
        
84
        /// Gets the name of the animation to which this state applies
85
        const String& getAnimationName() const;
86
        /// Gets the time position for this animation
87
        Real getTimePosition(void) const;
88
        /// Sets the time position for this animation
89
        void setTimePosition(Real timePos);
90
        /// Gets the total length of this animation (may be shorter than whole animation)
91
        Real getLength() const;
92
        /// Sets the total length of this animation (may be shorter than whole animation)
93
        void setLength(Real len);
94
        /// Gets the weight (influence) of this animation
95
        Real getWeight(void) const;
96
        /// Sets the weight (influence) of this animation
97
        void setWeight(Real weight);
98
        /** Modifies the time position, adjusting for animation length
99
        @param offset The amount of time, in seconds, to extend the animation.
100
101
        This method loops at the edges if animation looping is enabled.
102
        */
103
        void addTime(Real offset);
104
105
        /// Returns true if the animation has reached the end and is not looping
106
        bool hasEnded(void) const;
107
108
        /// Returns true if this animation is currently enabled
109
        bool getEnabled(void) const;
110
        /// Sets whether this animation is enabled
111
        void setEnabled(bool enabled);
112
113
        /// Equality operator
114
        bool operator==(const AnimationState& rhs) const;
115
        /// Inequality operator
116
        bool operator!=(const AnimationState& rhs) const;
117
118
        /** Sets whether or not an animation loops at the start and end of
119
            the animation if the time continues to be altered.
120
        */
121
0
        void setLoop(bool loop) { mLoop = loop; }
122
        /// Gets whether or not this animation loops            
123
0
        bool getLoop(void) const { return mLoop; }
124
     
125
        /** Copies the states from another animation state, preserving the animation name
126
        (unlike operator=) but copying everything else.
127
        @param animState Reference to animation state which will use as source.
128
        */
129
        void copyStateFrom(const AnimationState& animState);
130
131
        /// Get the parent animation state set
132
0
        AnimationStateSet* getParent(void) const { return mParent; }
133
134
      /** @brief Create a new blend mask with the given number of entries
135
       *
136
       * In addition to assigning a single weight value to a skeletal animation,
137
       * it may be desirable to assign animation weights per bone using a 'blend mask'.
138
       *
139
       * @param blendMaskSizeHint 
140
       *   The number of bones of the skeleton owning this AnimationState.
141
       * @param initialWeight
142
       *   The value all the blend mask entries will be initialised with (negative to skip initialisation)
143
       */
144
      void createBlendMask(size_t blendMaskSizeHint, float initialWeight = 1.0f);
145
      /// Destroy the currently set blend mask
146
      void destroyBlendMask();
147
148
      /** @brief Set the blend mask
149
       *
150
       * @par The size of the array should match the number of entries the
151
       *      blend mask was created with.
152
       *
153
       * @par Stick to the setBlendMaskEntry method if you don't know exactly what you're doing.
154
       */
155
      void _setBlendMask(const BoneBlendMask* blendMask);
156
      /// Get the current blend mask
157
0
      const BoneBlendMask* getBlendMask() const {return &mBlendMask;}
158
      /// Return whether there is currently a valid blend mask set
159
0
      bool hasBlendMask() const {return !mBlendMask.empty();}
160
      /// Set the weight for the bone identified by the given handle
161
      void setBlendMaskEntry(size_t boneHandle, float weight);
162
      /// Get the weight for the bone identified by the given handle
163
      inline float getBlendMaskEntry(size_t boneHandle) const
164
0
      {
165
0
          assert(mBlendMask.size() > boneHandle);
166
0
          return mBlendMask[boneHandle];
167
0
      }
168
    private:
169
        /** @brief Set the blend mask data (might be dangerous)
170
         *
171
         * @par The size of the array should match the number of entries the
172
         *      blend mask was created with.
173
         *
174
         * @par Stick to the setBlendMaskEntry method if you don't know exactly what you're doing.
175
         */
176
        void _setBlendMaskData(const float* blendMaskData);
177
        /// The blend mask (containing per bone weights)
178
        BoneBlendMask mBlendMask;
179
180
        String mAnimationName;
181
        AnimationStateSet* mParent;
182
        Real mTimePos;
183
        Real mLength;
184
        Real mWeight;
185
        bool mEnabled;
186
        bool mLoop;
187
188
    };
189
190
    // A map of animation states
191
    typedef std::map<String, AnimationState*> AnimationStateMap;
192
    typedef MapIterator<AnimationStateMap> AnimationStateIterator;
193
    typedef ConstMapIterator<AnimationStateMap> ConstAnimationStateIterator;
194
    // A list of enabled animation states
195
    typedef std::list<AnimationState*> EnabledAnimationStateList;
196
    typedef ConstVectorIterator<EnabledAnimationStateList> ConstEnabledAnimationStateIterator;
197
198
    /** Class encapsulating a set of AnimationState objects.
199
    */
200
    class _OgreExport AnimationStateSet : public AnimationAlloc
201
    {
202
    public:
203
        /// Mutex, public for external locking if needed
204
            OGRE_AUTO_MUTEX;
205
        /// Create a blank animation state set
206
        AnimationStateSet();
207
        /// Create an animation set by copying the contents of another
208
        AnimationStateSet(const AnimationStateSet& rhs);
209
210
        ~AnimationStateSet();
211
212
        /** Create a new AnimationState instance. 
213
        @param animName The name of the animation
214
        @param timePos Starting time position
215
        @param length Length of the animation to play
216
        @param weight Weight to apply the animation with 
217
        @param enabled Whether the animation is enabled
218
        */
219
        AnimationState* createAnimationState(const String& animName,  
220
            Real timePos, Real length, Real weight = 1.0, bool enabled = false);
221
        /// Get an animation state by the name of the animation
222
        AnimationState* getAnimationState(const String& name) const;
223
        /// Tests if state for the named animation is present
224
        bool hasAnimationState(const String& name) const;
225
        /// Remove animation state with the given name
226
        void removeAnimationState(const String& name);
227
        /// Remove all animation states
228
        void removeAllAnimationStates(void);
229
230
        /** Get an iterator over all the animation states in this set.
231
        @deprecated use getAnimationStates()
232
        */
233
        AnimationStateIterator getAnimationStateIterator(void);
234
        /** Get an iterator over all the animation states in this set.
235
        @deprecated use getAnimationStates()
236
        */
237
        OGRE_DEPRECATED ConstAnimationStateIterator getAnimationStateIterator(void) const;
238
239
        /** Get all the animation states in this set.
240
        @note
241
            This method is not threadsafe,
242
            you will need to manually lock the public mutex on this
243
            class to ensure thread safety if you need it.
244
        */
245
0
        const AnimationStateMap& getAnimationStates() const {
246
0
            return mAnimationStates;
247
0
        }
248
249
        /// Copy the state of any matching animation states from this to another
250
        void copyMatchingState(AnimationStateSet* target) const;
251
        /// Set the dirty flag and dirty frame number on this state set
252
        void _notifyDirty(void);
253
        /// Get the latest animation state been altered frame number
254
0
        unsigned long getDirtyFrameNumber(void) const { return mDirtyFrameNumber; }
255
256
        /// Internal method respond to enable/disable an animation state
257
        void _notifyAnimationStateEnabled(AnimationState* target, bool enabled);
258
        /// Tests if exists enabled animation state in this set
259
0
        bool hasEnabledAnimationState(void) const { return !mEnabledAnimationStates.empty(); }
260
        /** Get an iterator over all the enabled animation states in this set
261
        @deprecated use getEnabledAnimationStates()
262
        */
263
        OGRE_DEPRECATED ConstEnabledAnimationStateIterator getEnabledAnimationStateIterator(void) const;
264
265
        /** Get an iterator over all the enabled animation states in this set
266
        @note
267
            The iterator returned from this method is not threadsafe,
268
            you will need to manually lock the public mutex on this
269
            class to ensure thread safety if you need it.
270
        */
271
0
        const EnabledAnimationStateList& getEnabledAnimationStates() const {
272
0
            return mEnabledAnimationStates;
273
0
        }
274
275
    private:
276
        unsigned long mDirtyFrameNumber;
277
        AnimationStateMap mAnimationStates;
278
        EnabledAnimationStateList mEnabledAnimationStates;
279
280
    };
281
282
    /** ControllerValue wrapper class for AnimationState.
283
284
        In Azathoth and earlier, AnimationState was a ControllerValue but this
285
        actually causes memory problems since Controllers delete their values
286
        automatically when there are no further references to them, but AnimationState
287
        is deleted explicitly elsewhere so this causes double-free problems.
288
        This wrapper acts as a bridge and it is this which is destroyed automatically.
289
    */
290
    class _OgreExport AnimationStateControllerValue : public ControllerValue<float>
291
    {
292
    private:
293
        AnimationState* mTargetAnimationState;
294
        bool mAddTime;
295
    public:
296
        /// @deprecated use create instead
297
        AnimationStateControllerValue(AnimationState* targetAnimationState, bool addTime = false)
298
0
            : mTargetAnimationState(targetAnimationState), mAddTime(addTime) {}
299
300
        /**
301
         * create an instance of this class
302
         * @param targetAnimationState
303
         * @param addTime if true, increment time instead of setting to an absolute position
304
         */
305
        static ControllerValueRealPtr create(AnimationState* targetAnimationState, bool addTime = false);
306
307
        /** ControllerValue implementation. */
308
        float getValue(void) const override
309
0
        {
310
0
            return mTargetAnimationState->getTimePosition() / mTargetAnimationState->getLength();
311
0
        }
312
313
        /** ControllerValue implementation. */
314
        void setValue(float value) override
315
0
        {
316
0
            if(mAddTime)
317
0
                mTargetAnimationState->addTime(value);
318
0
            else
319
0
                mTargetAnimationState->setTimePosition(value * mTargetAnimationState->getLength());
320
0
        }
321
    };
322
323
    /** @} */   
324
    /** @} */
325
}
326
327
#include "OgreHeaderSuffix.h"
328
329
#endif
330