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 __COLLADASAXFWL_IFILEPARTLOADER_H__
12 #define __COLLADASAXFWL_IFILEPARTLOADER_H__
13 
14 #include "COLLADASaxFWLPrerequisites.h"
15 #include "COLLADASaxFWLTypes.h"
16 #include "COLLADASaxFWLSaxFWLError.h"
17 #include "COLLADASaxFWLXmlTypes.h"
18 #include "COLLADASaxFWLLoader.h"
19 #include "COLLADASaxFWLExtraDataLoader.h"
20 
21 #include "COLLADAFWUniqueId.h"
22 #include "COLLADAFWInstanceController.h"
23 
24 #include <list>
25 #include <map>
26 
27 
28 namespace COLLADASaxFWL14
29 {
30     class ColladaParserAutoGen14;
31     class ColladaParserAutoGen14Private;
32 }
33 namespace COLLADASaxFWL15
34 {
35     class ColladaParserAutoGen15;
36     class ColladaParserAutoGen15Private;
37 }
38 namespace COLLADAFW
39 {
40 	class IWriter;
41 	class Object;
42 	class Animatable;
43 	class AnimationList;
44 	class MorphController;
45 }
46 
47 namespace COLLADABU
48 {
49 	class URI;
50 }
51 
52 namespace COLLADASaxFWL
53 {
54 //	class Loader;
55 	class FileLoader;
56 	class GeometryMaterialIdInfo;
57 	class SidTreeNode;
58 	class SidAddress;
59     class RootParser14;
60     class RootParser15;
61     class IParserImpl;
62 	class IntermediateTargetable;
63 
64     /** Base class for all loaders that load parts of files or entire files */
65     class IFilePartLoader : public ExtraDataLoader
66 	{
67 	public:
68 
69         friend class RootParser14;
70         friend class RootParser15;
71 
72 	private:
73 
74 		/** The currently working file part loader.*/
75 		IFilePartLoader* mPartLoader;
76 
77         /** Object derived from a generated parser. */
78         IParserImpl* mParserImpl;
79 
80     public:
81 
82         /** Constructor. */
83         IFilePartLoader();
84 
85         /** Destructor. */
86         virtual ~IFilePartLoader();
87 
88 		/** Returns a pointer to the collada loader. */
89 		virtual Loader* getColladaLoader() =0;
90 
91 		/** Returns a const pointer to the collada document. */
92 		virtual const Loader* getColladaLoader()const =0;
93 
94 		/** Returns the writer the data will be written to.*/
95 		COLLADAFW::IWriter* writer();
96 
97 		/** Reports an error to the error handler. If this method returns true, the
98 		loader stops parsing immediately. If severity is not CRITICAL and this method
99 		returns true, the loader continues loading. */
100 		bool handleFWLError( const SaxFWLError& saxFWLError );
101 
102 		/** Reports an error to the error handler. If this method returns true, the
103 		loader stops parsing immediately. If severity is not CRITICAL and this method
104 		returns true, the loader continues loading.
105 		@param errorType The type of the error.
106 		@param errorMessage The error message describing the error.
107 		@param reportLineAndColumnNumber If true, the current line and number of the xml parser are set.
108 		@param severity The severity of the error. */
109 		bool handleFWLError( SaxFWLError::ErrorType errorType,
110 			              String errorMessage,
111 			              IError::Severity severity = IError::SEVERITY_ERROR_NONCRITICAL );
112 
113 		/** Returns the COLLADAFW::UniqueId of the element with uri @a uriString. If the uri has been
114 		passed to this method before, the same 	COLLADAFW::UniqueId will be returned, if not, a
115 		new one is created.
116 		@param uriString The uriString of the element to get the COLLADAFW::UniqueId for
117 		@param classId The COLLADAFW::ClassId of the object that will be created for @a element.
118 		@return The elements COLLADAFW::UniqueId */
119 		const COLLADAFW::UniqueId& createUniqueId(const String& uriString, COLLADAFW::ClassId classId);
120 
121 		/** Returns the COLLADAFW::UniqueId of the element with uri @a uri. If the uri has been
122 		passed to this method before, the same 	COLLADAFW::UniqueId will be returned,  if not, an
123 		invalid unique id will be returned.
124 		@param uriString The uriString of the element to get the COLLADAFW::UniqueId for
125 		@return The elements COLLADAFW::UniqueId or COLLADAFW::UniqueId::INVALID*/
126 		const COLLADAFW::UniqueId& getUniqueIdByUrl(const String& uriString);
127 
128 		/** Returns the COLLADAFW::UniqueId of the element with id  @a colladaId in the current file.
129 		If the id within this file has been passed to this method before, the same 	COLLADAFW::UniqueId
130 		will be returned, if not, a new one is created.
131 		@param id The collada id of the element to get the COLLADAFW::UniqueId for
132 		@param classId The COLLADAFW::ClassId of the object that will be created for @a element.
133 		@return The elements COLLADAFW::UniqueId */
134 		COLLADAFW::UniqueId createUniqueIdFromId( const ParserChar* colladaId, COLLADAFW::ClassId classId );
135 
136 		/** Returns the COLLADAFW::UniqueId of the element with id @a colladaId  in the current document. If the
137 		colladaId has been	passed to this method before while in the same file, the same COLLADAFW::UniqueId will
138 		be returned, if not, an invalid unique id will be returned.
139 		@param id The id of the element to get the COLLADAFW::UniqueId for
140 		@return The elements COLLADAFW::UniqueId or COLLADAFW::UniqueId::INVALID*/
141 		const COLLADAFW::UniqueId& getUniqueIdById(const ParserChar* colladaId);
142 
143 		/** Returns the COLLADAFW::UniqueId of the element referenced by the url  @a url. If the has
144 		been passed to this method before, the same COLLADAFW::UniqueId will be returned, if not,
145 		a new one is created.
146 		@param url The url of the element to get the COLLADAFW::UniqueId for
147 		@param classId The COLLADAFW::ClassId of the object that will be created for @a element.
148 		@return The elements COLLADAFW::UniqueId */
149 		const COLLADAFW::UniqueId& createUniqueIdFromUrl( const ParserChar* url, COLLADAFW::ClassId classId );
150 
151 		/** Returns the COLLADAFW::UniqueId of the element referenced by the url  @a url. If the has
152 		been passed to this method before, the same COLLADAFW::UniqueId will be returned, if not,
153 		a new one is created.
154 		@param url The url of the element to get the COLLADAFW::UniqueId for
155 		@param classId The COLLADAFW::ClassId of the object that will be created for @a element.
156 		@param isAbsolute If true, the url is assumed to be absolute, otherwise it will be made absolute
157 		using the current file urie.
158 		@return The elements COLLADAFW::UniqueId */
159 		const COLLADAFW::UniqueId& createUniqueIdFromUrl( const COLLADABU::URI& url, COLLADAFW::ClassId classId, bool isAbsolute = false );
160 
161 		/** Returns the COLLADAFW::UniqueId of the element referenced by the url  @a url. If the has
162 		been passed to this method before, the same COLLADAFW::UniqueId will be returned,   if not, an
163 		invalid unique id will be returned.
164 		@param uriString The uriString of the element to get the COLLADAFW::UniqueId for
165 		@param isAbsolute If true, the url is assumed to be absolute, otherwise it will be made absolute
166 		using the current file uri.
167 		@return The elements COLLADAFW::UniqueId or COLLADAFW::UniqueId::INVALID*/
168 		const COLLADAFW::UniqueId& getUniqueIdByUrl( const COLLADABU::URI& url, bool isAbsolute = false  );
169 
170 		/** Returns the COLLADAFW::UniqueId of an element with no uri.  At each call a new
171 		COLLADAFW::UniqueId will be created and returned. Use this member for collada elements that
172 		do not have an id.
173 		@param classId The COLLADAFW::ClassId of the object that will be created for @a element.
174 		@return The elements COLLADAFW::UniqueId */
175 		COLLADAFW::UniqueId createUniqueId(COLLADAFW::ClassId classId);
176 
177 		/** Returns the GeometryMaterialIdInfo to map symbols to ids*/
178 		GeometryMaterialIdInfo& getMeshMaterialIdInfo( );
179 
180 		/** Returns TextureMapId for @a semantic. Successive call with same semantic return the same TextureMapId.*/
181 		COLLADAFW::TextureMapId getTextureMapIdBySematic( const String& semantic );
182 
183 		/** Creates a new in the sid tree. Call this method for every collada element that has an sid or that has an id
184 		and can have children with sids. For every call of this method you have to call addToSidTree() when the element
185 		is closed.
186 		@param id The id of the element. Might be 0;
187 		@param sid The sid of the element. Might be 0;
188 		*/
189 		SidTreeNode*  addToSidTree( const char* colladaId, const char* colladaSid );
190 
191 		/** Creates a new node in the sid tree. Call this method for every collada element that has an sid or that has an id
192 		and can have children with sids. For every call of this method you have to call moveUpInSidTree() when the element
193 		is closed.
194 		@param id The id of the element. Might be 0;
195 		@param sid The sid of the element. Might be 0;
196 		@param target The target assigned to the sid tree node
197 		*/
198 		SidTreeNode*  addToSidTree( const char* colladaId, const char* colladaSid, COLLADAFW::Object* target );
199 
200 		/** Creates a new node in the sid tree. Call this method for every collada element that has an sid or that has an id
201 		and can have children with sids. For every call of this method you have to call moveUpInSidTree() when the element
202 		is closed.
203 		@param id The id of the element. Might be 0;
204 		@param sid The sid of the element. Might be 0;
205 		@param target The target assigned to the sid tree node
206 		*/
207 		SidTreeNode*  addToSidTree( const char* colladaId, const char* colladaSid, COLLADAFW::Animatable* target );
208 
209 		/** Creates a new node in the sid tree. Call this method for every collada element that has an sid or that has an id
210 		and can have children with sids. For every call of this method you have to call moveUpInSidTree() when the element
211 		is closed.
212 		@param id The id of the element. Might be 0;
213 		@param sid The sid of the element. Might be 0;
214 		@param target The target assigned to the sid tree node
215 		*/
216 		SidTreeNode*  addToSidTree( const char* colladaId, const char* colladaSid, IntermediateTargetable* target );
217 
218 		/** Moves one node up in the sid tree. Call this method whenever an element, for which addToSidTree() was
219 		called, is closed.*/
220 		void  moveUpInSidTree();
221 
222 		/** Tries to resolve the a sidaddress. If resolving failed, null is returned.*/
223 		const SidTreeNode* resolveSid( const SidAddress& sidAddress);
224 
225 		/** Stores the bindig of an animation to an object, referenced by @a targetSidAddress.*/
226 		void addToAnimationSidAddressBindings( const AnimationInfo& animationInfo, const SidAddress& targetSidAddress);
227 
228 		/** Returns the animation list with Unique id @a animationListUniqueId. If it could not be found, a new map
229 		entry is created.*/
230 		COLLADAFW::AnimationList*& getAnimationListByUniqueId( const COLLADAFW::UniqueId& animationListUniqueId);
231 
232 		/** Adds the pair @a skinDataUniqueId, @a jointSids to mSkinDataJointSidsMap.*/
233 		void addSkinDataJointSidsPair( const COLLADAFW::UniqueId& skinDataUniqueId, const StringList& sidsOrIds, bool areIds );
234 
235 		/** Adds the pair @a skinDataUniqueId, @a skinSource to mSkinDataSkinSourceMap.*/
236 		void addSkinDataSkinSourcePair( const COLLADAFW::UniqueId& skinDataUniqueId, const COLLADABU::URI& skinSource );
237 
238 		/** Adds @a morphController to the list of morph controllers. The morph controller will be deleted after
239 		if has been written through the IWriter interface.*/
240 		void addMorphController( COLLADAFW::MorphController* morphController);
241 
242 		/** Returns the sids or ids of the nodes used by a skin controller using skin data with unique id
243 		@a skinDataUniqueId*/
244 		const Loader::JointSidsOrIds& getJointSidsOrIdsBySkinDataUniqueId(const COLLADAFW::UniqueId& skinDataUniqueId) const;
245 
246 		/** Returns the mapping of the Unique generated from the id of the COLLADA controller element to the
247 		InstanceControllerDataList containing all instance controllers that reference the same controller.*/
248 		const Loader::InstanceControllerDataListMap& getInstanceControllerDataListMap() const ;
249 
250 		/** Returns the InstanceControllerDataList of the controller with Unique @a controllerUniqueId.*/
251 		const Loader::InstanceControllerDataList& getInstanceControllerDataListByControllerUniqueId(const COLLADAFW::UniqueId& controllerUniqueId)const;
252 
253 		/** Returns the InstanceControllerDataList of the controller with Unique @a controllerUniqueId.*/
254 		Loader::InstanceControllerDataList& getInstanceControllerDataListByControllerUniqueId(const COLLADAFW::UniqueId& controllerUniqueId);
255 
256 
257 		/** After this functions, the next sax callback should be caught by this the file part loader.*/
258 		void setMeAsParser();
259 
260         /** Sets the parser to @a parserToBeSet.*/
261         virtual void setParser( COLLADASaxFWL14::ColladaParserAutoGen14* parserToBeSet )=0;
262         /** Sets the parser to @a parserToBeSet.*/
263         virtual void setParser( COLLADASaxFWL15::ColladaParserAutoGen15* parserToBeSet )=0;
264 
265         /** Sets abstract parser implementation. */
setParserImpl(IParserImpl * parserImpl)266         void setParserImpl( IParserImpl* parserImpl ){mParserImpl = parserImpl;}
267         /** Returns currently set parser implementation. */
getParserImpl()268         IParserImpl* getParserImpl(){return mParserImpl;}
269 
270 		/** Sets the part loader.*/
setPartLoader(IFilePartLoader * partLoader)271 		void setPartLoader(IFilePartLoader* partLoader){mPartLoader=partLoader;}
getPartLoader()272 		const IFilePartLoader* getPartLoader() const {return mPartLoader;}
273 
274 		/** Returns the absolute uri of the currently parsed file*/
275 		virtual const COLLADABU::URI& getFileUri()=0;
276 
277 		/** Copies the contents of the STL container @a stlContainer into the framework array
278 		@a clonedArray.*/
279 		template<class StlContainer, class Array >
copyStlContainerToArray(const StlContainer & stlContainer,Array & clonedArray)280 		static void copyStlContainerToArray( const StlContainer& stlContainer, Array& clonedArray)
281 		{
282 			size_t stlContainerSize = stlContainer.size();
283 			if ( stlContainerSize > 0 )
284 			{
285 				clonedArray.allocMemory( stlContainerSize);
286 				typename StlContainer::const_iterator it = stlContainer.begin();
287 				size_t index = 0;
288 				for (; it != stlContainer.end(); ++it, ++index)
289 				{
290 					clonedArray[index] = *it;
291 				}
292 				clonedArray.setCount(stlContainerSize);
293 			}
294 		}
295 
296 
297         /** Starts loading a extra tag. */
298         virtual bool begin__technique( const technique__AttributeData& attributeData );
299 
300 		virtual bool end__technique();
301 
302 
303 	protected:
304 		/** Deletes the part loader mPartLoader, if it is not needed anymore. Always call this method,
305 		when creating a new FilePartLoader and switching to it.*/
306 		void deleteFilePartLoader();
307 
308 	private:
309 
310         /** Disable default copy ctor. */
311 		IFilePartLoader( const IFilePartLoader& pre );
312 
313         /** Disable default assignment operator. */
314 		const IFilePartLoader& operator= ( const IFilePartLoader& pre );
315 
316 	};
317 
318 } // namespace COLLADASAXFWL
319 
320 #endif // __COLLADASAXFWL_IFILEPARTLOADER_H__
321