/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 | | |