1 /*
2 Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4 This file is part of COLLADAMax.
5 
6 Portions of the code are:
7 Copyright (c) 2005-2007 Feeling Software Inc.
8 Copyright (c) 2005-2007 Sony Computer Entertainment America
9 
10 Based on the 3dsMax COLLADASW Tools:
11 Copyright (c) 2005-2006 Autodesk Media Entertainment
12 
13 Licensed under the MIT Open Source License,
14 for details please see LICENSE file or the website
15 http://www.opensource.org/licenses/mit-license.php
16 */
17 
18 #ifndef __COLLADAMAX_IMPORTERBASE_H__
19 #define __COLLADAMAX_IMPORTERBASE_H__
20 
21 #include "COLLADAMaxPrerequisites.h"
22 #include "COLLADAMaxTypes.h"
23 
24 #include "COLLADAMaxDocumentImporter.h"
25 #include "COLLADAFWLight.h"
26 
27 class Interface;
28 class ImpInterface;
29 class INode;
30 class DummyObject;
31 
32 namespace COLLADAFW
33 {
34 	class UniqueId;
35 	class LibraryNodes;
36 	class Node;
37 	class Material;
38 	class Effect;
39 }
40 
41 namespace COLLADAMax
42 {
43 
44 	class DocumentImporter;
45 
46     /** The base class of all importer classes. It provides methods  used by all importer classes.*/
47 	class ImporterBase
48 	{
49 	public:
50 		static const String EMPTY_STRING;
51 
52 	private:
53 		/** The collada importer the importer belongs to.*/
54 		DocumentImporter* mDocumentImporter;
55 
56 	protected:
57 
58         /** Constructor.
59 		@param colladaImporter The collada importer the importer belongs to.
60 		@param maxInterface The max interface.*/
61 		ImporterBase(DocumentImporter* colladaImporter);
62 
63         /** Destructor. */
64 		virtual ~ImporterBase();
65 
66 		/** Returns the document importer.*/
getDocumentImporter()67 		DocumentImporter* getDocumentImporter() { return mDocumentImporter; }
68 
69 		/** Creates a new max object with @a superClassId and @a classId. If the object could not be created,
70 		null is returned.*/
71 		void* createMaxObject(SClass_ID superClassId, Class_ID classId);
72 
73 		/** Returns the max interface.*/
74 		Interface* getMaxInterface();
75 
76 		/** Returns the max import interface.*/
77 		ImpInterface* getMaxImportInterface();
78 
79 		/** Prints a message in the max gui. Only for debugging purposes.*/
80 		void printMessage( const String& message);
81 
82 		/* Returns the time elapsed the instantiation of the importer.*/
83 		double getElapsedTime() const;
84 
85 		/** Returns the dummy object used for nodes that do not have an object assigned to.*/
86 		DummyObject* getDummyObject();
87 
88 		/** Returns collada importer the importer belongs to.*/
getColladaImporter()89 		DocumentImporter* getColladaImporter() { return mDocumentImporter; }
90 
91 		/** Performs all operations to ensure that the object is referenced by the all nodes
92 		that need to reference it.
93 		@tparam FWObject The framework object class of the framework object that became object */
94 		template<class FWObject>
95 		bool handleObjectReferences( FWObject* fWobject, Object* object );
96 
97 		/** Adds an UniqueId-Object INode pair to the UniqueIdObjectINodeMap.  An Object INode
98 		is an INode that references an object. For nodes that reference an object that has
99 		not already been loaded this method should be called.*/
100 		void addUniqueIdObjectINodePair(const COLLADAFW::UniqueId& uniqueId, INode* node);
101 
102 		/** Adds an UniqueId-Referencing INode pair to the UniqueIdReferencingINodeMap. An Referencing INode
103 		is an INode that references an INode. For nodes that reference an INode that has
104 		not already been loaded this method should be called.*/
105 		void addUniqueIdReferencingImpNodePair(const COLLADAFW::UniqueId& uniqueId, ImpNode* node);
106 
107 		/** Removes the UniqueId-Referencing INode pair from the UniqueIdReferencingINodeMap. Remove pairs
108 		before you start resolving the reference.*/
109 		void removeUniqueIdReferencingImpNodePair( const COLLADAFW::UniqueId& uniqueId, ImpNode* node );
110 
111 		/** Fills @a nodeList with all INodes that reference the object with UniqueId @a uniqueId.*/
112 		void getObjectINodesByUniqueId( const COLLADAFW::UniqueId& uniqueId, INodeList& nodelist );
113 
114 		/** Returns the the iterator pointing to the first element in the map of Unique id and object nodes.*/
115 		DocumentImporter::UniqueIdINodeMultiMapConstIterator getUniqueIdObjectINodesBegin() const;
116 
117 		/** Returns the the iterator pointing beyond the last element in the map of Unique id and object nodes.*/
118 		DocumentImporter::UniqueIdINodeMultiMapConstIterator getUniqueIdObjectINodesEnd() const;
119 
120 		/** Returns an INodes that reference the node with UniqueId @a uniqueId or zero if no such node is
121 		in the map. */
122 		ImpNode* getReferencingImpNodesByUniqueId( const COLLADAFW::UniqueId& uniqueId );
123 
124 		/** Adds an UniqueId-Object pair to the UniqueIdObjectMap. For every imported object this method should
125 		be called to ensure that elements that are imported later and instance this object can set the object
126 		as reference.*/
127 		void addUniqueIdObjectPair(const COLLADAFW::UniqueId& uniqueId, Object* object);
128 
129 		/** Adds an UniqueId-INode pair to the UniqueIdINodeMap. For every imported INode this method should
130 		be called to ensure that this node can be referenced later .*/
131 		void addUniqueIdINodePair( const COLLADAFW::UniqueId& uniqueId, INode* iNode );
132 
133 		/** Adds an object INode (an INode that references an object) UniqueId pair to the ObjectUniqueIdMap.
134 		For every imported INode that references an object this method should be called to ensure that its
135 		unique id can be retrieved from the created INode. This is required for instance node handling.*/
136 		void addObjectINodeUniqueIdPair( INode* object, const COLLADAFW::UniqueId& uniqueId );
137 
138 		/** Adds UniqueId frame work node pair to the UniqueIdFWNodeMap.
139 		For every received node that is in a library nodes and not immediately imported into th max scene graph
140 		this method should be called. This is required for instance node handling of nodes in a library nodes.*/
141 		void addUniqueIdFWNodePair( const COLLADAFW::UniqueId& uniqueId, const COLLADAFW::Node* node );
142 
143 		/** Adds UniqueId frame work material pair to the UniqueIdFWMaterialMap.
144 		For every received material that is in a library materials this method should be called. */
145 		void addUniqueIdFWMaterialPair( const COLLADAFW::UniqueId& uniqueId, const COLLADAFW::Material& material );
146 
147 		/** Adds UniqueId frame work effect pair to the UniqueIdFWEffectMap.
148 		For every received effect that is in a library effect this method should be called. */
149 		void addUniqueIdFWEffectPair( const COLLADAFW::UniqueId& uniqueId, const COLLADAFW::Effect& effect );
150 
151 		/** Adds UniqueId frame work image pair to the UniqueIdFWImageMap.
152 		For every received image that is in a library image this method should be called. */
153 		void addUniqueIdFWImagePair( const COLLADAFW::UniqueId& uniqueId, const COLLADAFW::Image& image );
154 
155 		/** Creates a new NodeMaterialBindingsPair with maxNode set to @a node and an empty material bindings
156 		vector and adds it to the NodeMaterialBindingsList.
157 		For every max node that references a geometry with set material this method should be called. */
158 		DocumentImporter::NodeMaterialBindingsPair& createAndAddNodeMaterialBindingsPair( INode* node );
159 
160 		/** Adds @a libraryNodes to the list of library nodes.*/
161 		void addLibraryNodes( const COLLADAFW::LibraryNodes* libraryNodes );
162 
163 		/** Adds @a visualScene to the map of visual scenes. @a visualScene will be deleted by the DocumentImporter.*/
164 		void addVisualScene( const COLLADAFW::VisualScene* visualScene );
165 
166 		/** Adds the @pair clonedNode and @a originalNode to the list of cloned and original inodes.*/
167 		void addClonedINodeOriginalINodePair(INode* clonedNode, INode* originalNode);
168 
169 		/** Adds an object object-name pair  to the ObejctObjectNameMap. Whenever an object is created,
170 		add it using this method.*/
171 		void addObjectObjectNamePair( Object* object, const String& name);
172 
173 		/** Adds @a vertexColorObjectuniqueId to the list of unique ids of objects that use vertex color.
174 		When ever a geometry that uses vertex color is created,	its unique id should be added to this list.*/
175 		void addVertexColorObjects(const COLLADAFW::UniqueId& vertexColorObjectuniqueId);
176 
177 		/** Add @a maxController to the list of float controllers created from framework animation with unique id
178 		@a animationUniqueId.*/
179 		void addMaxControllerToAnimationUniqueId( const COLLADAFW::UniqueId& animationUniqueId, Control* maxController);
180 
181 		/** Add @a animationList to the map of all animation list.*/
182 		void addAnimationList(  const COLLADAFW::AnimationList& animationList);
183 
184 		/** Returns the object that was created from the imported object with UniqueId @a uniqueId. If
185 		@a uniqueId has not been added using addUniqueIdObjectPair, null is returned.*/
186 		Object* getObjectByUniqueId( const COLLADAFW::UniqueId& uniqueId);
187 
188 		/** Returns the INode that was created from the imported node with UniqueId @a uniqueId. If
189 		@a uniqueId has not been added using addUniqueIdINodePair, null is returned.*/
190 		INode* getINodeByUniqueId( const COLLADAFW::UniqueId& uniqueId );
191 
192 		/** Returns the unique id of the framework object that was  used to create @a object. If
193 		@a object  not been added using addObjectINodeUniqueIdPair, an invalid unique id is returned.*/
194 		const COLLADAFW::UniqueId& getUniqueIdByObjectINode( INode* object );
195 
196 		/** Returns the frame work node with unique id @a uniqueId, if this node is in an already
197 		received library nodes, null otherwise.*/
198 		const COLLADAFW::Node* getFWNodeByUniqueId( const COLLADAFW::UniqueId& uniqueId );
199 
200 		/** Returns  mUniqueIdFWNodeMap.*/
201 		const DocumentImporter::UniqueIdFWNodeMap& ImporterBase::getUniqueIdFWNodeMap( );
202 
203 		/** Returns the frame work material with unique id @a uniqueId, if this node is in an already
204 		received material, null otherwise.*/
205 		const COLLADAFW::Material* getFWMaterialByUniqueId( const COLLADAFW::UniqueId& uniqueId );
206 
207 		/** Returns the frame work effect with unique id @a uniqueId, if this node is in an already
208 		received effect, null otherwise.*/
209 		const COLLADAFW::Effect* getFWEffectByUniqueId( const COLLADAFW::UniqueId& uniqueId );
210 
211         /** Returns the frame work effect maps for effects with unique id @a uniqueId, if this node is
212         in an already received effect, null otherwise.*/
213         const EffectMaps* getFWEffectMapsByUniqueId( const COLLADAFW::UniqueId& uniqueId );
214 
215 		/** Returns the frame work image with unique id @a uniqueId, if this node is in an already
216 		received image, null otherwise.*/
217 		const COLLADAFW::Image* getFWImageByUniqueId( const COLLADAFW::UniqueId& uniqueId );
218 
219 		/** Returns the list of all nodes that have a material and their material bindings.*/
220 		const DocumentImporter::NodeMaterialBindingsList& getNodeMaterialBindings();
221 
222 		/** Returns the material id map of geometry with @a uniqueId. If it is not already in the map, a new
223 		one is created.*/
224 		DocumentImporter::FWMaterialIdMaxMtlIdMap& getMaterialIdMapByGeometryUniqueId( const COLLADAFW::UniqueId& uniqueId);
225 
226 		/** Returns the SetMapChannelMap of geometry with @a uniqueId. If it is not already in the map, a new
227 		one is created.*/
228 		DocumentImporter::SetMapChannelMap& getSetMapChannelByGeometryUniqueId( const COLLADAFW::UniqueId& uniqueId );
229 
230 		/** Returns visual scene with unique id @a visualSceneUniqueId. If not found, null is returned.*/
231 		const COLLADAFW::VisualScene* getVisualSceneByUniqueId( const COLLADAFW::UniqueId& visualSceneUniqueId);
232 
233 		/**Returns the list of pairs of cloned nodes and their originals. This is used to assign materials.
234 		When ever an inode is cloned, the cloned one and itself should be added to that list.*/
235 		const DocumentImporter::INodeINodePairList& getClonedINodeOriginalINodePairList();
236 
237 		/** Returns the list of unique ids of objects that use vertex color. */
238 		const DocumentImporter::UniqueIdList& getVertexColorObjects();
239 
240 		/** Returns the name of @a object.*/
241 		const String& getObjectNameByObject( Object* object ) const;
242 
243 		/** Retrieves the list of max controller created from frame work animation with unique id @a animationUniqueId.
244 		An empty list is returned, if no controller has been created from the animation. */
245 		const DocumentImporter::MaxControllerList& getMaxControllerListByAnimationUniqueId( const COLLADAFW::UniqueId& animationUniqueId) const;
246 
247 		/** Retrieves the animation list with @a uniqueId. If not found, 0 is returned.*/
248 		const COLLADAFW::AnimationList* getAnimationListByUniqueId(const COLLADAFW::UniqueId& animationListUniqueId) const ;
249 
250 		/** Retrieves the animation list referenced by @a animatable. If not found, 0 is returned.*/
251 		const COLLADAFW::AnimationList* getAnimationList( const COLLADAFW::Animatable* animatable );
252 
253 		/** Functors used to convert values from frame work units into max units.*/
getUnitConversionFunctors()254 		const DocumentImporter::UnitConversionFunctors& getUnitConversionFunctors() const { return mDocumentImporter->getUnitConversionFunctors(); }
255 
256 		/** Maps unique ids of controller data to the corresponding controller.*/
getUniqueIdControllerMap()257 		const DocumentImporter::UniqueIdControllerMultiMap& getUniqueIdControllerMap() const { return mDocumentImporter->getUniqueIdControllerMap(); }
258 
259 		/** Adds the pair @a controllerData, @a controller to the UniqueIdControllerMultiMap.*/
260 		void addUniqueIdControllerPair( const COLLADAFW::UniqueId& controllerData, const COLLADAFW::Controller* controller);
261 
262 		/** Returns the morph controller with unique id @a morphControllerUniqueId. Null if not found. */
263 		const COLLADAFW::MorphController* getMorphControllerByUniqueId( const COLLADAFW::UniqueId& morphControllerUniqueId ) const;
264 
265 		/** Adds @a morphController to map of all morph controllers found during the first pass. The morph controller will
266 		be deleted at the end of the import.*/
267 		void addMorphController( const COLLADAFW::MorphController* morphController );
268 
269 		/** Returns the skin controller with unique id @a skinControllerUniqueId. Null if not found. */
270 		const COLLADAFW::SkinController* getSkinControllerByUniqueId( const COLLADAFW::UniqueId& skinControllerUniqueId ) const;
271 
272 		/** Adds @a skinController to map of all skin controllers found during the first pass. The skin controller will
273 		be deleted at the end of the import.*/
274 		void addSkinController( const COLLADAFW::SkinController* skinController );
275 
276 		/** Maps unique ids of controller data to the corresponding controller.*/
getINodeBySkinController(const COLLADAFW::UniqueId & skinController)277 		INode* getINodeBySkinController( const COLLADAFW::UniqueId& skinController ) const { return mDocumentImporter->getSkinControllerINodeMap()[skinController]; }
278 
279 		/** Adds the pair @a controllerData, @a controller to the UniqueIdControllerMultiMap.*/
addSkinControllerINodePair(const COLLADAFW::UniqueId & skinController,INode * inode)280 		void addSkinControllerINodePair( const COLLADAFW::UniqueId& skinController, INode* inode) { mDocumentImporter->getSkinControllerINodeMap()[skinController] = inode;}
281 
282 		/** Adds  @a fwLight to the LightList.*/
addLight(const COLLADAFW::Light & fwLight)283 		void addLight( const COLLADAFW::Light& fwLight) { mDocumentImporter->getLightList().push_back(fwLight);}
284 
285 		/** Returns the list of framework lights and max lights.*/
getLightList()286 		const DocumentImporter::LightList& getLightList() const { return mDocumentImporter->getLightList(); }
287 
288 		/** Maps the unique ids of  morph controllers that are NOT instantiated in the scene graph but
289 		used as source by a skin controller to the INode that references this skin controller.*/
getMorphUniqueIdINodeMap()290 		const DocumentImporter::UniqueIdINodeMap& getMorphUniqueIdINodeMap( ) const { return mDocumentImporter->getMorphUniqueIdINodeMap(); }
291 
292 		/** Maps the unique ids of  morph controllers that are NOT instantiated in the scene graph but
293 		used as source by a skin controller to the INode that references this skin controller.*/
addMorphControllerINodePair(const COLLADAFW::UniqueId & morphController,INode * inode)294 		void addMorphControllerINodePair( const COLLADAFW::UniqueId& morphController, INode* inode) { mDocumentImporter->getMorphUniqueIdINodeMap()[morphController] = inode;}
295 
296 		/** Returns informations about the entire file being loaded.*/
getFileInfo()297 		const DocumentImporter::FileInfo& getFileInfo() const { return mDocumentImporter->getFileInfo(); }
298 
299 		/** Converts @a originalValue in units provided by file info to units currently set in max.*/
300 		float convertSpaceUnit( float originalValue );
301 
302 		/** Converts a COLLADAFW Matrix4 into a max Matrix3.*/
303 		void Matrix4ToMaxMatrix3 ( Matrix3 & copy,  const COLLADABU::Math::Matrix4& original  );
304 
305 		const SkyLightParameters* getSkyLightParametersByUniqueId( const COLLADAFW::UniqueId& uniqueId );
306 
307 		void addUniqueIdSkyLightParametersPair( const COLLADAFW::UniqueId& lightUniqueId, const SkyLightParameters& skyLightParameters);
308 		void addUniqueIdEffectBumpMapParametersPair( const COLLADAFW::UniqueId& effectUniqueId, const BumpMap& bumpParameters);
309 
310 	private:
311 
312         /** Disable default copy ctor. */
313 		ImporterBase( const ImporterBase& pre );
314 
315         /** Disable default assignment operator. */
316 		const ImporterBase& operator= ( const ImporterBase& pre );
317 	};
318 
319 
320 
321 	//------------------------------
322 	template<class FWObject>
handleObjectReferences(FWObject * fWobject,Object * object)323 	bool ImporterBase::handleObjectReferences( FWObject* fWobject, Object* object )
324 	{
325 		const COLLADAFW::UniqueId& uniqueID = fWobject->getUniqueId();
326 
327 		const String& objectName = fWobject->getName();
328 		addUniqueIdObjectPair(uniqueID, object);
329 		if ( !objectName.empty() )
330 			addObjectObjectNamePair(object, objectName);
331 
332 #if 0
333 		INodeList objectNodeList;
334 		getObjectINodesByUniqueId(uniqueID, objectNodeList);
335 		for ( size_t i = 0, count = objectNodeList.size(); i<count; ++i)
336 		{
337 			INode* maxNode = objectNodeList[i];
338 			TCHAR* name = maxNode->GetName();
339 			if ( !name || !(*name) )
340 				maxNode->SetName( (char *)objectName.c_str());
341 			maxNode->SetObjectRef(object);
342 		}
343 #endif
344 		return true;
345 	}
346 
347 
348 
349 
350 } // namespace COLLADAMAX
351 
352 #endif // __COLLADAMAX_IMPORTERBASE_H__
353