2
Copyright (c) 2008-2009 NetAllied Systems GmbH
4
This file is part of COLLADASaxFrameworkLoader.
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
11
#include "COLLADASaxFWLStableHeaders.h"
12
#include "COLLADASaxFWLLoader.h"
13
#include "COLLADASaxFWLFileLoader.h"
14
#include "COLLADASaxFWLPostProcessor.h"
15
#include "COLLADASaxFWLSaxParserErrorHandler.h"
16
#include "COLLADASaxFWLUtils.h"
18
#include "COLLADABUURI.h"
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"
29
#include <sys/types.h>
30
#include <sys/timeb.h>
33
namespace COLLADASaxFWL
36
const Loader::InstanceControllerDataList Loader::EMPTY_INSTANCE_CONTROLLER_DATALIST = Loader::InstanceControllerDataList();
38
const Loader::JointSidsOrIds Loader::EMPTY_JOINTSIDSORIDS;
41
Loader::Loader( IErrorHandler* errorHandler )
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()
57
//---------------------------------
62
// delete visual scenes
63
deleteVectorFW(mVisualScenes);
65
// delete library nodes
66
deleteVectorFW(mLibraryNodes);
69
deleteVectorFW(mEffects);
72
deleteVectorFW(mLights);
75
deleteVectorFW(mCameras);
77
// We do not delete formulas here. They are deleted by the Formulas class
79
// delete animation lists
80
Loader::UniqueIdAnimationListMap::const_iterator it = mUniqueIdAnimationListMap.begin();
81
for ( ; it != mUniqueIdAnimationListMap.end(); ++it )
83
COLLADAFW::AnimationList* animationList = it->second;
84
FW_DELETE animationList;
88
//---------------------------------
89
const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri, COLLADAFW::ClassId classId )
91
URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
92
if ( it == mURIUniqueIdMap.end() )
94
return mURIUniqueIdMap[uri] = COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), getFileId(uri));
102
//---------------------------------
103
const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri)
105
URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
106
if ( it == mURIUniqueIdMap.end() )
108
return COLLADAFW::UniqueId::INVALID;
116
//---------------------------------
117
COLLADAFW::UniqueId Loader::getUniqueId( COLLADAFW::ClassId classId )
119
return COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), mCurrentFileId);
122
//---------------------------------
123
COLLADAFW::FileId Loader::getFileId( const COLLADABU::URI& uri )
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();
132
// its a relative uri. The file id is that of the current file
133
return mCurrentFileId;
136
// the uri is not relative. We need to find the correct file id
137
const COLLADABU::URI* usedUri = 0;
139
COLLADABU::URI uriWithoutFragment;
141
if ( uri.getFragment().empty() )
143
// the passed uri has no fragment, we can use it without modification
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;
153
URIFileIdMap::iterator it = mURIFileIdMap.find( *usedUri );
155
if ( it == mURIFileIdMap.end() )
157
COLLADAFW::FileId fileId = mNextFileId++;
158
addFileIdUriPair( fileId, *usedUri );
167
//---------------------------------
168
const COLLADABU::URI& Loader::getFileUri( COLLADAFW::FileId fileId )const
170
FileIdURIMap::const_iterator it = mFileIdURIMap.find( fileId );
172
if ( it == mFileIdURIMap.end() )
174
return COLLADABU::URI::INVALID;
182
//---------------------------------
183
void Loader::addFileIdUriPair( COLLADAFW::FileId fileId, const COLLADABU::URI& uri )
185
mURIFileIdMap[uri] = fileId;
186
mFileIdURIMap[fileId] = uri;
189
//---------------------------------
190
bool Loader::loadDocument( const String& fileName, COLLADAFW::IWriter* writer )
198
SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
200
COLLADABU::URI rootFileUri(COLLADABU::URI::nativePathToUri(fileName));
202
// the root file has always file id 0
203
addFileIdUriPair( mNextFileId++, rootFileUri );
205
bool abortLoading = false;
207
while ( (mCurrentFileId < mNextFileId) && !abortLoading )
209
const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
211
if ( (mCurrentFileId == 0)
212
|| !mExternalReferenceDeciderCallbackFunction
213
|| mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
215
mFileLoader = new FileLoader(this,
217
&saxParserErrorHandler,
220
mExtraDataCallbackHandlerList );
221
bool success = mFileLoader->load();
223
abortLoading = !success;
231
PostProcessor postProcessor(this,
232
&saxParserErrorHandler,
235
postProcessor.postProcess();
239
mWriter->cancel("Generic error");
244
mParsedObjectFlags |= mObjectFlags;
246
return !abortLoading;
249
//---------------------------------
250
bool Loader::loadDocument( const String& uri, const char* buffer, int length, COLLADAFW::IWriter* writer )
256
SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
258
COLLADABU::URI rootUri(uri);
260
// the root file has always file id 0
261
addFileIdUriPair( mNextFileId++, rootUri );
263
bool abortLoading = false;
265
while ( (mCurrentFileId < mNextFileId) && !abortLoading )
267
const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
269
if ( (mCurrentFileId == 0)
270
|| !mExternalReferenceDeciderCallbackFunction
271
|| mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
273
FileLoader fileLoader(this,
274
getFileUri( mCurrentFileId ),
275
&saxParserErrorHandler,
278
mExtraDataCallbackHandlerList );
279
bool success = fileLoader.load(buffer, length);
280
abortLoading = !success;
288
PostProcessor postProcessor(this,
289
&saxParserErrorHandler,
292
postProcessor.postProcess();
296
mWriter->cancel("Generic error");
301
mParsedObjectFlags |= mObjectFlags;
303
return !abortLoading;
306
//---------------------------------
307
bool Loader::registerExtraDataCallbackHandler ( IExtraDataCallbackHandler* extraDataCallbackHandler )
309
// Push the callback handler in the list of callback handlers.
310
mExtraDataCallbackHandlerList.push_back ( extraDataCallbackHandler );
315
//---------------------------------
316
GeometryMaterialIdInfo& Loader::getMeshMaterialIdInfo( )
318
return mGeometryMaterialIdInfo;
321
//---------------------------------
322
COLLADAFW::TextureMapId Loader::getTextureMapIdBySematic( const String& semantic )
324
StringTextureMapIdMap::iterator it = mTextureMapSemanticTextureMapIdMap.find(semantic);
325
if ( it == mTextureMapSemanticTextureMapIdMap.end() )
327
return mTextureMapSemanticTextureMapIdMap[semantic] = mNextTextureMapId++;
335
//-----------------------------
336
bool Loader::compare( const COLLADAFW::SkinController& lhs, const COLLADAFW::SkinController& rhs )
339
if (lhs.getSkinControllerData() < rhs.getSkinControllerData() )
341
if (lhs.getSkinControllerData() > rhs.getSkinControllerData() )
344
if (lhs.getSource() < rhs.getSource() )
346
if (lhs.getSource() > rhs.getSource() )
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 )
355
if (lhsJointsCount > rhsJointsCount )
358
for ( size_t i = 0; i < lhsJointsCount; ++i)
360
const COLLADAFW::UniqueId& lhsJoint = lhsJoints[i];
361
const COLLADAFW::UniqueId& rhsJoint = rhsJoints[i];
362
if (lhsJoint < rhsJoint )
364
if (lhsJoint > rhsJoint )
371
//------------------------------
372
void Loader::registerExternalReferenceDeciderCallbackFunction( ExternalReferenceDeciderCallbackFunction externalReferenceDeciderCallbackFunction )
374
mExternalReferenceDeciderCallbackFunction = externalReferenceDeciderCallbackFunction;
377
} // namespace COLLADA