PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/openCOLLADA-svn871/COLLADASaxFrameworkLoader/src/COLLADASaxFWLLoader.cpp

#
C++ | 375 lines | 269 code | 68 blank | 38 comment | 42 complexity | dde57e75966d9961085df52613bdb80e MD5 | raw file
  1. /*
  2. Copyright (c) 2008-2009 NetAllied Systems GmbH
  3. This file is part of COLLADASaxFrameworkLoader.
  4. Licensed under the MIT Open Source License,
  5. for details please see LICENSE file or the website
  6. http://www.opensource.org/licenses/mit-license.php
  7. */
  8. #include "COLLADASaxFWLStableHeaders.h"
  9. #include "COLLADASaxFWLLoader.h"
  10. #include "COLLADASaxFWLFileLoader.h"
  11. #include "COLLADASaxFWLPostProcessor.h"
  12. #include "COLLADASaxFWLSaxParserErrorHandler.h"
  13. #include "COLLADASaxFWLUtils.h"
  14. #include "COLLADABUURI.h"
  15. #include "COLLADAFWVisualScene.h"
  16. #include "COLLADAFWLibraryNodes.h"
  17. #include "COLLADAFWIWriter.h"
  18. #include "COLLADAFWEffect.h"
  19. #include "COLLADAFWLight.h"
  20. #include "COLLADAFWCamera.h"
  21. #include "COLLADAFWAnimationList.h"
  22. #include "COLLADAFWConstants.h"
  23. #include <sys/types.h>
  24. #include <sys/timeb.h>
  25. #include <fstream>
  26. namespace COLLADASaxFWL
  27. {
  28. const Loader::InstanceControllerDataList Loader::EMPTY_INSTANCE_CONTROLLER_DATALIST = Loader::InstanceControllerDataList();
  29. const Loader::JointSidsOrIds Loader::EMPTY_JOINTSIDSORIDS;
  30. Loader::Loader( IErrorHandler* errorHandler )
  31. : mNextFileId(0)
  32. , mCurrentFileId(0)
  33. , mErrorHandler(errorHandler)
  34. , mNextTextureMapId(0)
  35. , mObjectFlags( Loader::ALL_OBJECTS_MASK )
  36. , mParsedObjectFlags( Loader::NO_FLAG )
  37. , mSidTreeRoot( new SidTreeNode("", 0) )
  38. , mSkinControllerSet( compare )
  39. , mExternalReferenceDeciderCallbackFunction()
  40. {
  41. }
  42. //---------------------------------
  43. Loader::~Loader()
  44. {
  45. delete mSidTreeRoot;
  46. // delete visual scenes
  47. deleteVectorFW(mVisualScenes);
  48. // delete library nodes
  49. deleteVectorFW(mLibraryNodes);
  50. // delete effects
  51. deleteVectorFW(mEffects);
  52. // delete lights
  53. deleteVectorFW(mLights);
  54. // delete cameras
  55. deleteVectorFW(mCameras);
  56. // We do not delete formulas here. They are deleted by the Formulas class
  57. // delete animation lists
  58. Loader::UniqueIdAnimationListMap::const_iterator it = mUniqueIdAnimationListMap.begin();
  59. for ( ; it != mUniqueIdAnimationListMap.end(); ++it )
  60. {
  61. COLLADAFW::AnimationList* animationList = it->second;
  62. FW_DELETE animationList;
  63. }
  64. }
  65. //---------------------------------
  66. const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri, COLLADAFW::ClassId classId )
  67. {
  68. URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
  69. if ( it == mURIUniqueIdMap.end() )
  70. {
  71. return mURIUniqueIdMap[uri] = COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), getFileId(uri));
  72. }
  73. else
  74. {
  75. return it->second;
  76. }
  77. }
  78. //---------------------------------
  79. const COLLADAFW::UniqueId& Loader::getUniqueId( const COLLADABU::URI& uri)
  80. {
  81. URIUniqueIdMap::iterator it = mURIUniqueIdMap.find(uri);
  82. if ( it == mURIUniqueIdMap.end() )
  83. {
  84. return COLLADAFW::UniqueId::INVALID;
  85. }
  86. else
  87. {
  88. return it->second;
  89. }
  90. }
  91. //---------------------------------
  92. COLLADAFW::UniqueId Loader::getUniqueId( COLLADAFW::ClassId classId )
  93. {
  94. return COLLADAFW::UniqueId(classId, mLoaderUtil.getLowestObjectIdFor(classId), mCurrentFileId);
  95. }
  96. //---------------------------------
  97. COLLADAFW::FileId Loader::getFileId( const COLLADABU::URI& uri )
  98. {
  99. // check if the uri is relative
  100. bool isRelative = uri.getScheme().empty() &&
  101. uri.getAuthority().empty() &&
  102. uri.getPath().empty() &&
  103. uri.getQuery().empty();
  104. if ( isRelative )
  105. {
  106. // its a relative uri. The file id is that of the current file
  107. return mCurrentFileId;
  108. }
  109. // the uri is not relative. We need to find the correct file id
  110. const COLLADABU::URI* usedUri = 0;
  111. COLLADABU::URI uriWithoutFragment;
  112. if ( uri.getFragment().empty() )
  113. {
  114. // the passed uri has no fragment, we can use it without modification
  115. usedUri = &uri;
  116. }
  117. else
  118. {
  119. // the passed uri has a fragment, we need to make a copy without fragment
  120. uriWithoutFragment.set( uri.getScheme(), uri.getAuthority(), uri.getPath(), uri.getQuery(), COLLADAFW::Constants::EMPTY_STRING);
  121. usedUri = &uriWithoutFragment;
  122. }
  123. URIFileIdMap::iterator it = mURIFileIdMap.find( *usedUri );
  124. if ( it == mURIFileIdMap.end() )
  125. {
  126. COLLADAFW::FileId fileId = mNextFileId++;
  127. addFileIdUriPair( fileId, *usedUri );
  128. return fileId;
  129. }
  130. else
  131. {
  132. return it->second;
  133. }
  134. }
  135. //---------------------------------
  136. const COLLADABU::URI& Loader::getFileUri( COLLADAFW::FileId fileId )const
  137. {
  138. FileIdURIMap::const_iterator it = mFileIdURIMap.find( fileId );
  139. if ( it == mFileIdURIMap.end() )
  140. {
  141. return COLLADABU::URI::INVALID;
  142. }
  143. else
  144. {
  145. return it->second;
  146. }
  147. }
  148. //---------------------------------
  149. void Loader::addFileIdUriPair( COLLADAFW::FileId fileId, const COLLADABU::URI& uri )
  150. {
  151. mURIFileIdMap[uri] = fileId;
  152. mFileIdURIMap[fileId] = uri;
  153. }
  154. //---------------------------------
  155. bool Loader::loadDocument( const String& fileName, COLLADAFW::IWriter* writer )
  156. {
  157. if ( !writer )
  158. return false;
  159. mWriter = writer;
  160. mWriter->start();
  161. SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
  162. COLLADABU::URI rootFileUri(COLLADABU::URI::nativePathToUri(fileName));
  163. // the root file has always file id 0
  164. addFileIdUriPair( mNextFileId++, rootFileUri );
  165. bool abortLoading = false;
  166. while ( (mCurrentFileId < mNextFileId) && !abortLoading )
  167. {
  168. const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
  169. if ( (mCurrentFileId == 0)
  170. || !mExternalReferenceDeciderCallbackFunction
  171. || mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
  172. {
  173. FileLoader fileLoader(this,
  174. fileUri,
  175. &saxParserErrorHandler,
  176. mObjectFlags,
  177. mParsedObjectFlags,
  178. mExtraDataCallbackHandlerList );
  179. bool success = fileLoader.load();
  180. abortLoading = !success;
  181. }
  182. mCurrentFileId++;
  183. }
  184. if ( !abortLoading )
  185. {
  186. PostProcessor postProcessor(this,
  187. &saxParserErrorHandler,
  188. mObjectFlags,
  189. mParsedObjectFlags);
  190. postProcessor.postProcess();
  191. }
  192. else
  193. {
  194. mWriter->cancel("Generic error");
  195. }
  196. mWriter->finish();
  197. mParsedObjectFlags |= mObjectFlags;
  198. return !abortLoading;
  199. }
  200. //---------------------------------
  201. bool Loader::loadDocument( const String& uri, const char* buffer, int length, COLLADAFW::IWriter* writer )
  202. {
  203. if ( !writer )
  204. return false;
  205. mWriter = writer;
  206. SaxParserErrorHandler saxParserErrorHandler(mErrorHandler);
  207. COLLADABU::URI rootUri(uri);
  208. // the root file has always file id 0
  209. addFileIdUriPair( mNextFileId++, rootUri );
  210. bool abortLoading = false;
  211. while ( (mCurrentFileId < mNextFileId) && !abortLoading )
  212. {
  213. const COLLADABU::URI& fileUri = getFileUri( mCurrentFileId );
  214. if ( (mCurrentFileId == 0)
  215. || !mExternalReferenceDeciderCallbackFunction
  216. || mExternalReferenceDeciderCallbackFunction(fileUri, mCurrentFileId) )
  217. {
  218. FileLoader fileLoader(this,
  219. getFileUri( mCurrentFileId ),
  220. &saxParserErrorHandler,
  221. mObjectFlags,
  222. mParsedObjectFlags,
  223. mExtraDataCallbackHandlerList );
  224. bool success = fileLoader.load();
  225. abortLoading = !success;
  226. }
  227. mCurrentFileId++;
  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. mWriter->finish();
  242. mParsedObjectFlags |= mObjectFlags;
  243. return !abortLoading;
  244. }
  245. //---------------------------------
  246. bool Loader::registerExtraDataCallbackHandler ( IExtraDataCallbackHandler* extraDataCallbackHandler )
  247. {
  248. // Push the callback handler in the list of callback handlers.
  249. mExtraDataCallbackHandlerList.push_back ( extraDataCallbackHandler );
  250. return true;
  251. }
  252. //---------------------------------
  253. GeometryMaterialIdInfo& Loader::getMeshMaterialIdInfo( )
  254. {
  255. return mGeometryMaterialIdInfo;
  256. }
  257. //---------------------------------
  258. COLLADAFW::TextureMapId Loader::getTextureMapIdBySematic( const String& semantic )
  259. {
  260. StringTextureMapIdMap::iterator it = mTextureMapSemanticTextureMapIdMap.find(semantic);
  261. if ( it == mTextureMapSemanticTextureMapIdMap.end() )
  262. {
  263. return mTextureMapSemanticTextureMapIdMap[semantic] = mNextTextureMapId++;
  264. }
  265. else
  266. {
  267. return it->second;
  268. }
  269. }
  270. //-----------------------------
  271. bool Loader::compare( const COLLADAFW::SkinController& lhs, const COLLADAFW::SkinController& rhs )
  272. {
  273. if (lhs.getSkinControllerData() < rhs.getSkinControllerData() )
  274. return true;
  275. if (lhs.getSkinControllerData() > rhs.getSkinControllerData() )
  276. return false;
  277. if (lhs.getSource() < rhs.getSource() )
  278. return true;
  279. if (lhs.getSource() > rhs.getSource() )
  280. return false;
  281. const COLLADAFW::UniqueIdArray& lhsJoints = lhs.getJoints();
  282. const COLLADAFW::UniqueIdArray& rhsJoints = rhs.getJoints();
  283. size_t lhsJointsCount = lhsJoints.getCount();
  284. size_t rhsJointsCount = rhsJoints.getCount();
  285. if (lhsJointsCount < rhsJointsCount )
  286. return true;
  287. if (lhsJointsCount > rhsJointsCount )
  288. return false;
  289. for ( size_t i = 0; i < lhsJointsCount; ++i)
  290. {
  291. const COLLADAFW::UniqueId& lhsJoint = lhsJoints[i];
  292. const COLLADAFW::UniqueId& rhsJoint = rhsJoints[i];
  293. if (lhsJoint < rhsJoint )
  294. return true;
  295. if (lhsJoint > rhsJoint )
  296. return false;
  297. }
  298. return false;
  299. }
  300. //------------------------------
  301. void Loader::registerExternalReferenceDeciderCallbackFunction( ExternalReferenceDeciderCallbackFunction externalReferenceDeciderCallbackFunction )
  302. {
  303. mExternalReferenceDeciderCallbackFunction = externalReferenceDeciderCallbackFunction;
  304. }
  305. } // namespace COLLADA