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 
19 #ifndef __COLLADAMAX_EXPORTNODE_H__
20 #define __COLLADAMAX_EXPORTNODE_H__
21 
22 #include "COLLADAMaxPrerequisites.h"
23 
24 #include <max.h>
25 
26 #include "COLLADABUIDList.h"
27 
28 #include "COLLADAMaxControllerList.h"
29 
30 #include <map>
31 #include <vector>
32 
33 class INode;
34 
35 class ExportSceneGraph;
36 
37 
38 
39 namespace COLLADAMax
40 {
41 
42 
43     /** A class to represent a node that should be exported.
44     */
45 
46     class ExportNode
47     {
48 
49     public:
50         enum Type
51         {
52             UNDETERMINED,
53             UNKNOWN,
54             MESH,
55             CAMERA,
56             LIGHT,
57             BONE,
58 			HELPER,
59 			MATERIAL,
60 			XREF_OBJECT,
61 			NURBS_CURVE,
62 			SPLINE
63         };
64 
65         struct Symbol
66         {
67             bool used;
68             String name;
69         };
70 
71         /** Maps max materials to COLLADASW symbols map<material, symbol>.*/
72         typedef std::map<Mtl *, Symbol> MeshSymbolMap;
73 
74     private:
75         typedef std::vector<ExportNode *> ExportNodeList;
76 
77 		enum Flags
78 		{
79 			NONE                 = 0x0000,
80 
81 			/** Indicates if the node is a joint*/
82 			ISJOINT              = 0x0001,
83 
84 			/** Indicates if the node is in the visual scene, i.e. not hidden or selected if export selection only
85 			is choosen.*/
86 			ISINVISUALSCENE      = 0x0002,
87 
88 			/** Indicates if the node is referenced some where.*/
89 			ISREFERENCED         = 0x0004,
90 
91 			/** Indicates if the nodes object is an XRef object.*/
92 			ISXREFOBJECT         = 0x0008,
93 
94 			/** Indicates if the nodes object is an XRef material.*/
95 			ISXREFMATERIAL       = 0x0010
96 		};
97 
98     private:
99         /** Maps max material to symbol name.*/
100         MeshSymbolMap mMeshSymbolMap;
101 
102         /** Only used if mMeshSymbolMap is empty.*/
103         DWORD mWireFrameColor;
104 
105         /** The INode this export node wraps.*/
106         INode * mINode;
107 
108 		ExportNode* mParent;
109 
110 		/** Children of the export node.*/
111         ExportNodeList mChildren;
112 
113         /** The type of the node.*/
114         Type mType;
115 
116 		/** Flags used to store properties of the export node*/
117 		int mFlags;
118 
119         /** The unique id of the node.*/
120         String mId;
121 
122 		/** The sid of the node.*/
123 		String mSid;
124 
125 		/** List of the unique symbols of the mesh. (Only used if the node is a mesh).*/
126         COLLADABU::IDList mSymbolList;
127 
128 		/** All the controllers that are applied to the represented node and that are supported by COLLADASW.*/
129 		ControllerList * mControllerList;
130 
131     public:
132         /** Constructor
133         @param iNode The INode represented by the Export node. */
134         ExportNode ( INode * iNode, ExportNode* parent );
135 
136         /** Destructor*/
~ExportNode()137         virtual ~ExportNode()
138         {
139             clean();
140         }
141 
142         /** Returns the unique id of the node.*/
getId()143         const String & getId() const
144         {
145             return mId;
146         }
147 
148 		/** Returns the sid of the node.*/
getSid()149 		const String & getSid() const
150 		{
151 			return mSid;
152 		}
153 
154 		/** Sets the sid of the node*/
setSid(const String & sid)155 		void setSid(const String & sid){mSid=sid;}
156 
157 		/** Returns if the node has already an sid*/
hasSid()158 		bool hasSid()const {return !mSid.empty();}
159 
160 		/** Sets the type of the node to UNKNOWN. Use this if you notify that the simple
161 		approach based on class ids failed.*/
setTypeToUnknown()162 		void setTypeToUnknown() {mType = UNKNOWN;}
163 
164         /** Returns the type of the node.*/
getType()165 		Type getType() const { return mType; };
166 
167 		/** Returns if the node is a joint*/
getIsJoint()168 		bool getIsJoint()const {return (mFlags & ISJOINT) != 0;}
169 
170 		/** Sets if the node is a joint*/
171 		void setIsJoint(bool isJoint = true){ isJoint ? mFlags |= ISJOINT : mFlags &= ~ISJOINT;}
172 
173         /** Returns the INode associated with this Export Node.*/
getINode()174         INode * getINode() const
175         {
176             return mINode;
177         }
178 
179 		/** Returns true if object cast shadows. */
getCastShadows()180 		inline bool getCastShadows() {
181 			return getINode() ? getINode()->CastShadows() > 0 : false;
182 		}
183 
184 		/** Returns true if object receive shadows. */
getReceiveShadows()185 		inline bool getReceiveShadows() {
186 			return getINode() ? getINode()->RcvShadows() > 0 : false;
187 		}
188 
189 
190 		/** Returns the camera object represented by the export node. This functions returns a non zero pointer
191 		only if the node is a camera.*/
getCamera()192 		CameraObject* getCamera()const{ return (CameraObject*)mINode->GetObjectRef(); }
193 
194 		/** Returns the light object represented by the export node. This functions returns a non zero pointer
195 		only if the node is a light.*/
getLight()196 		LightObject* getLight()const{ return (LightObject*)mINode->GetObjectRef(); }
197 
198 
199 		/** Returns if the node is in the visual scene, i.e. not hidden or selected if export selection only
200 		is choosen.*/
getIsInVisualScene()201 		bool getIsInVisualScene()const {return (mFlags & ISINVISUALSCENE) != 0;}
202 
203 		/** Sets if the node is in the visual scene, i.e. not hidden or selected if export selection only
204 		is choosen.*/
205 		void setIsInVisualScene(bool isInVisualScene = true){isInVisualScene ? mFlags |= ISINVISUALSCENE : mFlags &= ~ISINVISUALSCENE;}
206 
207 		/** Returns if the node is referenced some where.*/
getIsReferenced()208 		bool getIsReferenced()const {return (mFlags & ISREFERENCED) != 0;}
209 
210 		/** Sets if the node is referenced some where.*/
211 		void setIsReferenced(bool isReferenced = true){isReferenced ? mFlags |= ISREFERENCED : mFlags &= ~ISREFERENCED;}
212 
213 		/** Returns if the nodes object is an XRef object.*/
getIsXRefObject()214 		bool getIsXRefObject()const {return (mFlags & ISXREFOBJECT) != 0;}
215 
216 		/** Sets if the nodes object is an XRef object.*/
217 		void setIsXRefObject(bool isXRef = true){isXRef ? mFlags |= ISXREFOBJECT : mFlags &= ~ISXREFOBJECT;}
218 
219 		/** Returns if the nodes material is an XRef material.*/
getIsXRefMaterial()220 		bool getIsXRefMaterial()const {return (mFlags & ISXREFMATERIAL) != 0;}
221 
222 		/** Sets if the nodes material is an XRef material.*/
223 		void setIsXRefMaterial(bool isXRef = true){isXRef ? mFlags |= ISXREFMATERIAL : mFlags &= ~ISXREFMATERIAL;}
224 
225 		/** Returns the parent or NULL if it has no parent.*/
getParent()226 		ExportNode* getParent()const{return mParent;}
227 
228         /** Returns the number of child nodes.*/
getNumberOfChildren()229         size_t getNumberOfChildren() const
230         {
231             return mChildren.size();
232         }
233 
234         /** Returns the @a i'th  child.*/
getChild(size_t i)235         ExportNode * getChild ( size_t i )
236         {
237             return mChildren[ i ];
238         }
239 
240         /** Returns the @a i'th  child.*/
getChild(size_t i)241         const ExportNode * const getChild ( size_t i ) const
242         {
243             return mChildren[ i ];
244         }
245 
246 		/** Returns the ControllerList*/
getControllerList()247 		ControllerList * getControllerList()const{ return mControllerList; }
248 
249 		/** Sets the controller list.*/
250 		void createControllerList();
251 
252 		/** Returns if the node has controllers applied to it.*/
hasControllers()253 		bool hasControllers()const{ return mControllerList ? mControllerList->hasControllers() : false; }
254 
255 		/** Returns the id of the last controller applied to the nodes geometry or an empty string if no
256 		controllers are assigned.*/
257 		String getLastControllerId()const;
258 
259 		/** Returns the the last controller applied to the nodes geometry or 0 if no
260 		controllers are assigned.*/
261 		Controller* getLastController()const;
262 
263 		/** Returns the initial pose of the object, before all controllers that will be exported are applied.*/
264 		Object* getInitialPose()const;
265 
266 		/** Returns the final pose of the object, after all controllers are applied.*/
267 		Object* getFinalPose()const;
268 
269         /** Adds channel @a channel with corresponding effect id @a effectId. The symbol is marked as unused.*/
270         void addSymbol ( Mtl * material, const String & symbol );
271 
272         /** Returns the symbol that corresponds to @a material.*/
273         const String& getSymbolByMaterialAndSetAsUsed ( Mtl* material );
274 
275         /** Returns the @a MeshSymbolMap of this node.*/
getMeshSymbolMap()276         const MeshSymbolMap & getMeshSymbolMap() const
277         {
278             return mMeshSymbolMap;
279         }
280 
281 		/** Returns the @a MeshSymbolMap of this node.*/
getMeshSymbolMap()282 		MeshSymbolMap & getMeshSymbolMap()
283 		{
284 			return mMeshSymbolMap;
285 		}
286 
287         /** Sets the wire frame color.*/
setWireFrameColor(DWORD color)288         void setWireFrameColor ( DWORD color )
289         {
290             mWireFrameColor = color;
291         }
292 
293         /** Returns the wire frame color.*/
getWireFrameColor()294         DWORD getWireFrameColor() const
295         {
296             return mWireFrameColor;
297         }
298 
299         /** Set the unique id of the export node to @a id.
300         It is ensured, that the id is a valid id according to the xml spec*/
setId(const String & id)301         const String& setId ( const String& id )
302         {
303             mId = COLLADABU::Utils::checkID ( id );
304             return mId;
305         }
306 
307         /** Removes all children.*/
308         void clean();
309 
310         /** Adds @a exportNode to its children.*/
311 
add(ExportNode * exportNode)312         void add
313         ( ExportNode * exportNode )
314         {
315             mChildren.push_back ( exportNode );
316         }
317 
318     protected:
319         ExportNode ( INode * iNode, ExportNode* parent, Type type );
320 
321     private:
322 		/** Determines and returns the type of @a INode.*/
323 		Type determineType ( INode * iNode );
324 
325         /** Determines the type of the export node.*/
326         void determineType();
327     };
328 
329 }
330 
331 
332 #endif //__COLLADAMAX_EXPORTNODE_H__
333