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

« back to all changes in this revision

Viewing changes to COLLADASaxFrameworkLoader/src/COLLADASaxFWLLibraryAnimationsLoader.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 COLLADASaxFrameworkLoader.
 
5
 
 
6
    Licensed under the MIT Open Source License, 
 
7
    for details please see LICENSE file or the website
 
8
    http://www.opensource.org/licenses/mit-license.php
 
9
*/
 
10
 
 
11
#include "COLLADASaxFWLStableHeaders.h"
 
12
#include "COLLADASaxFWLLibraryAnimationsLoader.h"
 
13
#include "COLLADASaxFWLSidAddress.h"
 
14
#include "COLLADASaxFWLSidTreeNode.h"
 
15
#include "COLLADASaxFWLInterpolationTypeSource.h"
 
16
#include "COLLADASaxFWLLoader.h"
 
17
 
 
18
#include "COLLADAFWValidate.h"
 
19
#include "COLLADAFWAnimationCurve.h"
 
20
#include "COLLADAFWAnimationList.h"
 
21
#include "COLLADAFWIWriter.h"
 
22
#include "COLLADAFWTypes.h"
 
23
 
 
24
 
 
25
namespace COLLADASaxFWL
 
26
{
 
27
 
 
28
        enum SamplerInputSemantics
 
29
        {
 
30
                SEMANTIC_UNKNOWN,
 
31
                SEMANTIC_INPUT,
 
32
                SEMANTIC_OUTPUT,
 
33
                SEMANTIC_INTERPOLATION,
 
34
                SEMANTIC_IN_TANGENT,
 
35
                SEMANTIC_OUT_TANGENT
 
36
        };
 
37
 
 
38
        const String INTERPOLATIONTYPE_LINEAR("LINEAR");
 
39
        const String INTERPOLATIONTYPE_BEZIER("BEZIER"); 
 
40
        const String INTERPOLATIONTYPE_CARDINAL("CARDINAL"); 
 
41
        const String INTERPOLATIONTYPE_HERMITE("HERMITE");
 
42
        const String INTERPOLATIONTYPE_BSPLINE("BSPLINE"); 
 
43
        const String INTERPOLATIONTYPE_STEP("STEP");
 
44
        const String INTERPOLATIONTYPE_MIXED("MIXED");
 
45
 
 
46
 
 
47
        //------------------------------
 
48
        bool operator==( const ParserString& parserString, const String& stlSring )
 
49
        {
 
50
                if ( parserString.length != stlSring.length() )
 
51
                        return false;
 
52
 
 
53
                size_t pos = 0;
 
54
                const char* str = stlSring.c_str();
 
55
                while ( (pos < parserString.length) )
 
56
                {
 
57
                        if ( parserString.str[pos] != str[pos] )
 
58
                                return false;
 
59
                        ++pos;
 
60
                }
 
61
                return true;
 
62
        }
 
63
 
 
64
        struct AccessorAnimationClassPair
 
65
        {
 
66
                AccessorAnimationClassPair( const SourceBase::AccessorParameter* _parameters,
 
67
                                                                        size_t _parameterCount,
 
68
                                                COLLADAFW::AnimationList::AnimationClass _animationClass)
 
69
                                                                        : parameters(_parameters)
 
70
                                                                        , parameterCount(_parameterCount/sizeof(SourceBase::AccessorParameter))
 
71
                                                                        , animationClass(_animationClass)
 
72
                {}
 
73
                const SourceBase::AccessorParameter* parameters;
 
74
                size_t parameterCount;
 
75
                COLLADAFW::AnimationList::AnimationClass animationClass;
 
76
        };
 
77
 
 
78
        struct AccessorDimensionsPair
 
79
        {
 
80
                AccessorDimensionsPair( const SourceBase::AccessorParameter& _parameter,
 
81
                                                                COLLADAFW::PhysicalDimension _physicalDimension,
 
82
                                                                size_t _dimension)
 
83
                        : parameter(_parameter)
 
84
                        , physicalDimension(_physicalDimension)
 
85
                        , dimension(_dimension)
 
86
                {}
 
87
                const SourceBase::AccessorParameter& parameter;
 
88
                COLLADAFW::PhysicalDimension physicalDimension;
 
89
                size_t dimension;
 
90
        };
 
91
 
 
92
        SourceBase::AccessorParameter parameterTime = {"TIME", "float"};
 
93
        SourceBase::AccessorParameter parameterFloat = {"", "float"};
 
94
        SourceBase::AccessorParameter parameterX = {"X", "float"};
 
95
        SourceBase::AccessorParameter parameterY = {"Y", "float"};
 
96
        SourceBase::AccessorParameter parameterZ = {"Z", "float"};
 
97
        SourceBase::AccessorParameter parameterR = {"R", "float"};
 
98
        SourceBase::AccessorParameter parameterG = {"G", "float"};
 
99
        SourceBase::AccessorParameter parameterB = {"B", "float"};
 
100
        SourceBase::AccessorParameter parameterA = {"A", "float"};
 
101
        SourceBase::AccessorParameter parameterAngle = {"ANGLE", "float"};
 
102
        SourceBase::AccessorParameter parameterTransform = {"TRANSFORM", "float4x4"};
 
103
 
 
104
        SourceBase::AccessorParameter accessorTime[] = {parameterTime};
 
105
        SourceBase::AccessorParameter accessorFloat[] = {parameterFloat};
 
106
        SourceBase::AccessorParameter accessorX[] = {parameterX};
 
107
        SourceBase::AccessorParameter accessorY[] = {parameterY};
 
108
        SourceBase::AccessorParameter accessorZ[] = {parameterZ};
 
109
        SourceBase::AccessorParameter accessorR[] = {parameterR};
 
110
        SourceBase::AccessorParameter accessorG[] = {parameterG};
 
111
        SourceBase::AccessorParameter accessorB[] = {parameterB};
 
112
        SourceBase::AccessorParameter accessorA[] = {parameterA};
 
113
        SourceBase::AccessorParameter accessorAngle[] = {parameterAngle};
 
114
        SourceBase::AccessorParameter accessorTransform[] = {parameterTransform};
 
115
 
 
116
        SourceBase::AccessorParameter accessorXYZ[] = {parameterX, parameterY, parameterZ};
 
117
        SourceBase::AccessorParameter accessorRGB[] = {parameterR, parameterG, parameterB};
 
118
        SourceBase::AccessorParameter accessorRGBA[] = {parameterR, parameterG, parameterB, parameterA};
 
119
        SourceBase::AccessorParameter accessorAxisAngle[] = {parameterX, parameterY, parameterZ, parameterAngle};
 
120
 
 
121
        AccessorAnimationClassPair animationClassMap[] = 
 
122
        { 
 
123
                  AccessorAnimationClassPair( accessorTime, sizeof(accessorTime), COLLADAFW::AnimationList::TIME)
 
124
                , AccessorAnimationClassPair( accessorFloat, sizeof(accessorFloat), COLLADAFW::AnimationList::FLOAT)
 
125
                , AccessorAnimationClassPair( accessorX, sizeof(accessorX), COLLADAFW::AnimationList::POSITION_X)
 
126
                , AccessorAnimationClassPair( accessorY, sizeof(accessorY), COLLADAFW::AnimationList::POSITION_Y)
 
127
                , AccessorAnimationClassPair( accessorZ, sizeof(accessorZ), COLLADAFW::AnimationList::POSITION_Z)
 
128
                , AccessorAnimationClassPair( accessorR, sizeof(accessorR), COLLADAFW::AnimationList::COLOR_R)
 
129
                , AccessorAnimationClassPair( accessorG, sizeof(accessorG), COLLADAFW::AnimationList::COLOR_G)
 
130
                , AccessorAnimationClassPair( accessorB, sizeof(accessorB), COLLADAFW::AnimationList::COLOR_B)
 
131
                , AccessorAnimationClassPair( accessorA, sizeof(accessorA), COLLADAFW::AnimationList::COLOR_A)
 
132
                , AccessorAnimationClassPair( accessorAngle, sizeof(accessorAngle), COLLADAFW::AnimationList::ANGLE)
 
133
                , AccessorAnimationClassPair( accessorXYZ, sizeof(accessorXYZ), COLLADAFW::AnimationList::POSITION_XYZ)
 
134
                , AccessorAnimationClassPair( accessorRGB, sizeof(accessorRGB), COLLADAFW::AnimationList::COLOR_RGB)
 
135
                , AccessorAnimationClassPair( accessorRGBA, sizeof(accessorRGBA), COLLADAFW::AnimationList::COLOR_RGBA)
 
136
                , AccessorAnimationClassPair( accessorAxisAngle, sizeof(accessorAxisAngle), COLLADAFW::AnimationList::AXISANGLE)
 
137
                , AccessorAnimationClassPair( accessorTransform, sizeof(accessorTransform), COLLADAFW::AnimationList::MATRIX4X4)
 
138
        };
 
139
 
 
140
#if 0
 
141
        AccessorDimensionsPair animationDimensionMap[] = 
 
142
        { 
 
143
              AccessorDimensionsPair( parameterFloat, PHYSICAL_DIMENSION_UNKNOWN, 1)
 
144
        , AccessorDimensionsPair( parameterX, PHYSICAL_DIMENSION_LENGTH, 1)
 
145
                , AccessorDimensionsPair( parameterY, PHYSICAL_DIMENSION_LENGTH, 1)
 
146
                , AccessorDimensionsPair( parameterZ, PHYSICAL_DIMENSION_LENGTH, 1)
 
147
                , AccessorDimensionsPair( parameterAngle, PHYSICAL_DIMENSION_ANGLE, 1)
 
148
                , AccessorDimensionsPair( parameterTransform, PHYSICAL_DIMENSION_TRANSFORMATIONMATRIX4X4, 16)
 
149
        };
 
150
#endif
 
151
 
 
152
 
 
153
        /** Determines the animation class from the accessor.*/
 
154
        //------------------------------
 
155
        COLLADAFW::AnimationList::AnimationClass determineAnimationClass( const SourceBase::Accessor& accessor )
 
156
        {
 
157
                static const size_t mapSize = sizeof(animationClassMap)/sizeof(AccessorAnimationClassPair);
 
158
                for ( size_t i = 0; i < mapSize; ++i)
 
159
                {
 
160
                        const AccessorAnimationClassPair& animationClassPair = animationClassMap[i];
 
161
 
 
162
                        if ( accessor.size() != animationClassPair.parameterCount )
 
163
                        {
 
164
                                // two accessor must have equal number of parameters to be equal
 
165
                                continue;
 
166
                        }
 
167
 
 
168
                        bool equal = true;
 
169
                        for ( size_t j = 0; j < animationClassPair.parameterCount; ++j)
 
170
                        {
 
171
                                const SourceBase::AccessorParameter& parameter = animationClassPair.parameters[j];
 
172
                                const SourceBase::AccessorParameter& accessorParameter = accessor[j];
 
173
                                if ( parameter !=  accessorParameter ) 
 
174
                                {
 
175
                                        equal = false;
 
176
                                        break;
 
177
                                }
 
178
                        }
 
179
 
 
180
                        if ( equal )
 
181
                        {
 
182
                                // if we reach this point, the parameters in accessor are equal to those in animationClassPair
 
183
                                return animationClassPair.animationClass;
 
184
                        }
 
185
                }
 
186
 
 
187
                return COLLADAFW::AnimationList::UNKNOWN_CLASS;
 
188
        }
 
189
 
 
190
#if 0
 
191
        /** Determines the physical dimension and the dimension of @a parameter.
 
192
        @param parameters the accessor parameter to determine the dimensions from
 
193
        @param physicalDimension Will be set to the physical dimension
 
194
        @param dimension Will be set to the dimension of the parameter, e.g. 1 for float, 16 for float4x4 
 
195
        @return True if parameter was found, false otherwise.*/
 
196
        //------------------------------
 
197
        bool determineParameterDimensions( const SourceBase::AccessorParameter& parameter,
 
198
                                                                           COLLADAFW::PhysicalDimension& physicalDimension,
 
199
                                                                           size_t& dimension)
 
200
        {
 
201
                static const size_t mapSize = sizeof(animationDimensionMap)/sizeof(AccessorDimensionsPair);
 
202
                for ( size_t i = 0; i < mapSize; ++i)
 
203
                {
 
204
                        const AccessorDimensionsPair& animationDimensionPair = animationDimensionMap[i];
 
205
 
 
206
                        if ( parameter ==  animationDimensionPair.parameter ) 
 
207
                        {
 
208
                                physicalDimension = animationDimensionPair.physicalDimension;
 
209
                                dimension = animationDimensionPair.dimension;
 
210
                                return true;
 
211
                        }
 
212
                }
 
213
 
 
214
                return false;
 
215
        }
 
216
#endif
 
217
 
 
218
        //------------------------------
 
219
        COLLADAFW::AnimationCurve::InterpolationType LibraryAnimationsLoader::getInterpolationTypeByString( const ParserString& string )
 
220
        {
 
221
                if ( string == INTERPOLATIONTYPE_LINEAR )
 
222
                {
 
223
                        return COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR;
 
224
                }
 
225
                else if ( string == INTERPOLATIONTYPE_BEZIER )
 
226
                {
 
227
                        return COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER;
 
228
                }
 
229
                else if ( string == INTERPOLATIONTYPE_CARDINAL )
 
230
                {
 
231
                        return COLLADAFW::AnimationCurve::INTERPOLATION_CARDINAL;
 
232
                }
 
233
                else if ( string == INTERPOLATIONTYPE_HERMITE )
 
234
                {
 
235
                        return COLLADAFW::AnimationCurve::INTERPOLATION_HERMITE;
 
236
                }
 
237
                else if ( string == INTERPOLATIONTYPE_BSPLINE )
 
238
                {
 
239
                        return COLLADAFW::AnimationCurve::INTERPOLATION_BSPLINE;
 
240
                }
 
241
                else if ( string == INTERPOLATIONTYPE_STEP )
 
242
                {
 
243
                        return COLLADAFW::AnimationCurve::INTERPOLATION_STEP;
 
244
                }
 
245
                else if ( string == INTERPOLATIONTYPE_MIXED )
 
246
                {
 
247
                        return COLLADAFW::AnimationCurve::INTERPOLATION_MIXED;
 
248
                }
 
249
 
 
250
                return COLLADAFW::AnimationCurve::INTERPOLATION_UNKNOWN;
 
251
        }
 
252
 
 
253
        //------------------------------
 
254
        SamplerInputSemantics getSemanticBySemanticStr( const char * semanticStr)
 
255
        {
 
256
                if ( strcmp(semanticStr, "INPUT" ) == 0 )
 
257
                {
 
258
                        return SEMANTIC_INPUT;
 
259
                }
 
260
                else if ( strcmp(semanticStr, "OUTPUT" ) == 0 )
 
261
                {
 
262
                        return SEMANTIC_OUTPUT;
 
263
                }
 
264
                else if ( strcmp(semanticStr, "INTERPOLATION" ) == 0 )
 
265
                {
 
266
                        return SEMANTIC_INTERPOLATION;
 
267
                }
 
268
                else if ( strcmp(semanticStr, "IN_TANGENT" ) == 0 )
 
269
                {
 
270
                        return SEMANTIC_IN_TANGENT;
 
271
                }
 
272
                else if ( strcmp(semanticStr, "OUT_TANGENT" ) == 0 )
 
273
                {
 
274
                        return SEMANTIC_OUT_TANGENT;
 
275
                }
 
276
                return SEMANTIC_UNKNOWN;
 
277
        }
 
278
 
 
279
        //------------------------------
 
280
        LibraryAnimationsLoader::LibraryAnimationsLoader( IFilePartLoader* callingFilePartLoader )
 
281
                : SourceArrayLoader(callingFilePartLoader)
 
282
                , mCurrentAnimationCurve(0)
 
283
                , mCurrentlyParsingInterpolationArray(false)
 
284
                , mCurrentAnimationInfo( 0 )
 
285
                , mCurrentAnimationCurveRequiresTangents(true)
 
286
                , mVerboseValidate(true)
 
287
        , mProcessedCount(0)
 
288
        {}
 
289
 
 
290
    //------------------------------
 
291
        LibraryAnimationsLoader::~LibraryAnimationsLoader()
 
292
        {
 
293
        }
 
294
 
 
295
    //------------------------------
 
296
    const COLLADAFW::UniqueId& LibraryAnimationsLoader::getUniqueId ()
 
297
    {
 
298
        if ( mCurrentAnimationCurve )
 
299
            return mCurrentAnimationCurve->getUniqueId ();
 
300
 
 
301
        // TODO One curve for every sampler in an collada animation. Returns always an invalid id!
 
302
        return COLLADAFW::UniqueId::INVALID;
 
303
    }
 
304
 
 
305
        //------------------------------
 
306
        AnimationInfo* LibraryAnimationsLoader::getAnimationInfoBySamplerId( const String& samplerId )
 
307
        {
 
308
                StringAnimationInfoMap::iterator it = mSamplerIdAnimationInfoMap.find( samplerId );
 
309
                if ( it == mSamplerIdAnimationInfoMap.end() )
 
310
                {
 
311
                        return 0;
 
312
                }
 
313
                else
 
314
                {
 
315
                        return &(it->second);
 
316
                }
 
317
        }
 
318
 
 
319
        //------------------------------
 
320
        bool LibraryAnimationsLoader::end__library_animations()
 
321
        {
 
322
                moveUpInSidTree();
 
323
                finish();
 
324
                return true;
 
325
        }
 
326
 
 
327
        //------------------------------
 
328
        bool LibraryAnimationsLoader::begin__source( const source__AttributeData& attributes )
 
329
        {
 
330
                return beginSource(attributes);
 
331
        }
 
332
 
 
333
        //------------------------------
 
334
        bool LibraryAnimationsLoader::end__source(  )
 
335
        {
 
336
                return endSource();
 
337
        }
 
338
 
 
339
        //------------------------------
 
340
        bool LibraryAnimationsLoader::begin__animation( const animation__AttributeData& attributeData )
 
341
        {
 
342
        if ( attributeData.name ) 
 
343
            mName = (const char*)attributeData.name;
 
344
        else if ( attributeData.id) 
 
345
            mName = (const char*)attributeData.id;
 
346
 
 
347
        if ( attributeData.id )
 
348
            mOriginalId = (const char*)attributeData.id;
 
349
        else {
 
350
            //FR: we create an id, so that clients can figure out - for an incoming animation - which animation it originally belongs to.
 
351
            //Thus, it can be able to respect the same layout of animation than the input COLLADA file.
 
352
            std::ostringstream o;
 
353
            o << "animation_"  << this->mProcessedCount++;
 
354
            mOriginalId = o.str();
 
355
        }
 
356
        
 
357
                return true;
 
358
        }
 
359
 
 
360
        //------------------------------
 
361
        bool LibraryAnimationsLoader::end__animation()
 
362
        {
 
363
        mOriginalId = COLLADABU::Utils::EMPTY_STRING;
 
364
 
 
365
                return true;
 
366
        }
 
367
 
 
368
        //------------------------------
 
369
        bool LibraryAnimationsLoader::begin__sampler( const sampler__AttributeData& attributeData )
 
370
        {
 
371
                mCurrentAnimationCurve = FW_NEW COLLADAFW::AnimationCurve(createUniqueIdFromId(attributeData.id, COLLADAFW::Animation::ID()));
 
372
 
 
373
                mCurrentAnimationCurve->setName ( mName );
 
374
        mCurrentAnimationCurve->setOriginalId ( mOriginalId );
 
375
 
 
376
                if ( attributeData.id && *attributeData.id )
 
377
                {
 
378
                        AnimationInfo animationInfo;
 
379
                        animationInfo.uniqueId = mCurrentAnimationCurve->getUniqueId();
 
380
                        animationInfo.animationClass = COLLADAFW::AnimationList::UNKNOWN_CLASS;
 
381
                        mCurrentAnimationInfo = &(mSamplerIdAnimationInfoMap.insert(std::make_pair(attributeData.id, animationInfo)).first->second);
 
382
                }
 
383
                return true;
 
384
        }
 
385
 
 
386
        //------------------------------
 
387
        bool LibraryAnimationsLoader::end__sampler()
 
388
        {
 
389
                bool success = true;
 
390
                if ( !mCurrentAnimationCurveRequiresTangents )
 
391
                {
 
392
                        mCurrentAnimationCurve->getInTangentValues().clear();
 
393
                        mCurrentAnimationCurve->getOutTangentValues().clear();
 
394
                }
 
395
                if ( (getObjectFlags() & Loader::ANIMATION_FLAG) != 0 )
 
396
                {
 
397
                        //assume linear interpolation if no interpolation is set
 
398
                        if ( mCurrentAnimationCurve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_UNKNOWN )
 
399
                        {
 
400
                                mCurrentAnimationCurve->setInterpolationType(COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR );
 
401
                        }
 
402
 
 
403
                        if ( COLLADAFW::validate( mCurrentAnimationCurve, mVerboseValidate ) == 0)
 
404
                        {
 
405
                                success = writer()->writeAnimation(mCurrentAnimationCurve);
 
406
                                FW_DELETE mCurrentAnimationCurve;
 
407
                        }
 
408
                        else
 
409
                        {
 
410
                handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "Animation curve \"" + mCurrentAnimationCurve->getName () + "\" not valid!" );
 
411
                        }
 
412
                }
 
413
                mCurrentAnimationCurve = 0;
 
414
                mCurrentAnimationInfo = 0;
 
415
                mCurrentAnimationCurveRequiresTangents = true;
 
416
                return success;
 
417
        }
 
418
 
 
419
        //------------------------------
 
420
        bool LibraryAnimationsLoader::begin__channel( const channel__AttributeData& attributeData )
 
421
        {
 
422
                String samplerId = getIdFromURIFragmentType(attributeData.source);
 
423
 
 
424
                AnimationInfo* animationInfo = getAnimationInfoBySamplerId( samplerId );
 
425
 
 
426
                if ( !animationInfo )
 
427
                        return true;
 
428
 
 
429
                SidAddress sidAddress( String(attributeData.target) );
 
430
#if 0
 
431
                const SidTreeNode* sidTreeNode = resolveSid( sidAddress );
 
432
 
 
433
                if ( sidTreeNode )
 
434
                {
 
435
                        if ( sidTreeNode->getTargetType() == SidTreeNode::TARGETTYPE_ANIMATABLE )
 
436
                        {
 
437
                                COLLADAFW::Animatable* animatable = sidTreeNode->getAnimatableTarget();
 
438
                                COLLADAFW::UniqueId animationListUniqueId = animatable->getAnimationList();
 
439
                                if ( !animationListUniqueId.isValid() )
 
440
                                {
 
441
                                        animationListUniqueId = getUniqueId( COLLADAFW::AnimationList::ID() );
 
442
                                        animatable->setAnimationList( animationListUniqueId );
 
443
                                }
 
444
                                COLLADAFW::AnimationList*& animationList = getAnimationListByUniqueId(animationListUniqueId);
 
445
 
 
446
                                if ( !animationList )
 
447
                                {
 
448
                                        animationList = new COLLADAFW::AnimationList( animationListUniqueId.getObjectId() );
 
449
                                }
 
450
 
 
451
                                // TODO handle this for arrays
 
452
                                COLLADAFW::AnimationList::AnimationBinding animationBinding;
 
453
                                animationBinding.animation = animationInfo->uniqueId;
 
454
                                animationBinding.animationClass = animationInfo->animationClass;
 
455
                                if ( animationBinding.animationClass == COLLADAFW::AnimationList::MATRIX4X4_ELEMENT )
 
456
                                {
 
457
                                        animationBinding.firstIndex = sidAddress.getFirstIndex();
 
458
                                        animationBinding.secondIndex = sidAddress.getSecondIndex();
 
459
                                }
 
460
                                else
 
461
                                {
 
462
                                        animationBinding.firstIndex = 0;
 
463
                                        animationBinding.secondIndex = 0;
 
464
                                }
 
465
                                animationList->getAnimationBindings().append( animationBinding );
 
466
                        }
 
467
                }
 
468
                else
 
469
#endif
 
470
                {
 
471
                        // the references element has not been parsed. Store the connection. Will be processed by FileLoader
 
472
                        // at the end of the collada file.
 
473
                        addToAnimationSidAddressBindings( *animationInfo, sidAddress );
 
474
                }
 
475
 
 
476
                return true;
 
477
        }
 
478
 
 
479
        //------------------------------
 
480
        bool LibraryAnimationsLoader::end__channel()
 
481
        {
 
482
                return true;
 
483
        }
 
484
 
 
485
 
 
486
        //------------------------------
 
487
        bool LibraryAnimationsLoader::begin__input____InputLocal( const input____InputLocal__AttributeData& attributeData )
 
488
        {
 
489
                // we ignore inputs that don't have semantics or source
 
490
                if ( !attributeData.semantic || !attributeData.source  )
 
491
                {
 
492
                        return true;
 
493
                }
 
494
 
 
495
                SamplerInputSemantics semantic = getSemanticBySemanticStr( attributeData.semantic );
 
496
                if ( semantic == SEMANTIC_UNKNOWN )
 
497
                {
 
498
                        return true;
 
499
                }
 
500
 
 
501
                String sourceId = getIdFromURIFragmentType(attributeData.source);
 
502
                const SourceBase* sourceBase = getSourceById ( sourceId );
 
503
                // TODO handle case where source could not be found
 
504
                if ( !sourceBase )
 
505
                        return true;
 
506
                SourceBase::DataType sourceDataType =  sourceBase->getDataType();
 
507
 
 
508
 
 
509
                switch ( semantic )
 
510
                {
 
511
                case SEMANTIC_INPUT:
 
512
                        {
 
513
                                if ( sourceDataType != SourceBase::DATA_TYPE_REAL )
 
514
                                {
 
515
                                        // The source array has wrong type. Only reals are allowed for semantic INPUT
 
516
                                        break;
 
517
                                }
 
518
 
 
519
                                COLLADAFW::AnimationList::AnimationClass animationClass = determineAnimationClass( sourceBase->getAccessor() );
 
520
 
 
521
                                if ( animationClass == COLLADAFW::AnimationList::TIME )
 
522
                                {
 
523
                                        mCurrentAnimationCurve->setInPhysicalDimension( COLLADAFW::PHYSICAL_DIMENSION_TIME );
 
524
                                }
 
525
                                else
 
526
                                {
 
527
                                        mCurrentAnimationCurve->setInPhysicalDimension( COLLADAFW::PHYSICAL_DIMENSION_UNKNOWN );
 
528
                                }
 
529
 
 
530
                                setRealValues( mCurrentAnimationCurve->getInputValues(), (const RealSource*)sourceBase);
 
531
                        }
 
532
                        break;
 
533
                case SEMANTIC_OUTPUT:
 
534
                        {
 
535
                                if ( sourceDataType != SourceBase::DATA_TYPE_REAL )
 
536
                                {
 
537
                                        // The source array has wrong type. Only reals are allowed for semantic OUTPUT
 
538
                                        break;
 
539
                                }
 
540
 
 
541
                                COLLADABU_ASSERT( mCurrentAnimationInfo );
 
542
                                COLLADAFW::PhysicalDimensionArray& physicalDimensions = mCurrentAnimationCurve->getOutPhysicalDimensions();
 
543
                                
 
544
                                if ( mCurrentAnimationInfo )
 
545
                                {
 
546
                                        COLLADAFW::AnimationList::AnimationClass animationClass = determineAnimationClass( sourceBase->getAccessor() );
 
547
                                        mCurrentAnimationInfo->animationClass = animationClass;
 
548
 
 
549
                                        switch ( animationClass )
 
550
                                        {
 
551
                                        case COLLADAFW::AnimationList::POSITION_X:
 
552
                                        case COLLADAFW::AnimationList::POSITION_Y:
 
553
                                        case COLLADAFW::AnimationList::POSITION_Z:
 
554
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
555
                                                break;
 
556
                                        case COLLADAFW::AnimationList::POSITION_XYZ:
 
557
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
558
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
559
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
560
                                                break;
 
561
                                        case COLLADAFW::AnimationList::ANGLE:
 
562
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_ANGLE);
 
563
                                                break;
 
564
                                        case COLLADAFW::AnimationList::AXISANGLE:
 
565
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
566
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
567
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
568
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_ANGLE);
 
569
                                                break;
 
570
                                        case COLLADAFW::AnimationList::MATRIX4X4:
 
571
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
572
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
573
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
574
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
575
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
576
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
577
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
578
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
579
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
580
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
581
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
582
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_LENGTH);
 
583
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
584
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
585
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
586
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
587
                                                break;
 
588
                                        case COLLADAFW::AnimationList::COLOR_R:
 
589
                                        case COLLADAFW::AnimationList::COLOR_G:
 
590
                                        case COLLADAFW::AnimationList::COLOR_B:
 
591
                                        case COLLADAFW::AnimationList::COLOR_A:
 
592
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
593
                                                break;
 
594
                                        case COLLADAFW::AnimationList::COLOR_RGB:
 
595
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
596
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
597
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
598
                                                break;
 
599
                                        case COLLADAFW::AnimationList::COLOR_RGBA:
 
600
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
601
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
602
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
603
                                                physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_COLOR);
 
604
                                                break;
 
605
                    case COLLADAFW::AnimationList::FLOAT:
 
606
                        physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_NUMBER);
 
607
                        break;
 
608
                    case COLLADAFW::AnimationList::ARRAY_ELEMENT_1D:
 
609
                    case COLLADAFW::AnimationList::ARRAY_ELEMENT_2D:
 
610
                            //https://github.com/KhronosGroup/OpenCOLLADA/issues/245
 
611
                            //FR: is this an issue to have nothing processed here, or is it processed somewhere else ?
 
612
                        break;
 
613
                    case COLLADAFW::AnimationList::UNKNOWN_CLASS:
 
614
                    case COLLADAFW::AnimationList::TIME:
 
615
                        break;
 
616
                                        }
 
617
                                }
 
618
 
 
619
                                const RealSource* realSource = (const RealSource*)sourceBase;
 
620
                                setRealValues( mCurrentAnimationCurve->getOutputValues(), realSource);
 
621
 
 
622
                                size_t stride = (size_t)realSource->getStride();
 
623
                                size_t physicalDimensionsCount = physicalDimensions.getCount();
 
624
                                // if stride is larger that physicalDimensionsCount, we need to append dimensions to physicalDimensions
 
625
                                for ( size_t i =  physicalDimensionsCount; i < stride; ++i)
 
626
                                {
 
627
                                        physicalDimensions.append(COLLADAFW::PHYSICAL_DIMENSION_UNKNOWN);
 
628
                                }
 
629
                                mCurrentAnimationCurve->setOutDimension(stride);
 
630
                        }
 
631
                        break;
 
632
                case SEMANTIC_OUT_TANGENT:
 
633
                        {
 
634
                                if ( sourceDataType != SourceBase::DATA_TYPE_REAL )
 
635
                                {
 
636
                                        // The source array has wrong type. Only reals are allowed for semantic OUTPUT
 
637
                                        break;
 
638
                                }
 
639
 
 
640
                                if ( !mCurrentAnimationCurveRequiresTangents )
 
641
                                {
 
642
                                        // This animation does not require tangents
 
643
                                        break;
 
644
                                }
 
645
                                setRealValues( mCurrentAnimationCurve->getOutTangentValues(), (const RealSource*)sourceBase);
 
646
                        }
 
647
                        break;
 
648
                case SEMANTIC_IN_TANGENT:
 
649
                        {
 
650
                                if ( sourceDataType != SourceBase::DATA_TYPE_REAL )
 
651
                                {
 
652
                                        // The source array has wrong type. Only reals are allowed for semantic OUTPUT
 
653
                                        break;
 
654
                                }
 
655
                                if ( !mCurrentAnimationCurveRequiresTangents )
 
656
                                {
 
657
                                        // This animation does not require tangents
 
658
                                        break;
 
659
                                }
 
660
                                setRealValues( mCurrentAnimationCurve->getInTangentValues(), (const RealSource*)sourceBase);
 
661
                        }
 
662
                        break;
 
663
                case SEMANTIC_INTERPOLATION:
 
664
                        {
 
665
                                if ( sourceDataType != SourceBase::DATA_TYPE_INTERPOLATIONTYPE )
 
666
                                {
 
667
                                        // The source array has wrong type. Only reals are allowed for semantic INTERPOLATION
 
668
                                        break;
 
669
                                }
 
670
 
 
671
                                COLLADAFW::AnimationCurve::InterpolationType currentAnimationCurveInterpolationType = mCurrentAnimationCurve->getInterpolationType();
 
672
 
 
673
                                if ( currentAnimationCurveInterpolationType != COLLADAFW::AnimationCurve::INTERPOLATION_UNKNOWN )
 
674
                                {
 
675
                                        // There already must have been an input with semantic INTERPOLATION. We ignore all following.
 
676
                                        break;
 
677
                                }
 
678
 
 
679
                                const InterpolationTypeSource* interpolationTypeSource = (const InterpolationTypeSource*)sourceBase;
 
680
                                COLLADAFW::AnimationCurve::InterpolationType interpolationType = interpolationTypeSource->getInterpolationType();
 
681
                                mCurrentAnimationCurveRequiresTangents = interpolationTypeSource->getRequiresTangents();
 
682
 
 
683
                                mCurrentAnimationCurve->setInterpolationType(interpolationType);
 
684
 
 
685
                                if ( interpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_MIXED )
 
686
                                {
 
687
                                        COLLADAFW::AnimationCurve::InterpolationTypeArray& interpolationTypes = mCurrentAnimationCurve->getInterpolationTypes();
 
688
                                        interpolationTypes.appendValues(interpolationTypeSource->getArrayElement().getValues());
 
689
                                }
 
690
                        }
 
691
                        break;
 
692
        default:
 
693
            break;
 
694
                }
 
695
 
 
696
                return true;
 
697
        }
 
698
 
 
699
        //------------------------------
 
700
        bool LibraryAnimationsLoader::begin__Name_array( const Name_array__AttributeData& attributeData )
 
701
        {
 
702
                return beginArray<InterpolationTypeSource>( attributeData.count, attributeData.id ) != 0;
 
703
                return true;
 
704
        }
 
705
 
 
706
        //------------------------------
 
707
        bool LibraryAnimationsLoader::end__Name_array()
 
708
        {
 
709
                return true;
 
710
        }
 
711
 
 
712
        //------------------------------
 
713
        bool LibraryAnimationsLoader::data__Name_array( const ParserString* data, size_t length )
 
714
        {
 
715
                InterpolationTypeSource* interpolationTypeSource = (InterpolationTypeSource*)mCurrentSoure;
 
716
                for ( size_t i = 0; i < length;  ++i)
 
717
                {
 
718
                        const ParserString& interpolationTypeString = data[i];
 
719
                        COLLADAFW::AnimationCurve::InterpolationType interpolationType = getInterpolationTypeByString( interpolationTypeString );
 
720
                        COLLADAFW::AnimationCurve::InterpolationTypeArray& array  = interpolationTypeSource->getArrayElement().getValues();
 
721
                        array.append( interpolationType );
 
722
 
 
723
                        COLLADAFW::AnimationCurve::InterpolationType interpolationTypeSourceInterpolationType = interpolationTypeSource->getInterpolationType();
 
724
                        if ( (interpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) || 
 
725
                                 (interpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_HERMITE) )
 
726
                        {
 
727
                                interpolationTypeSource->setRequiresTangents( true );
 
728
                        }
 
729
                        if ( interpolationTypeSourceInterpolationType == COLLADAFW::AnimationCurve::INTERPOLATION_UNKNOWN )
 
730
                        {
 
731
                                interpolationTypeSource->setInterpolationType( interpolationType );
 
732
                        }
 
733
                        else if ( interpolationTypeSourceInterpolationType != interpolationType )
 
734
                        {
 
735
                                interpolationTypeSource->setInterpolationType( COLLADAFW::AnimationCurve::INTERPOLATION_MIXED);
 
736
                        }
 
737
                }
 
738
                return true;
 
739
        }
 
740
 
 
741
} // namespace COLLADASaxFWL