~ubuntu-branches/ubuntu/wily/opencollada/wily

« back to all changes in this revision

Viewing changes to COLLADAMax/src/COLLADAMaxAnimationImporter.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2008-2009 NetAllied Systems GmbH
 
3
 
 
4
This file is part of COLLADAMax.
 
5
 
 
6
Portions of the code are:
 
7
Copyright (c) 2005-2007 Feeling Software Inc.
 
8
Copyright (c) 2005-2007 Sony Computer Entertainment America
 
9
 
 
10
Based on the 3dsMax COLLADASW Tools:
 
11
Copyright (c) 2005-2006 Autodesk Media Entertainment
 
12
 
 
13
Licensed under the MIT Open Source License, 
 
14
for details please see LICENSE file or the website
 
15
http://www.opensource.org/licenses/mit-license.php
 
16
*/
 
17
 
 
18
#include "COLLADAMaxStableHeaders.h"
 
19
#include "COLLADAMaxAnimationImporter.h"
 
20
 
 
21
#include "COLLADAFWAnimation.h"
 
22
 
 
23
 
 
24
namespace COLLADAMax
 
25
{
 
26
 
 
27
        //------------------------------
 
28
        inline int frameWorkInterpolationToMaxInterpolation(COLLADAFW::AnimationCurve::InterpolationType interpolationType)
 
29
        {
 
30
                switch (interpolationType)
 
31
                {
 
32
                case COLLADAFW::AnimationCurve::INTERPOLATION_STEP: 
 
33
                        return BEZKEY_STEP;
 
34
                case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: 
 
35
                        return BEZKEY_LINEAR;
 
36
                default: 
 
37
                        return BEZKEY_USER;
 
38
                }
 
39
        }
 
40
 
 
41
    //------------------------------
 
42
        AnimationImporter::AnimationImporter( DocumentImporter* documentImporter, const COLLADAFW::Animation* animation )
 
43
                : AnimationCreator(documentImporter)
 
44
                , mAnimation(animation)
 
45
                , mUnitConversionFunctors(getUnitConversionFunctors())
 
46
        {
 
47
        }
 
48
        
 
49
    //------------------------------
 
50
        AnimationImporter::~AnimationImporter()
 
51
        {
 
52
        }
 
53
 
 
54
        ConversionFunctor* AnimationImporter::getConversionFunctorByPhysicalDimension( COLLADAFW::PhysicalDimension physicalDimension )
 
55
        {
 
56
                switch ( physicalDimension )
 
57
                {
 
58
                case COLLADAFW::PHYSICAL_DIMENSION_LENGTH:
 
59
                        return mUnitConversionFunctors.lengthConversion;
 
60
                case COLLADAFW::PHYSICAL_DIMENSION_ANGLE:
 
61
                        return mUnitConversionFunctors.angleConversion;
 
62
                case COLLADAFW::PHYSICAL_DIMENSION_TIME:
 
63
                        return mUnitConversionFunctors.timeConversion;
 
64
                }
 
65
                return 0;
 
66
        }
 
67
 
 
68
        //------------------------------
 
69
        bool AnimationImporter::import()
 
70
        {
 
71
                // We only support curves
 
72
                if ( mAnimation->getAnimationType() != COLLADAFW::Animation::ANIMATION_CURVE )
 
73
                        return true;
 
74
 
 
75
                const COLLADAFW::UniqueId& animationUniqueId = mAnimation->getUniqueId();
 
76
 
 
77
                COLLADAFW::AnimationCurve* animationCurve = (COLLADAFW::AnimationCurve*)mAnimation;
 
78
                
 
79
                size_t dimensions = animationCurve->getOutDimension();
 
80
 
 
81
                if ( dimensions == 16 )
 
82
                {
 
83
                        //Special case of a matrix
 
84
                        if ( animationCurve->getInterpolationType() != COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR )
 
85
                        {
 
86
                                // we only support linearly interpolated matrices
 
87
                                return true;
 
88
                        }
 
89
                        Control* maxController = createAndFillMaxTransformationController( animationCurve );
 
90
                        addMaxControllerToAnimationUniqueId( animationUniqueId, maxController);
 
91
                }
 
92
                else
 
93
                {
 
94
                        for ( size_t i = 0; i < dimensions; ++i)
 
95
                        {
 
96
                                Control* maxController = createAndFillMaxFloatController( animationCurve, i);
 
97
                                addMaxControllerToAnimationUniqueId( animationUniqueId, maxController);
 
98
                        }
 
99
                }
 
100
                return true;
 
101
        }
 
102
 
 
103
        //------------------------------
 
104
        Control* AnimationImporter::createAndFillMaxFloatController( COLLADAFW::AnimationCurve* animationCurve, size_t dimension )
 
105
        {
 
106
                COLLADAFW::AnimationCurve::InterpolationType interpolationType = animationCurve->getInterpolationType();
 
107
                bool isLinear = (interpolationType ==  COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR);
 
108
 
 
109
                Control* maxController = createMaxFloatController( animationCurve, isLinear );
 
110
                if ( !maxController )
 
111
                        return 0;
 
112
 
 
113
                IKeyControl* maxKeyController = GetKeyControlInterface( maxController );
 
114
 
 
115
                fillMaxFloatController( maxKeyController, animationCurve, dimension, isLinear);
 
116
 
 
117
                return maxController;
 
118
        }
 
119
 
 
120
        //------------------------------
 
121
        bool AnimationImporter::fillMaxFloatController( IKeyControl* maxKeyController, COLLADAFW::AnimationCurve* animationCurve, size_t dimension, bool isLinear )
 
122
        {
 
123
                // Fill in the controller with the animation data from the curve
 
124
                size_t keyCount = animationCurve->getKeyCount();
 
125
                size_t dimensions = animationCurve->getOutDimension();
 
126
 
 
127
                assert( dimension <= dimensions);
 
128
 
 
129
                maxKeyController->SetNumKeys((int) keyCount);
 
130
 
 
131
                const COLLADAFW::FloatOrDoubleArray& inputValues = animationCurve->getInputValues();
 
132
                COLLADAFW::FloatOrDoubleArray::DataType inputValuesDataType = inputValues.getType();
 
133
 
 
134
                const COLLADAFW::FloatOrDoubleArray& outputValues = animationCurve->getOutputValues();
 
135
                COLLADAFW::FloatOrDoubleArray::DataType outputValuesDataType = outputValues.getType();
 
136
 
 
137
                ConversionFunctor* inputConversionFunctor = getConversionFunctorByPhysicalDimension( animationCurve->getInPhysicalDimension() );
 
138
                ConversionFunctor* outputConversionFunctor = getConversionFunctorByPhysicalDimension( animationCurve->getOutPhysicalDimensions()[dimension]);
 
139
 
 
140
                if ( isLinear )
 
141
                {
 
142
                        if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
143
                        {
 
144
                                if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
145
                                {
 
146
                                        fillLinearMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), inputConversionFunctor, outputConversionFunctor);
 
147
                                }
 
148
                                else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
149
                                {
 
150
                                        fillLinearMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), inputConversionFunctor, outputConversionFunctor);
 
151
                                }
 
152
                        }
 
153
                        else if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT )
 
154
                        {
 
155
                                if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
156
                                {
 
157
                                        fillLinearMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), inputConversionFunctor, outputConversionFunctor);
 
158
                                }
 
159
                                else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
160
                                {
 
161
                                        fillLinearMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getFloatValues(), inputConversionFunctor, outputConversionFunctor);
 
162
                                }
 
163
                        }
 
164
                }
 
165
                else
 
166
                {
 
167
                        const COLLADAFW::AnimationCurve::InterpolationTypeArray& interpolationTypes = animationCurve->getInterpolationTypes();
 
168
                        COLLADAFW::AnimationCurve::InterpolationType interpolationType = animationCurve->getInterpolationType();
 
169
 
 
170
                        const COLLADAFW::FloatOrDoubleArray& inTangentValues = animationCurve->getInTangentValues();
 
171
                        COLLADAFW::FloatOrDoubleArray::DataType inTangentValuesDataType = inTangentValues.getType();
 
172
 
 
173
                        const COLLADAFW::FloatOrDoubleArray& outTangentValues = animationCurve->getOutTangentValues();
 
174
                        COLLADAFW::FloatOrDoubleArray::DataType outTangentValuesDataType = outTangentValues.getType();
 
175
 
 
176
 
 
177
                        if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
178
                        {
 
179
                                if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
180
                                {
 
181
                                        if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
182
                                        {
 
183
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
184
                                                {
 
185
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
186
                                                }
 
187
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
188
                                                {
 
189
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
190
                                                }
 
191
                                        }
 
192
                                        else if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
193
                                        {
 
194
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
195
                                                {
 
196
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), *inTangentValues.getFloatValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
197
                                                }
 
198
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
199
                                                {
 
200
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), *inTangentValues.getFloatValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
201
                                                }
 
202
                                        }
 
203
                                }
 
204
                                else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
205
                                {
 
206
                                        if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
207
                                        {
 
208
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
209
                                                {
 
210
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
211
                                                }
 
212
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
213
                                                {
 
214
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
215
                                                }
 
216
                                        }
 
217
                                        else if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
218
                                        {
 
219
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
220
                                                {
 
221
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), *inTangentValues.getFloatValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
222
                                                }
 
223
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
224
                                                {
 
225
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), *inTangentValues.getFloatValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
226
                                                }
 
227
                                        }
 
228
                                }
 
229
                        }
 
230
                        else if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT )
 
231
                        {
 
232
                                if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
233
                                {
 
234
                                        if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
235
                                        {
 
236
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
237
                                                {
 
238
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
239
                                                }
 
240
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
241
                                                {
 
242
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
243
                                                }
 
244
                                        }
 
245
                                        else if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
246
                                        {
 
247
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
248
                                                {
 
249
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), *inTangentValues.getFloatValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
250
                                                }
 
251
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
252
                                                {
 
253
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), *inTangentValues.getFloatValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
254
                                                }
 
255
                                        }
 
256
                                }
 
257
                                else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
258
                                {
 
259
                                        if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
260
                                        {
 
261
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
262
                                                {
 
263
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getFloatValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
264
                                                }
 
265
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
266
                                                {
 
267
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getFloatValues(), *inTangentValues.getDoubleValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
268
                                                }
 
269
                                        }
 
270
                                        else if ( inTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
271
                                        {
 
272
                                                if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
273
                                                {
 
274
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getFloatValues(), *inTangentValues.getFloatValues(), *outTangentValues.getDoubleValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
275
                                                }
 
276
                                                else if ( outTangentValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
277
                                                {
 
278
                                                        fillBezierMaxFloatController( maxKeyController, keyCount, dimensions, dimension, *inputValues.getFloatValues(), *outputValues.getFloatValues(), *inTangentValues.getFloatValues(), *outTangentValues.getFloatValues(), interpolationType, interpolationTypes, inputConversionFunctor, outputConversionFunctor);
 
279
                                                }
 
280
                                        }
 
281
                                }
 
282
                        }
 
283
                }
 
284
                
 
285
                maxKeyController->SortKeys();
 
286
                return true;
 
287
        }
 
288
 
 
289
        //------------------------------
 
290
        template<class InputArrayType, class OutputArrayType> 
 
291
        bool AnimationImporter::fillLinearMaxFloatController( IKeyControl* maxKeyController, 
 
292
                                                          size_t keyCount, 
 
293
                                                                  size_t dimensions, 
 
294
                                                                  size_t dimension, 
 
295
                                                                  const InputArrayType& inputValues, 
 
296
                                                                  const OutputArrayType& outputValues,
 
297
                                                                                                                  ConversionFunctorType inputConversionFunctor,
 
298
                                                                                                                  ConversionFunctorType outputConversionFunctor)
 
299
        {
 
300
                for ( size_t i = 0; i < keyCount; ++i)
 
301
                {
 
302
                        // Create the linear keys
 
303
                        ILinFloatKey key;
 
304
                        if ( inputConversionFunctor )
 
305
                        {
 
306
                                key.time = (TimeValue)((*inputConversionFunctor)((float)(inputValues[i])));
 
307
                        }
 
308
                        else
 
309
                        {
 
310
                                key.time = (TimeValue)(inputValues[i]);
 
311
                        }
 
312
                        
 
313
                        if ( outputConversionFunctor )
 
314
                        {
 
315
                                key.val = (*outputConversionFunctor)((float)(outputValues[ i*dimensions + dimension ]));
 
316
                        }
 
317
                        else
 
318
                        {
 
319
                                key.val = (float)(outputValues[ i*dimensions + dimension ]);
 
320
                        }
 
321
 
 
322
                        maxKeyController->SetKey((int) i, &key);
 
323
                }
 
324
                return true;
 
325
        }
 
326
 
 
327
 
 
328
        //------------------------------
 
329
        template<class InputArrayType, class OutputArrayType, class InTangentArrayType, class OutTangentArrayType> 
 
330
        bool AnimationImporter::fillBezierMaxFloatController( IKeyControl* maxKeyController, 
 
331
                                                                                                                  size_t keyCount, 
 
332
                                                                                                                  size_t dimensions, 
 
333
                                                                                                                  size_t dimension, 
 
334
                                                                                                                  const InputArrayType& inputValues, 
 
335
                                                                                                                  const OutputArrayType& outputValues,
 
336
                                                                                                                  const InTangentArrayType& inTangentValues,
 
337
                                                                                                                  const OutTangentArrayType& outTangentValues,
 
338
                                                                                                                  const COLLADAFW::AnimationCurve::InterpolationType interpolationType,
 
339
                                                                                                                  const COLLADAFW::AnimationCurve::InterpolationTypeArray& interpolationTypes,
 
340
                                                                                                                  ConversionFunctorType inputConversionFunctor,
 
341
                                                                                                                  ConversionFunctorType outputConversionFunctor)
 
342
        {
 
343
                COLLADAFW::AnimationCurve::InterpolationType previousKeyInterpolationType;
 
344
                COLLADAFW::AnimationCurve::InterpolationType currentKeyInterpolationType;
 
345
                if ( interpolationType != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED )
 
346
                {
 
347
                        previousKeyInterpolationType = interpolationType;
 
348
                        currentKeyInterpolationType = interpolationType;
 
349
                }
 
350
 
 
351
                for ( size_t i = 0; i < keyCount; ++i)
 
352
                {
 
353
 
 
354
                        if ( interpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_MIXED )
 
355
                        {
 
356
                                previousKeyInterpolationType = interpolationTypes[i > 0 ? i-1 : i];
 
357
                                currentKeyInterpolationType = interpolationTypes[i];
 
358
                        }
 
359
 
 
360
 
 
361
                        float currentKeyInput = (float)(inputValues[i]);
 
362
                        // Create the linear keys
 
363
                        IBezFloatKey key;
 
364
 
 
365
                        key.time = (TimeValue)convert( inputConversionFunctor, currentKeyInput );
 
366
 
 
367
                        key.val = convert( outputConversionFunctor, (float)(outputValues[ i*dimensions + dimension ]));
 
368
                
 
369
                        SetInTanType(key.flags, frameWorkInterpolationToMaxInterpolation( previousKeyInterpolationType ) );
 
370
                        SetOutTanType(key.flags, frameWorkInterpolationToMaxInterpolation( currentKeyInterpolationType ) );
 
371
 
 
372
                        size_t tangentIndex = 2*(dimensions * i + dimension);
 
373
 
 
374
                        // in tangent
 
375
                        if ( previousKeyInterpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER )
 
376
                        {
 
377
                                float previousSpan = (i > 0 ? currentKeyInput - (float)(inputValues[i-1]) : TOLERANCE);
 
378
 
 
379
                                // Calculate the in-tangent
 
380
                                float absoluteInTangentLength = currentKeyInput - (float)inTangentValues[tangentIndex];
 
381
                                key.inLength = absoluteInTangentLength / previousSpan;
 
382
                                if ( COLLADABU::Math::Utils::equalsZero( key.inLength ) ) 
 
383
                                {
 
384
                                        key.inLength = COLLADABU::Math::Utils::sign(key.inLength) * TOLERANCE;
 
385
                                }
 
386
                                key.intan = ( convert( outputConversionFunctor, (float)inTangentValues[tangentIndex + 1]) - key.val) / ( convert(inputConversionFunctor, absoluteInTangentLength));
 
387
                        }
 
388
                        else
 
389
                        {
 
390
                                key.intan  = 0.0f;
 
391
                                key.inLength = 0.333f;
 
392
                        }
 
393
 
 
394
 
 
395
                        // out tangent
 
396
                        if ( currentKeyInterpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER )
 
397
                        {
 
398
                                float nextSpan = (i < keyCount - 1 ? (float)(inputValues[i+1]) - currentKeyInput : TOLERANCE );
 
399
 
 
400
                                // Calculate the out-tangent
 
401
                                float absoluteOutTangentLength =  (float)outTangentValues[tangentIndex] - currentKeyInput;
 
402
                                key.outLength = absoluteOutTangentLength / nextSpan;
 
403
                                if ( COLLADABU::Math::Utils::equalsZero(key.outLength) )
 
404
                                {
 
405
                                        key.outLength = COLLADABU::Math::Utils::sign(key.outLength) * TOLERANCE;
 
406
                                }
 
407
                                key.outtan = (convert( outputConversionFunctor, (float)outTangentValues[tangentIndex + 1]) - key.val) / ( convert(inputConversionFunctor, absoluteOutTangentLength) );
 
408
                        }
 
409
                        else
 
410
                        {
 
411
                                key.outtan = 0.0f;
 
412
                                key.outLength = 0.333f;
 
413
                        }
 
414
 
 
415
                        // In some rare cases, only half the key is set by the first call, so call the SetKey function twice.
 
416
                        maxKeyController->SetKey((int) i, &key);
 
417
                        maxKeyController->SetKey((int) i, &key);
 
418
                }
 
419
 
 
420
                return true;
 
421
        }
 
422
 
 
423
 
 
424
        //------------------------------
 
425
        Control* AnimationImporter::createAndFillMaxTransformationController( COLLADAFW::AnimationCurve* animationCurve )
 
426
        {
 
427
                if ( animationCurve->getInterpolationType() !=  COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR )
 
428
                {
 
429
                        // we support only linear transformations
 
430
                        return 0;
 
431
                }
 
432
 
 
433
                if ( animationCurve->getOutDimension() !=  16 )
 
434
                {
 
435
                        // we can only handle animations with 16 dimension as matrix controller
 
436
                        return 0;
 
437
                }
 
438
 
 
439
                Control* maxController = createMaxTransformationController( animationCurve );
 
440
                if ( !maxController )
 
441
                {
 
442
                        return 0;
 
443
                }
 
444
 
 
445
                IKeyControl* maxKeyController = GetKeyControlInterface( maxController );
 
446
 
 
447
                fillMaxTransformationController( maxController, animationCurve);
 
448
 
 
449
                return maxController;
 
450
        }
 
451
 
 
452
        //------------------------------
 
453
        bool AnimationImporter::fillMaxTransformationController( Control* maxController, COLLADAFW::AnimationCurve* animationCurve )
 
454
        {
 
455
                // Fill in the controller with the animation data from the curve
 
456
                size_t keyCount = animationCurve->getKeyCount();
 
457
 
 
458
                assert( animationCurve->getOutDimension() == 16);
 
459
 
 
460
                //maxController->SetNumKeys((int) keyCount);
 
461
 
 
462
                const COLLADAFW::FloatOrDoubleArray& inputValues = animationCurve->getInputValues();
 
463
                COLLADAFW::FloatOrDoubleArray::DataType inputValuesDataType = inputValues.getType();
 
464
 
 
465
                const COLLADAFW::FloatOrDoubleArray& outputValues = animationCurve->getOutputValues();
 
466
                COLLADAFW::FloatOrDoubleArray::DataType outputValuesDataType = outputValues.getType();
 
467
 
 
468
                ConversionFunctor* inputConversionFunctor = getConversionFunctorByPhysicalDimension( animationCurve->getInPhysicalDimension() );
 
469
                ConversionFunctor* outputConversionFunctors[16];
 
470
                for ( size_t i = 0; i < 16; ++i)
 
471
                {
 
472
                        outputConversionFunctors[i] = getConversionFunctorByPhysicalDimension( animationCurve->getOutPhysicalDimensions()[i]);
 
473
                }
 
474
 
 
475
                if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
476
                {
 
477
                        if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
478
                        {
 
479
                                fillLinearMaxTransformationController( maxController, keyCount, *inputValues.getDoubleValues(), *outputValues.getDoubleValues(), inputConversionFunctor, outputConversionFunctors);
 
480
                        }
 
481
                        else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
482
                        {
 
483
                                fillLinearMaxTransformationController( maxController, keyCount, *inputValues.getDoubleValues(), *outputValues.getFloatValues(), inputConversionFunctor, outputConversionFunctors);
 
484
                        }
 
485
                }
 
486
                else if ( inputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT )
 
487
                {
 
488
                        if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE )
 
489
                        {
 
490
                                fillLinearMaxTransformationController( maxController, keyCount, *inputValues.getFloatValues(), *outputValues.getDoubleValues(), inputConversionFunctor, outputConversionFunctors);
 
491
                        }
 
492
                        else if ( outputValuesDataType == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT)
 
493
                        {
 
494
                                fillLinearMaxTransformationController( maxController, keyCount, *inputValues.getFloatValues(), *outputValues.getFloatValues(), inputConversionFunctor, outputConversionFunctors);
 
495
                        }
 
496
                }
 
497
                return true;
 
498
        }
 
499
 
 
500
 
 
501
        //------------------------------
 
502
        template<class InputArrayType, class OutputArrayType> 
 
503
        bool AnimationImporter::fillLinearMaxTransformationController( Control* maxController, 
 
504
                                                                                                                  size_t keyCount, 
 
505
                                                                                                              const InputArrayType& inputValues, 
 
506
                                                                  const OutputArrayType& outputValues,
 
507
                                                                                                                  ConversionFunctorType inputConversionFunctor,
 
508
                                                                                                                  ConversionFunctor* outputConversionFunctors[])
 
509
        {
 
510
                SuspendAnimate();
 
511
 
 
512
                AnimateOn();
 
513
 
 
514
                for ( size_t i = 0; i < keyCount; ++i)
 
515
                {
 
516
                        TimeValue keyTime;
 
517
                        if ( inputConversionFunctor )
 
518
                        {
 
519
                                keyTime = (TimeValue)((*inputConversionFunctor)((float)(inputValues[i])));
 
520
                        }
 
521
                        else
 
522
                        {
 
523
                                keyTime = (TimeValue)(inputValues[i]);
 
524
                        }
 
525
                        
 
526
                        Matrix3 matrixValue;
 
527
                        
 
528
                        size_t firstMatrixElement = 16*i;
 
529
 
 
530
                        Point4 column;
 
531
                        column[ 0 ] = convert(outputConversionFunctors[0], (float)outputValues[firstMatrixElement +  0]);
 
532
                        column[ 1 ] = convert(outputConversionFunctors[1], (float)outputValues[firstMatrixElement +  1]);
 
533
                        column[ 2 ] = convert(outputConversionFunctors[2], (float)outputValues[firstMatrixElement +  2]);
 
534
                        column[ 3 ] = convert(outputConversionFunctors[3], (float)outputValues[firstMatrixElement + 3]);
 
535
                        matrixValue.SetColumn(0, column);
 
536
 
 
537
                        column[ 0 ] = convert(outputConversionFunctors[4], (float)outputValues[firstMatrixElement +  4]);
 
538
                        column[ 1 ] = convert(outputConversionFunctors[5], (float)outputValues[firstMatrixElement +  5]);
 
539
                        column[ 2 ] = convert(outputConversionFunctors[6], (float)outputValues[firstMatrixElement +  6]);
 
540
                        column[ 3 ] = convert(outputConversionFunctors[7], (float)outputValues[firstMatrixElement + 7]);
 
541
                        matrixValue.SetColumn(1, column);
 
542
 
 
543
                        column[ 0 ] = convert(outputConversionFunctors[8], (float)outputValues[firstMatrixElement +  8]);
 
544
                        column[ 1 ] = convert(outputConversionFunctors[9], (float)outputValues[firstMatrixElement +  9]);
 
545
                        column[ 2 ] = convert(outputConversionFunctors[10], (float)outputValues[firstMatrixElement + 10]);
 
546
                        column[ 3 ] = convert(outputConversionFunctors[11], (float)outputValues[firstMatrixElement + 11]);
 
547
                        matrixValue.SetColumn(2, column);
 
548
 
 
549
                        SetXFormPacket matrixValuePacket(matrixValue);
 
550
                        maxController->SetValue( keyTime, &matrixValuePacket, 1, CTRL_ABSOLUTE);
 
551
                }
 
552
                ResumeAnimate(); 
 
553
                return true;
 
554
        }
 
555
 
 
556
 
 
557
 
 
558
} // namespace COLLADAMax