rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /** @file LWOAnimation.h
|
nuclear@0
|
42 * @brief LWOAnimationResolver utility class
|
nuclear@0
|
43 *
|
nuclear@0
|
44 * This is for all lightwave-related file format, not only LWO.
|
nuclear@0
|
45 * LWS isthe main purpose.
|
nuclear@0
|
46 */
|
nuclear@0
|
47 #ifndef AI_LWO_ANIMATION_INCLUDED
|
nuclear@0
|
48 #define AI_LWO_ANIMATION_INCLUDED
|
nuclear@0
|
49
|
nuclear@0
|
50 namespace Assimp {
|
nuclear@0
|
51 namespace LWO {
|
nuclear@0
|
52
|
nuclear@0
|
53 // ---------------------------------------------------------------------------
|
nuclear@0
|
54 /** \brief List of recognized LWO envelopes
|
nuclear@0
|
55 */
|
nuclear@0
|
56 enum EnvelopeType
|
nuclear@0
|
57 {
|
nuclear@0
|
58 EnvelopeType_Position_X = 0x1,
|
nuclear@0
|
59 EnvelopeType_Position_Y = 0x2,
|
nuclear@0
|
60 EnvelopeType_Position_Z = 0x3,
|
nuclear@0
|
61
|
nuclear@0
|
62 EnvelopeType_Rotation_Heading = 0x4,
|
nuclear@0
|
63 EnvelopeType_Rotation_Pitch = 0x5,
|
nuclear@0
|
64 EnvelopeType_Rotation_Bank = 0x6,
|
nuclear@0
|
65
|
nuclear@0
|
66 EnvelopeType_Scaling_X = 0x7,
|
nuclear@0
|
67 EnvelopeType_Scaling_Y = 0x8,
|
nuclear@0
|
68 EnvelopeType_Scaling_Z = 0x9,
|
nuclear@0
|
69
|
nuclear@0
|
70 // -- currently not yet handled
|
nuclear@0
|
71 EnvelopeType_Color_R = 0xa,
|
nuclear@0
|
72 EnvelopeType_Color_G = 0xb,
|
nuclear@0
|
73 EnvelopeType_Color_B = 0xc,
|
nuclear@0
|
74
|
nuclear@0
|
75 EnvelopeType_Falloff_X = 0xd,
|
nuclear@0
|
76 EnvelopeType_Falloff_Y = 0xe,
|
nuclear@0
|
77 EnvelopeType_Falloff_Z = 0xf,
|
nuclear@0
|
78
|
nuclear@0
|
79 EnvelopeType_Unknown
|
nuclear@0
|
80 };
|
nuclear@0
|
81
|
nuclear@0
|
82 // ---------------------------------------------------------------------------
|
nuclear@0
|
83 /** \brief List of recognized LWO interpolation modes
|
nuclear@0
|
84 */
|
nuclear@0
|
85 enum InterpolationType
|
nuclear@0
|
86 {
|
nuclear@0
|
87 IT_STEP, IT_LINE, IT_TCB, IT_HERM, IT_BEZI, IT_BEZ2
|
nuclear@0
|
88 };
|
nuclear@0
|
89
|
nuclear@0
|
90
|
nuclear@0
|
91 // ---------------------------------------------------------------------------
|
nuclear@0
|
92 /** \brief List of recognized LWO pre or post range behaviours
|
nuclear@0
|
93 */
|
nuclear@0
|
94 enum PrePostBehaviour
|
nuclear@0
|
95 {
|
nuclear@0
|
96 PrePostBehaviour_Reset = 0x0,
|
nuclear@0
|
97 PrePostBehaviour_Constant = 0x1,
|
nuclear@0
|
98 PrePostBehaviour_Repeat = 0x2,
|
nuclear@0
|
99 PrePostBehaviour_Oscillate = 0x3,
|
nuclear@0
|
100 PrePostBehaviour_OffsetRepeat = 0x4,
|
nuclear@0
|
101 PrePostBehaviour_Linear = 0x5
|
nuclear@0
|
102 };
|
nuclear@0
|
103
|
nuclear@0
|
104 // ---------------------------------------------------------------------------
|
nuclear@0
|
105 /** \brief Data structure for a LWO animation keyframe
|
nuclear@0
|
106 */
|
nuclear@0
|
107 struct Key
|
nuclear@0
|
108 {
|
nuclear@0
|
109 Key()
|
nuclear@0
|
110 : inter (IT_LINE)
|
nuclear@0
|
111 {}
|
nuclear@0
|
112
|
nuclear@0
|
113 //! Current time
|
nuclear@0
|
114 double time;
|
nuclear@0
|
115
|
nuclear@0
|
116 //! Current value
|
nuclear@0
|
117 float value;
|
nuclear@0
|
118
|
nuclear@0
|
119 //! How to interpolate this key with previous key?
|
nuclear@0
|
120 InterpolationType inter;
|
nuclear@0
|
121
|
nuclear@0
|
122 //! Interpolation parameters
|
nuclear@0
|
123 float params[5];
|
nuclear@0
|
124
|
nuclear@0
|
125
|
nuclear@0
|
126 // for std::find()
|
nuclear@0
|
127 operator double () {
|
nuclear@0
|
128 return time;
|
nuclear@0
|
129 }
|
nuclear@0
|
130 };
|
nuclear@0
|
131
|
nuclear@0
|
132 // ---------------------------------------------------------------------------
|
nuclear@0
|
133 /** \brief Data structure for a LWO animation envelope
|
nuclear@0
|
134 */
|
nuclear@0
|
135 struct Envelope
|
nuclear@0
|
136 {
|
nuclear@0
|
137 Envelope()
|
nuclear@0
|
138 : type (EnvelopeType_Unknown)
|
nuclear@0
|
139 , pre (PrePostBehaviour_Constant)
|
nuclear@0
|
140 , post (PrePostBehaviour_Constant)
|
nuclear@0
|
141
|
nuclear@0
|
142 , old_first (0)
|
nuclear@0
|
143 , old_last (0)
|
nuclear@0
|
144 {}
|
nuclear@0
|
145
|
nuclear@0
|
146 //! Index of this envelope
|
nuclear@0
|
147 unsigned int index;
|
nuclear@0
|
148
|
nuclear@0
|
149 //! Type of envelope
|
nuclear@0
|
150 EnvelopeType type;
|
nuclear@0
|
151
|
nuclear@0
|
152 //! Pre and post-behaviour
|
nuclear@0
|
153 PrePostBehaviour pre,post;
|
nuclear@0
|
154
|
nuclear@0
|
155 //! Keyframes for this envelope
|
nuclear@0
|
156 std::vector<Key> keys;
|
nuclear@0
|
157
|
nuclear@0
|
158
|
nuclear@0
|
159 // temporary data for AnimResolver
|
nuclear@0
|
160 size_t old_first,old_last;
|
nuclear@0
|
161 };
|
nuclear@0
|
162
|
nuclear@0
|
163 // ---------------------------------------------------------------------------
|
nuclear@0
|
164 //! @def AI_LWO_ANIM_FLAG_SAMPLE_ANIMS
|
nuclear@0
|
165 //! Flag for AnimResolver, subsamples the input data with the rate specified
|
nuclear@0
|
166 //! by AnimResolver::SetSampleRate().
|
nuclear@0
|
167 #define AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 0x1
|
nuclear@0
|
168
|
nuclear@0
|
169
|
nuclear@0
|
170 // ---------------------------------------------------------------------------
|
nuclear@0
|
171 //! @def AI_LWO_ANIM_FLAG_START_AT_ZERO
|
nuclear@0
|
172 //! Flag for AnimResolver, ensures that the animations starts at zero.
|
nuclear@0
|
173 #define AI_LWO_ANIM_FLAG_START_AT_ZERO 0x2
|
nuclear@0
|
174
|
nuclear@0
|
175 // ---------------------------------------------------------------------------
|
nuclear@0
|
176 /** @brief Utility class to build Assimp animations from LWO envelopes.
|
nuclear@0
|
177 *
|
nuclear@0
|
178 * Used for both LWO and LWS (MOT also).
|
nuclear@0
|
179 */
|
nuclear@0
|
180 class AnimResolver
|
nuclear@0
|
181 {
|
nuclear@0
|
182 public:
|
nuclear@0
|
183
|
nuclear@0
|
184 // ------------------------------------------------------------------
|
nuclear@0
|
185 /** @brief Construct an AnimResolver from a given list of envelopes
|
nuclear@0
|
186 * @param envelopes Input envelopes. May be empty.
|
nuclear@0
|
187 * @param Output tick rate, per second
|
nuclear@0
|
188 * @note The input envelopes are possibly modified.
|
nuclear@0
|
189 */
|
nuclear@0
|
190 AnimResolver(std::list<Envelope>& envelopes,
|
nuclear@0
|
191 double tick);
|
nuclear@0
|
192
|
nuclear@0
|
193 public:
|
nuclear@0
|
194
|
nuclear@0
|
195 // ------------------------------------------------------------------
|
nuclear@0
|
196 /** @brief Extract the bind-pose transformation matrix.
|
nuclear@0
|
197 * @param out Receives bind-pose transformation matrix
|
nuclear@0
|
198 */
|
nuclear@0
|
199 void ExtractBindPose(aiMatrix4x4& out);
|
nuclear@0
|
200
|
nuclear@0
|
201 // ------------------------------------------------------------------
|
nuclear@0
|
202 /** @brief Extract a node animation channel
|
nuclear@0
|
203 * @param out Receives a pointer to a newly allocated node anim.
|
nuclear@0
|
204 * If there's just one keyframe defined, *out is set to NULL and
|
nuclear@0
|
205 * no animation channel is computed.
|
nuclear@0
|
206 * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
|
nuclear@0
|
207 */
|
nuclear@0
|
208 void ExtractAnimChannel(aiNodeAnim** out, unsigned int flags = 0);
|
nuclear@0
|
209
|
nuclear@0
|
210
|
nuclear@0
|
211 // ------------------------------------------------------------------
|
nuclear@0
|
212 /** @brief Set the sampling rate for ExtractAnimChannel().
|
nuclear@0
|
213 *
|
nuclear@0
|
214 * Non-linear interpolations are subsampled with this rate (keys
|
nuclear@0
|
215 * per second). Closer sampling positions, if existent, are kept.
|
nuclear@0
|
216 * The sampling rate defaults to 0, if this value is not changed and
|
nuclear@0
|
217 * AI_LWO_ANIM_FLAG_SAMPLE_ANIMS is specified for ExtractAnimChannel(),
|
nuclear@0
|
218 * the class finds a suitable sample rate by itself.
|
nuclear@0
|
219 */
|
nuclear@0
|
220 void SetSampleRate(double sr) {
|
nuclear@0
|
221 sample_rate = sr;
|
nuclear@0
|
222 }
|
nuclear@0
|
223
|
nuclear@0
|
224 // ------------------------------------------------------------------
|
nuclear@0
|
225 /** @brief Getter for SetSampleRate()
|
nuclear@0
|
226 */
|
nuclear@0
|
227 double GetSampleRate() const {
|
nuclear@0
|
228 return sample_rate;
|
nuclear@0
|
229 }
|
nuclear@0
|
230
|
nuclear@0
|
231 // ------------------------------------------------------------------
|
nuclear@0
|
232 /** @brief Set the animation time range
|
nuclear@0
|
233 *
|
nuclear@0
|
234 * @param first Time where the animation starts, in ticks
|
nuclear@0
|
235 * @param last Time where the animation ends, in ticks
|
nuclear@0
|
236 */
|
nuclear@0
|
237 void SetAnimationRange(double _first, double _last) {
|
nuclear@0
|
238 first = _first;
|
nuclear@0
|
239 last = _last;
|
nuclear@0
|
240
|
nuclear@0
|
241 ClearAnimRangeSetup();
|
nuclear@0
|
242 UpdateAnimRangeSetup();
|
nuclear@0
|
243 }
|
nuclear@0
|
244
|
nuclear@0
|
245 protected:
|
nuclear@0
|
246
|
nuclear@0
|
247 // ------------------------------------------------------------------
|
nuclear@0
|
248 /** @brief Build linearly subsampled keys from 3 single envelopes
|
nuclear@0
|
249 * @param out Receives output keys
|
nuclear@0
|
250 * @param envl_x X-component envelope
|
nuclear@0
|
251 * @param envl_y Y-component envelope
|
nuclear@0
|
252 * @param envl_z Z-component envelope
|
nuclear@0
|
253 * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
|
nuclear@0
|
254 * @note Up to two input envelopes may be NULL
|
nuclear@0
|
255 */
|
nuclear@0
|
256 void GetKeys(std::vector<aiVectorKey>& out,
|
nuclear@0
|
257 LWO::Envelope* envl_x,
|
nuclear@0
|
258 LWO::Envelope* envl_y,
|
nuclear@0
|
259 LWO::Envelope* envl_z,
|
nuclear@0
|
260 unsigned int flags);
|
nuclear@0
|
261
|
nuclear@0
|
262 // ------------------------------------------------------------------
|
nuclear@0
|
263 /** @brief Resolve a single animation key by applying the right
|
nuclear@0
|
264 * interpolation to it.
|
nuclear@0
|
265 * @param cur Current key
|
nuclear@0
|
266 * @param envl Envelope working on
|
nuclear@0
|
267 * @param time time to be interpolated
|
nuclear@0
|
268 * @param fill Receives the interpolated output value.
|
nuclear@0
|
269 */
|
nuclear@0
|
270 void DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
|
nuclear@0
|
271 LWO::Envelope* envl,double time, float& fill);
|
nuclear@0
|
272
|
nuclear@0
|
273 // ------------------------------------------------------------------
|
nuclear@0
|
274 /** @brief Almost the same, except we won't handle pre/post
|
nuclear@0
|
275 * conditions here.
|
nuclear@0
|
276 * @see DoInterpolation
|
nuclear@0
|
277 */
|
nuclear@0
|
278 void DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
|
nuclear@0
|
279 std::vector<LWO::Key>::const_iterator end,double time, float& fill);
|
nuclear@0
|
280
|
nuclear@0
|
281 // ------------------------------------------------------------------
|
nuclear@0
|
282 /** @brief Interpolate 2 tracks if one is given
|
nuclear@0
|
283 *
|
nuclear@0
|
284 * @param out Receives extra output keys
|
nuclear@0
|
285 * @param key_out Primary output key
|
nuclear@0
|
286 * @param time Time to interpolate for
|
nuclear@0
|
287 */
|
nuclear@0
|
288 void InterpolateTrack(std::vector<aiVectorKey>& out,
|
nuclear@0
|
289 aiVectorKey& key_out,double time);
|
nuclear@0
|
290
|
nuclear@0
|
291 // ------------------------------------------------------------------
|
nuclear@0
|
292 /** @brief Subsample an animation track by a given sampling rate
|
nuclear@0
|
293 *
|
nuclear@0
|
294 * @param out Receives output keys. Last key at input defines the
|
nuclear@0
|
295 * time where subsampling starts.
|
nuclear@0
|
296 * @param time Time to end subsampling at
|
nuclear@0
|
297 * @param sample_delta Time delta between two samples
|
nuclear@0
|
298 */
|
nuclear@0
|
299 void SubsampleAnimTrack(std::vector<aiVectorKey>& out,
|
nuclear@0
|
300 double time,double sample_delta);
|
nuclear@0
|
301
|
nuclear@0
|
302 // ------------------------------------------------------------------
|
nuclear@0
|
303 /** @brief Delete all keys which we inserted to match anim setup
|
nuclear@0
|
304 */
|
nuclear@0
|
305 void ClearAnimRangeSetup();
|
nuclear@0
|
306
|
nuclear@0
|
307 // ------------------------------------------------------------------
|
nuclear@0
|
308 /** @brief Insert extra keys to match LWO's pre and post behaviours
|
nuclear@0
|
309 * in a given time range [first...last]
|
nuclear@0
|
310 */
|
nuclear@0
|
311 void UpdateAnimRangeSetup();
|
nuclear@0
|
312
|
nuclear@0
|
313 private:
|
nuclear@0
|
314 std::list<Envelope>& envelopes;
|
nuclear@0
|
315 double sample_rate;
|
nuclear@0
|
316
|
nuclear@0
|
317 LWO::Envelope* trans_x, *trans_y, *trans_z;
|
nuclear@0
|
318 LWO::Envelope* rotat_x, *rotat_y, *rotat_z;
|
nuclear@0
|
319 LWO::Envelope* scale_x, *scale_y, *scale_z;
|
nuclear@0
|
320
|
nuclear@0
|
321 double first, last;
|
nuclear@0
|
322 bool need_to_setup;
|
nuclear@0
|
323
|
nuclear@0
|
324 // temporary storage
|
nuclear@0
|
325 LWO::Envelope* envl_x, * envl_y, * envl_z;
|
nuclear@0
|
326 std::vector<LWO::Key>::const_iterator cur_x,cur_y,cur_z;
|
nuclear@0
|
327 bool end_x, end_y, end_z;
|
nuclear@0
|
328
|
nuclear@0
|
329 unsigned int flags;
|
nuclear@0
|
330 double sample_delta;
|
nuclear@0
|
331 };
|
nuclear@0
|
332
|
nuclear@0
|
333 } // end namespace LWO
|
nuclear@0
|
334 } // end namespace Assimp
|
nuclear@0
|
335
|
nuclear@0
|
336 #endif // !! AI_LWO_ANIMATION_INCLUDED
|