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 #ifndef __COLLADA_LOADER_H__ 12 #define __COLLADA_LOADER_H__ 13 14 #include "COLLADASaxFWLPrerequisites.h" 15 #include "COLLADASaxFWLGeometryMaterialIdInfo.h" 16 #include "COLLADASaxFWLSidTreeNode.h" 17 #include "COLLADASaxFWLKinematicsIntermediateData.h" 18 #include "COLLADASaxFWLTypes.h" 19 20 #include "COLLADAFWILoader.h" 21 #include "COLLADAFWLoaderUtils.h" 22 #include "COLLADAFWUniqueId.h" 23 #include "COLLADAFWTypes.h" 24 #include "COLLADAFWSkinController.h" 25 #include "COLLADAFWInstanceController.h" 26 27 #include "COLLADABUHashFunctions.h" 28 #include "COLLADABUURI.h" 29 #include "COLLADABUhash_map.h" 30 31 #include <set> 32 33 namespace COLLADAFW 34 { 35 class IWriter; 36 class VisualScene; 37 class LibraryNodes; 38 class Effect; 39 class Light; 40 class Camera; 41 class Formula; 42 class AnimationList; 43 class MorphController; 44 } 45 46 47 namespace COLLADASaxFWL 48 { 49 50 class IErrorHandler; 51 class DocumentProcessor; 52 class PostProcessor; 53 class FileLoader; 54 55 56 typedef std::list<String> StringList; 57 58 typedef std::list<COLLADABU::URI> URIList; 59 60 static StringList EMPTY_STRING_LIST = StringList(); 61 62 63 64 /** Loader to a COLLADA document and all the documents that are referenced it.*/ 65 class Loader : public COLLADAFW::ILoader 66 { 67 public: 68 69 typedef std::map<String, COLLADAFW::TextureMapId> StringTextureMapIdMap; 70 71 /** Flags for each type of object that are passed by the IWriter interface. */ 72 enum ObjectFlags 73 { 74 NO_FLAG = 0, 75 ASSET_FLAG = 1<< 0, 76 SCENE_FLAG = 1<< 1, 77 VISUAL_SCENES_FLAG = 1<< 2, 78 LIBRARY_NODES_FLAG = 1<< 3, 79 GEOMETRY_FLAG = 1<< 4, 80 MATERIAL_FLAG = 1<< 5, 81 EFFECT_FLAG = 1<< 6, 82 CAMERA_FLAG = 1<< 7, 83 IMAGE_FLAG = 1<< 8, 84 LIGHT_FLAG = 1<< 9, 85 ANIMATION_FLAG = 1<<10, 86 ANIMATION_LIST_FLAG = 1<<11, 87 SKIN_CONTROLLER_DATA_FLAG = 1<<12, 88 CONTROLLER_FLAG = 1<<13, 89 FORMULA_FLAG = 1<<14, 90 KINEMATICS_FLAG = 1<<15, 91 ANIMATION_CLIP_FLAG = 1<<16, 92 93 ALL_OBJECTS_MASK = (1<<17) - 1, 94 }; 95 96 public: 97 typedef COLLADABU::hash_map<COLLADABU::URI, COLLADAFW::UniqueId> URIUniqueIdMap; 98 99 typedef COLLADABU::hash_map<COLLADABU::URI, COLLADAFW::FileId> URIFileIdMap; 100 101 /** Maps file id to uri.*/ 102 typedef std::map<COLLADAFW::FileId, COLLADABU::URI> FileIdURIMap; 103 104 /** Maps the id of a collada element to the corresponding sit tree node.*/ 105 typedef std::map<String /*id*/, SidTreeNode*> IdStringSidTreeNodeMap; 106 107 /** Maps unique ids of animation list to the corresponding animation list.*/ 108 typedef std::map< COLLADAFW::UniqueId , COLLADAFW::AnimationList* > UniqueIdAnimationListMap; 109 110 /** List of visual scenes.*/ 111 typedef std::vector<COLLADAFW::VisualScene*> VisualSceneList; 112 113 /** List of library nodes.*/ 114 typedef std::vector<COLLADAFW::LibraryNodes*> LibraryNodesList; 115 116 /** List of effects.*/ 117 typedef std::vector<COLLADAFW::Effect*> EffectList; 118 119 /** List of lights.*/ 120 typedef std::vector<COLLADAFW::Light*> LightList; 121 122 /** List of cameras.*/ 123 typedef std::vector<COLLADAFW::Camera*> CameraList; 124 125 /** List of morph controller.*/ 126 typedef std::vector<COLLADAFW::MorphController*> MorphControllerList; 127 128 struct JointSidsOrIds 129 { JointSidsOrIdsJointSidsOrIds130 JointSidsOrIds():areIds(true){} 131 132 /** List of sids or ids.*/ 133 StringList sidsOrIds; 134 /** True if sidsOrIds contains ids, false if sidsOrIds contains sids.*/ 135 bool areIds; 136 }; 137 138 /** Maps unique ids of skin data to the sids or ids of the joints of this skin controller.*/ 139 typedef std::map< COLLADAFW::UniqueId, JointSidsOrIds> SkinDataJointSidsMap; 140 141 /** Maps unique ids of skin data to the source uri string.*/ 142 typedef std::map< COLLADAFW::UniqueId/*skin controller data*/, COLLADABU::URI/*source uri string*/> SkinDataSkinSourceMap; 143 144 /** Set of SkinControllers.*/ 145 typedef std::set< COLLADAFW::SkinController, bool(*)(const COLLADAFW::SkinController& lhs, const COLLADAFW::SkinController& rhs)> SkinControllerSet; 146 147 /** Data that needs to be store, intermediately, to assign controllers. One struct for each 148 instance controller.*/ 149 struct InstanceControllerData 150 { 151 /** List of URIs of the skeleton roots, ie the uris in the COLLADA skeleton element.*/ 152 URIList skeletonRoots; 153 154 /** The instance controller that instantiates the controller.*/ 155 COLLADAFW::InstanceController* instanceController; 156 }; 157 158 /** List of all instance controllers that reference the same controller, ie share the same skin 159 data for skin controllers.*/ 160 typedef std::list<InstanceControllerData> InstanceControllerDataList; 161 162 /** Maps each controller data unique id to the list of nodes instantiating it.*/ 163 typedef std::map<COLLADAFW::UniqueId,InstanceControllerDataList> InstanceControllerDataListMap; 164 165 166 /** List of formulas.*/ 167 typedef std::map<COLLADAFW::UniqueId, COLLADAFW::Formula*> UniqueIdFormulaMap; 168 169 /** Contains the binding of an animation to the referenced object. Required to create animation lists*/ 170 struct AnimationSidAddressBinding 171 { AnimationSidAddressBindingAnimationSidAddressBinding172 AnimationSidAddressBinding( const AnimationInfo& _animationInfo, const SidAddress& _sidAddress) 173 : animationInfo(_animationInfo), sidAddress(_sidAddress) {} 174 AnimationInfo animationInfo; 175 176 SidAddress sidAddress; 177 }; 178 179 /** List of UniqueIdSidAddressPairs.*/ 180 typedef std::vector< AnimationSidAddressBinding > AnimationSidAddressBindingList; 181 182 /** Function pointer to functions provided to registerExternalReferenceDeciderCallbackFunction.*/ 183 typedef bool (*ExternalReferenceDeciderCallbackFunction)( const COLLADABU::URI&, COLLADAFW::FileId ); 184 185 public: 186 const static InstanceControllerDataList EMPTY_INSTANCE_CONTROLLER_DATALIST; 187 static const JointSidsOrIds EMPTY_JOINTSIDSORIDS; 188 189 private: 190 /** The version of the collada document.*/ 191 COLLADAVersion mCOLLADAVersion; 192 193 FileLoader * mFileLoader; 194 195 /** Loader utils that will help us to fill the model.*/ 196 COLLADAFW::LoaderUtils mLoaderUtil; 197 198 /** The writer that will be fed by this loader.*/ 199 COLLADAFW::IWriter* mWriter; 200 201 /** List of registered extra data callback handlers. */ 202 ExtraDataCallbackHandlerList mExtraDataCallbackHandlerList; 203 204 /** Maps each already processed dae element to its COLLADAFW::UniqueId. */ 205 URIUniqueIdMap mURIUniqueIdMap; 206 207 /** Maps each uri to the file id assigned to it. The Uris need to have empty fragments.*/ 208 URIFileIdMap mURIFileIdMap; 209 210 /** Maps each file id, already assigned to an uri, to that uri.*/ 211 FileIdURIMap mFileIdURIMap; 212 213 /** The file id that will be used for the next file.*/ 214 COLLADAFW::FileId mNextFileId; 215 216 /** The file id of the file currently being loaded.*/ 217 COLLADAFW::FileId mCurrentFileId; 218 219 /** Maps the unique id of each geometry to the corresponding GeometryMaterialIdInfo.*/ 220 GeometryMaterialIdInfo mGeometryMaterialIdInfo; 221 222 /** The error handler to pass the errors to.*/ 223 IErrorHandler* mErrorHandler; 224 225 /** The TextureMapId that will be assigned to the next unknown texture map semantic.*/ 226 COLLADAFW::TextureMapId mNextTextureMapId; 227 228 /** Maps the semantic name of a texture map to the TextureMapId used in the framework.*/ 229 StringTextureMapIdMap mTextureMapSemanticTextureMapIdMap; 230 231 /** A combination of ObjectFlags, indicating which objects should be parsed during the 232 parse process.*/ 233 int mObjectFlags; 234 235 /** A combination of ObjectFlags, indicating which objects have be parsed already.*/ 236 int mParsedObjectFlags; 237 238 /** The root node of the sid tree. This tree is used to resolve sids.*/ 239 SidTreeNode *mSidTreeRoot; 240 241 /** Maps the id of a collada element to the corresponding sit tree node.*/ 242 IdStringSidTreeNodeMap mIdStringSidTreeNodeMap; 243 244 /** List of all visual scenes in the file. They are send to the writer and deleted, when the file has 245 completely been parsed.*/ 246 VisualSceneList mVisualScenes; 247 248 /** List of all library nodes in the file. They are send to the writer and deleted, when the file has 249 completely been parsed.*/ 250 LibraryNodesList mLibraryNodes; 251 252 /** List of all effects in the file. They are send to the writer and deleted, when the file has 253 completely been parsed.*/ 254 EffectList mEffects; 255 256 /** List of all lights in the file. They are send to the writer and deleted, when the file has 257 completely been parsed.*/ 258 LightList mLights; 259 260 /** List of all cameras in the file. They are send to the writer and deleted, when the file has 261 completely been parsed.*/ 262 CameraList mCameras; 263 264 /** List of all effects in the file. They are send to the writer and deleted, when the file has 265 completely been parsed. This is required to assign animations of the morph weights.*/ 266 MorphControllerList mMorphControllerList; 267 268 /** Maps unique ids of skin data to the sids or ids of the joints of this skin controller.*/ 269 SkinDataJointSidsMap mSkinDataJointSidsMap; 270 271 /** Maps the Unique generated from the id of the COLLADA controller element to the 272 InstanceControllerDataList containing all instance controllers that reference the same controller.*/ 273 InstanceControllerDataListMap mInstanceControllerDataListMap; 274 275 /** Maps unique ids of skin data to the source uri string.*/ 276 SkinDataSkinSourceMap mSkinDataSkinSourceMap; 277 278 /** Set of all SkinController already created and written.*/ 279 SkinControllerSet mSkinControllerSet; 280 281 282 /** Maps unique ids of animation list to the corresponding animation list. All animation list in this map 283 will be deleted by the FileLoader.*/ 284 UniqueIdAnimationListMap mUniqueIdAnimationListMap; 285 286 /** Intermediate data to build up the kinematics after the COLLADA file has been parsed.*/ 287 KinematicsIntermediateData mKinematicsIntermediateData; 288 289 /** Maps ids of all formulas in the file to the formula itself. They are send to the writer and deleted, when the file has 290 completely been parsed. This is required to resolve referenced elements like parameters and other formulas.*/ 291 UniqueIdFormulaMap mFormulasMap; 292 293 /** List all the connections of animations and sid addresses of the targets. 294 TODO: This list has to become a member of FileLoader. The animation post processing needs to be done per 295 file in FileLoader, since the SidAddresses stored in this List are only valid within the file they were 296 found.*/ 297 AnimationSidAddressBindingList mAnimationSidAddressBindings; 298 299 /** The call back function used to decide which filed should be leaded.*/ 300 ExternalReferenceDeciderCallbackFunction mExternalReferenceDeciderCallbackFunction; 301 302 public: 303 304 /** Constructor. */ 305 Loader( IErrorHandler* errorHandler = 0 ); 306 307 /** Destructor. */ 308 virtual ~Loader(); 309 310 /** The version of the collada document.*/ getCOLLADAVersion()311 COLLADAVersion getCOLLADAVersion() const { return mCOLLADAVersion; } 312 getFileLoader()313 const FileLoader * getFileLoader() const { return mFileLoader; } 314 getAnimationSidAddressBindingList()315 AnimationSidAddressBindingList & getAnimationSidAddressBindingList() { return mAnimationSidAddressBindings; } 316 317 /** Starts loading the model and feeds the writer with data. 318 @param fileName The name of the file that should be loaded. 319 @param writer The writer that should be fed with data. 320 @return True, if loading succeeded, false otherwise.*/ 321 virtual bool loadDocument(const String& fileName, COLLADAFW::IWriter* writer ); 322 323 /** Starts loading the model and feeds the writer with data. 324 @param buffer A pointer to a document buffer that should be loaded. 325 @param uri The URI associated with the buffer. 326 @param length The length of the buffer in bytes. 327 @param writer The writer that should be fed with data. 328 @return True, if loading succeeded, false otherwise.*/ 329 virtual bool loadDocument( const String& uri, const char* buffer, int length, COLLADAFW::IWriter* writer ); 330 331 /** Sets the flags indicating which objects should be loaded. 332 @param objectFlags The flags indicating which objects should be loaded.*/ setObjectFlags(int objectFlags)333 void setObjectFlags( int objectFlags ) { mObjectFlags = objectFlags; } 334 335 /** Register an extra data callback handler. 336 * @param ExtraDataCallbackHandler* extraDataCallbackHandler The callback handler to register. 337 * @return bool True, if the handler could be registered successfull. */ 338 bool registerExtraDataCallbackHandler( IExtraDataCallbackHandler* extraDataCallbackHandler ); 339 340 /** Register a decider function, used to decide if external references should be loaded. This 341 function is called, before an external file should be loaded. If the function returns true, the 342 external is loaded, otherwise the file is omitted. If no function is registered, all external files 343 will be loaded. 344 To unregister call with externalReferenceDeciderCallbackFunction = 0 345 The parameters of the callback function are the uri of the external file and its FileId used in 346 corresponding UniqueIds. 347 * @param externalReferenceDeciderCallbackFunction The callback function to register. 348 */ 349 void registerExternalReferenceDeciderCallbackFunction( ExternalReferenceDeciderCallbackFunction externalReferenceDeciderCallbackFunction ); 350 351 352 /** Returns the Uri the file id @a fileId was assigned to by getFileId(). If @a fileId has not been 353 assigned to any Uri, an invalid uri is returned.*/ 354 const COLLADABU::URI& getFileUri( COLLADAFW::FileId fileId )const; 355 356 /** Maps the Unique generated from the id of the COLLADA controller element to the 357 InstanceControllerDataList containing all instance controllers that reference the same controller.*/ getInstanceControllerDataListMap()358 InstanceControllerDataListMap& getInstanceControllerDataListMap() { return mInstanceControllerDataListMap; } 359 360 /** Returns the COLLADAFW::UniqueId of the element with uri @a uri. If the uri has been 361 passed to this method before, the same COLLADAFW::UniqueId will be returned, if not, a 362 new one is created. 363 @param uri The uri of the element to get the COLLADAFW::UniqueId for 364 @param classId The COLLADAFW::ClassId of the object that will be created for @a element. 365 @return The elements COLLADAFW::UniqueId */ 366 const COLLADAFW::UniqueId& getUniqueId(const COLLADABU::URI& uri, COLLADAFW::ClassId classId); 367 368 /** Returns the COLLADAFW::UniqueId of the element with uri @a uri. If the uri has been 369 passed to this method before, the same COLLADAFW::UniqueId will be returned, if not, an 370 invalid unique id will be returned. 371 @param uri The uri of the element to get the COLLADAFW::UniqueId for 372 @return The elements COLLADAFW::UniqueId or COLLADAFW::UniqueId::INVALID*/ 373 const COLLADAFW::UniqueId& getUniqueId(const COLLADABU::URI& uri); 374 375 /** Returns the COLLADAFW::UniqueId of an element with no uri. At each call a new 376 COLLADAFW::UniqueId will be created and returned. Use this member for collada elements that 377 do not have an id. 378 @param classId The COLLADAFW::ClassId of the object that will be created for @a element. 379 @return The elements COLLADAFW::UniqueId */ 380 COLLADAFW::UniqueId getUniqueId(COLLADAFW::ClassId classId); 381 382 /** Returns the map of COLLADAFW::URIs to COLLADAFW::UniqueIds. This can be used, for example, 383 to figure out the original ID or target attribute of an input element from the relevant UniqueId. 384 @preturn The URIUniqueIdMap for this loader. */ 385 const URIUniqueIdMap& getUniqueIdMap(void) const; 386 387 private: 388 friend class IFilePartLoader; 389 friend class FileLoader; 390 friend class PostProcessor; 391 friend class DocumentProcessor; 392 393 /** The version of the collada document.*/ setCOLLADAVersion(COLLADAVersion cOLLADAVersion)394 void setCOLLADAVersion(COLLADAVersion cOLLADAVersion) { mCOLLADAVersion = cOLLADAVersion; } 395 396 /** The error handler to pass the errors to.*/ getErrorHandler()397 IErrorHandler* getErrorHandler() {return mErrorHandler;} 398 399 /** Returns the file id of the file pointed to by the path in @a uri. If @a uri is relative, 400 the file id of the current file is returned. If the an uri with the same path has been passed to 401 this method before, the same file id is returned, if not a new one is created.*/ 402 COLLADAFW::FileId getFileId(const COLLADABU::URI& uri); 403 404 /** Add the pair of @a fileId and @a uri to mURIFileIdMap and mFileIdURIMap. It is assumed, neither 405 @a fileId nor @a uri have been passed to that method before.*/ 406 void addFileIdUriPair( COLLADAFW::FileId fileId, const COLLADABU::URI& uri ); 407 408 /** Returns the GeometryMaterialIdInfo to map symbols to ids*/ 409 GeometryMaterialIdInfo& getMeshMaterialIdInfo( ); 410 411 /** Returns TextureMapId for @a semantic. Successive call with same semantic return the same TextureMapId.*/ 412 COLLADAFW::TextureMapId getTextureMapIdBySematic( const String& semantic ); 413 414 /** The root node of the sid tree. This tree is used to resolve sids.*/ getSidTreeRoot()415 SidTreeNode * getSidTreeRoot() { return mSidTreeRoot; } 416 417 /** Maps the id of a collada element to the corresponding sit tree node.*/ getIdStringSidTreeNodeMap()418 IdStringSidTreeNodeMap& getIdStringSidTreeNodeMap() { return mIdStringSidTreeNodeMap; } 419 420 /** List of all visual scenes in the file. They are send to the writer and deleted, when the file has 421 completely been parsed.*/ getVisualScenes()422 VisualSceneList& getVisualScenes() { return mVisualScenes; } 423 424 /** List of all library nodes in the file. They are send to the writer and deleted, when the file has 425 completely been parsed.*/ getLibraryNodes()426 LibraryNodesList& getLibraryNodes() { return mLibraryNodes; } 427 428 /** List of all effects in the file. They are send to the writer and deleted, when the file has 429 completely been parsed.*/ getEffects()430 EffectList& getEffects() { return mEffects; } 431 432 /** List of all lights in the file. They are send to the writer and deleted, when the file has 433 completely been parsed.*/ getLights()434 LightList& getLights() { return mLights; } 435 436 /** List of all cameras in the file. They are send to the writer and deleted, when the file has 437 completely been parsed.*/ getCameras()438 CameraList& getCameras() { return mCameras; } 439 440 /** Returns the intermediate data to build up the kinematics after the COLLADA file has been parsed.*/ getKinematicsIntermediateData()441 KinematicsIntermediateData& getKinematicsIntermediateData() { return mKinematicsIntermediateData; } 442 443 /** Maps ids of all formulas in the file to the formula itself. They are send to the writer and deleted, when the file has 444 completely been parsed. This is required to resolve referenced elements like parameters and other formulas.*/ getFormulasMap()445 UniqueIdFormulaMap& getFormulasMap() { return mFormulasMap; } 446 447 /** List all the connections of animations and sid addresses of the targets.*/ getAnimationSidAddressBindings()448 AnimationSidAddressBindingList& getAnimationSidAddressBindings() { return mAnimationSidAddressBindings; } 449 450 /** Maps unique ids of animation list to the corresponding animation list. All animation list in this map 451 will be deleted by the FileLoader.*/ getUniqueIdAnimationListMap()452 UniqueIdAnimationListMap& getUniqueIdAnimationListMap() { return mUniqueIdAnimationListMap; } 453 454 /** List of all effects in the file. They are send to the writer and deleted, when the file has 455 completely been parsed. This is required to assign animations of the morph weights.*/ getMorphControllerList()456 MorphControllerList& getMorphControllerList() { return mMorphControllerList; } 457 458 /** Maps unique ids of skin data to the sids or ids of the joints of this skin controller.*/ getSkinDataJointSidsMap()459 SkinDataJointSidsMap& getSkinDataJointSidsMap() { return mSkinDataJointSidsMap; } 460 461 /** Maps unique ids of skin data to the source uri string.*/ getSkinDataSkinSourceMap()462 SkinDataSkinSourceMap& getSkinDataSkinSourceMap() { 463 return mSkinDataSkinSourceMap; 464 } 465 466 /** Set of all SkinController already created and written.*/ getSkinControllerSet()467 SkinControllerSet& getSkinControllerSet() { return mSkinControllerSet; } 468 469 /** Compares to SkinControllers. The comparison is suitable for using SkinController as key in stl 470 containers but has no deeper meaning. The unique id of the SkinControllers themselves is not 471 taken into account. Is basically compares if two SkinControllers describe exactly the same skin controller 472 i.e. have the same source, joints and SkinControllerData.*/ 473 static bool compare( const COLLADAFW::SkinController& lhs, const COLLADAFW::SkinController& rhs); 474 475 /** Returns the writer the data will be written to.*/ writer()476 COLLADAFW::IWriter* writer(){ return mWriter; } 477 478 479 /** Disable default copy ctor. */ 480 Loader( const Loader& pre ); 481 482 /** Disable default assignment operator. */ 483 const Loader& operator= ( const Loader& pre ); 484 485 486 }; 487 488 } // namespace COLLADA 489 490 #endif // __COLLADA_LOADER_H__ 491