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