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

« back to all changes in this revision

Viewing changes to COLLADASaxFrameworkLoader/src/COLLADASaxFWLLoader.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 "COLLADASaxFWLLoader.h"
 
13
#include "COLLADASaxFWLFileLoader.h"
 
14
#include "COLLADASaxFWLPostProcessor.h"
 
15
#include "COLLADASaxFWLSaxParserErrorHandler.h"
 
16
#include "COLLADASaxFWLUtils.h"
 
17
 
 
18
#include "COLLADABUURI.h"
 
19
 
 
20
#include "COLLADAFWVisualScene.h"
 
21
#include "COLLADAFWLibraryNodes.h"
 
22
#include "COLLADAFWIWriter.h"
 
23
#include "COLLADAFWEffect.h"
 
24
#include "COLLADAFWLight.h"
 
25
#include "COLLADAFWCamera.h"
 
26
#include "COLLADAFWAnimationList.h"
 
27
#include "COLLADAFWConstants.h"
 
28
 
 
29
#include <sys/types.h>
 
30
#include <sys/timeb.h>
 
31
#include <fstream>
 
32
 
 
33
namespace COLLADASaxFWL
 
34
{
 
35
 
 
36
        const Loader::InstanceControllerDataList Loader::EMPTY_INSTANCE_CONTROLLER_DATALIST = Loader::InstanceControllerDataList();
 
37
 
 
38
        const Loader::JointSidsOrIds Loader::EMPTY_JOINTSIDSORIDS;
 
39
 
 
40
 
 
41
        Loader::Loader( IErrorHandler* errorHandler )
 
42
                : mFileLoader(0)
 
43
                , mNextFileId(0)
 
44
                , mCurrentFileId(0)
 
45
                , mErrorHandler(errorHandler)
 
46
                , mNextTextureMapId(0)
 
47
                , mObjectFlags( Loader::ALL_OBJECTS_MASK )
 
48
                , mParsedObjectFlags( Loader::NO_FLAG )
 
49
                , mSidTreeRoot( new SidTreeNode("", 0) )
 
50
                , mSkinControllerSet( compare )
 
51
                , mExternalReferenceDeciderCallbackFunction()
 
52
 
 
53
        {
 
54
        }
 
55
 
 
56
 
 
57
        //---------------------------------
 
58
        Loader::~Loader()
 
59
        {
 
60
                delete mSidTreeRoot;
 
61
 
 
62
                // delete visual scenes
 
63
                deleteVectorFW(mVisualScenes);
 
64
 
 
65
                // delete library nodes
 
66
                deleteVectorFW(mLibraryNodes);
 
67
 
 
68
                // delete effects
 
69
                deleteVectorFW(mEffects);
 
70
 
 
71
                // delete lights
 
72
                deleteVectorFW(mLights);
 
73
 
 
74
                // delete cameras
 
75
                deleteVectorFW(mCameras);
 
76
 
 
77
                // We do not delete formulas here. They are deleted by the Formulas class
 
78
 
 
79
                // delete animation lists
 
80
                Loader::UniqueIdAnimationListMap::const_iterator it = mUniqueIdAnimationListMap.begin();
 
81
                for ( ; it != mUniqueIdAnimationListMap.end(); ++it )
 
82
                {
 
83
                        COLLADAFW::AnimationList* animationList = it->second;
 
84
                        FW_DELETE animationList;
 
85
                }
 
86
        }
 
87
 
 
88
    //---------------------------------
 
89
        const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri, COLLADAFW::ClassId classId )
 
90
        {
 
91
                URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
 
92
                if ( it == mURIUniqueIdMap.end() )
 
93
                {
 
94
                        return mURIUniqueIdMap[uri] = COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), getFileId(uri));
 
95
                }
 
96
                else
 
97
                {
 
98
                        return it->second;
 
99
                }
 
100
        }
 
101
 
 
102
        //---------------------------------
 
103
        const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri)
 
104
        {
 
105
                URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
 
106
                if ( it == mURIUniqueIdMap.end() )
 
107
                {
 
108
                        return COLLADAFW::UniqueId::INVALID;
 
109
                }
 
110
                else
 
111
                {
 
112
                        return it->second;
 
113
                }
 
114
        }
 
115
 
 
116
        //---------------------------------
 
117
        COLLADAFW::UniqueId Loader::getUniqueId( COLLADAFW::ClassId classId )
 
118
        {
 
119
                return COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), mCurrentFileId);
 
120
        }
 
121
 
 
122
        //---------------------------------
 
123
        COLLADAFW::FileId Loader::getFileId( const COLLADABU::URI& uri )
 
124
        {
 
125
                // check if the uri is relative
 
126
                bool isRelative = uri.getScheme().empty() && 
 
127
                                      uri.getAuthority().empty() && 
 
128
                                                  uri.getPath().empty() && 
 
129
                                                  uri.getQuery().empty();
 
130
                if ( isRelative )
 
131
                {
 
132
                        // its a relative uri. The file id is that of the current file
 
133
                        return mCurrentFileId;
 
134
                }
 
135
 
 
136
                // the uri is not relative. We need to find the correct file id
 
137
                const COLLADABU::URI* usedUri = 0;
 
138
 
 
139
                COLLADABU::URI uriWithoutFragment;
 
140
                
 
141
                if ( uri.getFragment().empty() )
 
142
                {
 
143
                        // the passed uri has no fragment, we can use it without modification
 
144
                        usedUri = &uri;
 
145
                }
 
146
                else
 
147
                {
 
148
                        // the passed uri has a fragment, we need to make a copy without fragment
 
149
                        uriWithoutFragment.set( uri.getScheme(), uri.getAuthority(), uri.getPath(), uri.getQuery(), COLLADAFW::Constants::EMPTY_STRING);
 
150
                        usedUri = &uriWithoutFragment;
 
151
                }
 
152
 
 
153
                URIFileIdMap::iterator it = mURIFileIdMap.find( *usedUri );
 
154
 
 
155
                if ( it == mURIFileIdMap.end() )
 
156
                {
 
157
                        COLLADAFW::FileId fileId = mNextFileId++;
 
158
                        addFileIdUriPair( fileId, *usedUri );
 
159
                        return fileId;
 
160
                }
 
161
                else
 
162
                {
 
163
                        return it->second;
 
164
                }
 
165
        }
 
166
 
 
167
        //---------------------------------
 
168
        const COLLADABU::URI& Loader::getFileUri( COLLADAFW::FileId fileId )const
 
169
        {
 
170
                FileIdURIMap::const_iterator it = mFileIdURIMap.find( fileId );
 
171
 
 
172
                if ( it == mFileIdURIMap.end() )
 
173
                {
 
174
                        return COLLADABU::URI::INVALID;
 
175
                }
 
176
                else
 
177
                {
 
178
                        return it->second;
 
179
                }
 
180
        }
 
181
 
 
182
        //---------------------------------
 
183
        void Loader::addFileIdUriPair( COLLADAFW::FileId fileId, const COLLADABU::URI& uri )
 
184
        {
 
185
                mURIFileIdMap[uri] = fileId;
 
186
                mFileIdURIMap[fileId] = uri;
 
187
        }
 
188
 
 
189
        //---------------------------------
 
190
        bool Loader::loadDocument( const String& fileName, COLLADAFW::IWriter* writer )
 
191
        {
 
192
                if ( !writer )
 
193
                        return false;
 
194
                mWriter = writer;
 
195
 
 
196
                mWriter->start();
 
197
 
 
198
                SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
 
199
 
 
200
                COLLADABU::URI rootFileUri(COLLADABU::URI::nativePathToUri(fileName));
 
201
                
 
202
                // the root file has always file id 0
 
203
                addFileIdUriPair( mNextFileId++, rootFileUri );
 
204
 
 
205
                bool abortLoading = false;
 
206
 
 
207
                while ( (mCurrentFileId < mNextFileId) && !abortLoading )
 
208
                {
 
209
                        const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
 
210
 
 
211
                        if ( (mCurrentFileId == 0) 
 
212
                                || !mExternalReferenceDeciderCallbackFunction 
 
213
                                || mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
 
214
                        {
 
215
                                mFileLoader = new FileLoader(this, 
 
216
                                        fileUri,
 
217
                                        &saxParserErrorHandler, 
 
218
                                        mObjectFlags,
 
219
                                        mParsedObjectFlags, 
 
220
                                        mExtraDataCallbackHandlerList );
 
221
                                bool success = mFileLoader->load();
 
222
                                delete mFileLoader;
 
223
                                abortLoading = !success;
 
224
                        }
 
225
 
 
226
                        mCurrentFileId++;
 
227
                }
 
228
 
 
229
                if ( !abortLoading )
 
230
                {
 
231
                        PostProcessor postProcessor(this, 
 
232
                                &saxParserErrorHandler, 
 
233
                                mObjectFlags,
 
234
                                mParsedObjectFlags);
 
235
                        postProcessor.postProcess();
 
236
                }
 
237
                else
 
238
                {
 
239
                        mWriter->cancel("Generic error");
 
240
                }
 
241
 
 
242
                mWriter->finish();
 
243
 
 
244
                mParsedObjectFlags |= mObjectFlags;
 
245
 
 
246
                return !abortLoading;
 
247
        }
 
248
 
 
249
        //---------------------------------
 
250
        bool Loader::loadDocument( const String& uri, const char* buffer, int length, COLLADAFW::IWriter* writer )
 
251
        {
 
252
                if ( !writer )
 
253
                        return false;
 
254
                mWriter = writer;
 
255
        
 
256
                SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
 
257
        
 
258
                COLLADABU::URI rootUri(uri);
 
259
                
 
260
                // the root file has always file id 0
 
261
                addFileIdUriPair( mNextFileId++, rootUri );
 
262
        
 
263
                bool abortLoading = false;
 
264
 
 
265
                while ( (mCurrentFileId < mNextFileId) && !abortLoading )
 
266
                {
 
267
                        const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
 
268
 
 
269
                        if ( (mCurrentFileId == 0) 
 
270
                                || !mExternalReferenceDeciderCallbackFunction 
 
271
                                || mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
 
272
                        {
 
273
                                FileLoader fileLoader(this, 
 
274
                                        getFileUri( mCurrentFileId ),
 
275
                                        &saxParserErrorHandler, 
 
276
                                        mObjectFlags,
 
277
                                        mParsedObjectFlags, 
 
278
                                        mExtraDataCallbackHandlerList );
 
279
                                bool success = fileLoader.load(buffer, length);
 
280
                                abortLoading = !success;
 
281
                        }
 
282
            
 
283
                        mCurrentFileId++;
 
284
                }
 
285
        
 
286
                if ( !abortLoading )
 
287
                {
 
288
                        PostProcessor postProcessor(this, 
 
289
                                &saxParserErrorHandler, 
 
290
                                mObjectFlags,
 
291
                                mParsedObjectFlags);
 
292
                        postProcessor.postProcess();
 
293
                }
 
294
                else
 
295
                {
 
296
                        mWriter->cancel("Generic error");
 
297
                }
 
298
        
 
299
                mWriter->finish();
 
300
 
 
301
                mParsedObjectFlags |= mObjectFlags;
 
302
        
 
303
                return !abortLoading;
 
304
        }
 
305
 
 
306
    //---------------------------------
 
307
    bool Loader::registerExtraDataCallbackHandler ( IExtraDataCallbackHandler* extraDataCallbackHandler )
 
308
    {
 
309
        // Push the callback handler in the list of callback handlers.
 
310
        mExtraDataCallbackHandlerList.push_back ( extraDataCallbackHandler );
 
311
 
 
312
        return true;
 
313
    }
 
314
 
 
315
        //---------------------------------
 
316
        GeometryMaterialIdInfo& Loader::getMeshMaterialIdInfo( )
 
317
        {
 
318
                return mGeometryMaterialIdInfo;
 
319
        }
 
320
 
 
321
        //---------------------------------
 
322
        COLLADAFW::TextureMapId Loader::getTextureMapIdBySematic( const String& semantic )
 
323
        {
 
324
                StringTextureMapIdMap::iterator it = mTextureMapSemanticTextureMapIdMap.find(semantic);
 
325
                if ( it == mTextureMapSemanticTextureMapIdMap.end() )
 
326
                {
 
327
                        return mTextureMapSemanticTextureMapIdMap[semantic] = mNextTextureMapId++;
 
328
                }
 
329
                else
 
330
                {
 
331
                        return it->second;
 
332
                }
 
333
        }
 
334
 
 
335
        //-----------------------------
 
336
        bool Loader::compare( const COLLADAFW::SkinController& lhs, const COLLADAFW::SkinController& rhs )
 
337
        {
 
338
 
 
339
                if (lhs.getSkinControllerData() < rhs.getSkinControllerData() )
 
340
                        return true;
 
341
                if (lhs.getSkinControllerData() > rhs.getSkinControllerData() )
 
342
                        return false;
 
343
 
 
344
                if (lhs.getSource() < rhs.getSource() )
 
345
                        return true;
 
346
                if (lhs.getSource() > rhs.getSource() )
 
347
                        return false;
 
348
 
 
349
                const COLLADAFW::UniqueIdArray& lhsJoints = lhs.getJoints();
 
350
                const COLLADAFW::UniqueIdArray& rhsJoints = rhs.getJoints();
 
351
                size_t lhsJointsCount = lhsJoints.getCount();
 
352
                size_t rhsJointsCount = rhsJoints.getCount();
 
353
                if (lhsJointsCount < rhsJointsCount )
 
354
                        return true;
 
355
                if (lhsJointsCount > rhsJointsCount )
 
356
                        return false;
 
357
 
 
358
                for ( size_t i = 0; i < lhsJointsCount; ++i)
 
359
                {
 
360
                        const COLLADAFW::UniqueId& lhsJoint = lhsJoints[i];
 
361
                        const COLLADAFW::UniqueId& rhsJoint = rhsJoints[i];
 
362
                        if (lhsJoint < rhsJoint )
 
363
                                return true;
 
364
                        if (lhsJoint > rhsJoint )
 
365
                                return false;
 
366
                }
 
367
 
 
368
                return false;
 
369
        }
 
370
 
 
371
        //------------------------------
 
372
        void Loader::registerExternalReferenceDeciderCallbackFunction( ExternalReferenceDeciderCallbackFunction externalReferenceDeciderCallbackFunction )
 
373
        {
 
374
                mExternalReferenceDeciderCallbackFunction = externalReferenceDeciderCallbackFunction;
 
375
        }
 
376
 
 
377
} // namespace COLLADA