1 /*
2 	Copyright (C) 2005-2007 Feeling Software Inc.
3 	Portions of the code are:
4 	Copyright (C) 2005-2007 Sony Computer Entertainment America
5 
6 	MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8 /*
9 	Based on the FS Import classes:
10 	Copyright (C) 2005-2006 Feeling Software Inc
11 	Copyright (C) 2005-2006 Autodesk Media Entertainment
12 	MIT License: http://www.opensource.org/licenses/mit-license.php
13 */
14 
15 /**
16 	@file FCDSceneNode.h
17 	This file contains the FCDSceneNode class.
18 */
19 
20 #ifndef _FCD_SCENE_NODE_
21 #define _FCD_SCENE_NODE_
22 
23 #ifndef _FCD_ENTITY_H_
24 #include "FCDocument/FCDEntity.h"
25 #endif // _FCD_ENTITY_H_
26 #ifndef _FCD_TRANSFORM_H_
27 #include "FCDocument/FCDTransform.h" /** @todo Remove this include by moving the FCDTransform::Type enum to FUDaeEnum.h. */
28 #endif // _FCD_TRANSFORM_H_
29 #ifndef _FCD_ENTITY_INSTANCE_H_
30 #include "FCDocument/FCDEntityInstance.h" /** @todo Remove this include by moving the FCDEntityInstance::Type enum to FUDaeEnum.h. */
31 #endif // _FCD_ENTITY_INSTANCE_H_
32 
33 class FCDocument;
34 class FCDEntityInstance;
35 class FCDSceneNode;
36 class FCDTransform;
37 
38 /**
39 	A COLLADA visual scene node.
40 	This class is also used to represent COLLADA visual scene entities.
41 
42 	A visual scene node contains child scene nodes to make a tree.
43 	A visual scene node may appear multiple times within the scene graph,
44 	but checks are made to verify that there are no cycles within the graph.
45 
46 	A visual scene node also contained an ordered list of transformations
47 	and a list of entity instances.
48 
49 	NOTE: The GenerateSampledMatrixAnimation function was moved to the
50 	FCDSceneNodeTools namespace to improve DLL support.
51 
52 	@ingroup FCDocument
53 */
54 class FCOLLADA_EXPORT FCDSceneNode : public FCDEntity
55 {
56 private:
57 	DeclareObjectType(FCDEntity);
58 
59 	// Hierarchy and instances
60 	DeclareParameterTrackList(FCDSceneNode, parents, FC("Parents"));
61 	DeclareParameterTrackList(FCDSceneNode, children, FC("Child Nodes"));
62 	DeclareParameterContainer(FCDTransform, transforms, FC("Transforms"));
63 	DeclareParameterContainer(FCDEntityInstance, instances, FC("Instances"));
64 
65 	// Visibility parameter.
66 	// Should be a boolean, but is animated as float.
67 	DeclareParameterAnimatable(float, FUParameterQualifiers::SIMPLE, visibility, FC("Visibility"));
68 
69 	// The number of entities that target this node
70 	uint32 targetCount;
71 
72 	// Mainly for joints.
73 	DeclareParameter(fm::string, FUParameterQualifiers::SIMPLE, daeSubId, FC("Sub-id"));
74 
75 public:
76 	DeclareFlag(TransformsDirty, 0); /**< Whether the transforms have been dirtied. */
77 	DeclareFlag(Joint, 1); /**< Whether the scene node is a joint. */
78 	DeclareFlagCount(2); /**< . */
79 
80 public:
81 	/** Constructor: do not use directly.
82 		Instead, use the FCDSceneNode::AddChild function for child
83 		visual scene nodes or the FCDLibrary::AddEntity function
84 		for visual scenes.
85 		@param document The COLLADA document that owns the scene node. */
86 	FCDSceneNode(FCDocument* document);
87 
88 	/** Destructor. */
89 	virtual ~FCDSceneNode();
90 
91 	/** Retrieves the type of the entity class.
92 		@return The type of entity class: SCENE_NODE. */
GetType()93 	virtual Type GetType() const { return SCENE_NODE; }
94 
95 	/** Retrieves the number of parent nodes for this visual scene node.
96 		@return The number of parents. */
GetParentCount()97 	inline size_t GetParentCount() const { return parents.size(); };
98 
99 	/** Retrieves a specific parent of the visual scene node.
100 		@param index The index of the parent.
101 		@return The parent visual scene node. This pointer will be NULL if
102 			the scene node has no parents or if the index is out-of-bounds. */
103 	inline FCDSceneNode* GetParent(size_t index = 0) { FUAssert(index == 0 || index < parents.size(), return NULL); return (!parents.empty()) ? parents.at(index) : NULL; }
104 	inline const FCDSceneNode* GetParent(size_t index = 0) const { FUAssert(index == 0 || index < parents.size(), return NULL); return (!parents.empty()) ? parents.at(index) : NULL; } /**< See above. */
105 
106 	/** Retrieves the list of parents for the visual scene node.
107 		@return The list of parents. */
GetParents()108 	inline const FCDSceneNode** GetParents() const { return parents.begin(); }
109 
110 	/** Retrieves the number of child nodes for this visual scene node.
111 		@return The number of children. */
GetChildrenCount()112 	inline size_t GetChildrenCount() const { return children.size(); };
113 
114 	/** Retrieves a specific child of the visual scene node.
115 		@param index The index of the child.
116 		@return The child scene node. This pointer will be NULL if the
117 			index is out-of-bounds. */
GetChild(size_t index)118 	inline FCDSceneNode* GetChild(size_t index) { FUAssert(index < children.size(), return NULL); return children.at(index); }
GetChild(size_t index)119 	inline const FCDSceneNode* GetChild(size_t index) const { FUAssert(index < children.size(), return NULL); return children.at(index); } /**< See above. */
120 
121 	/** Retrieves the list of children of the visual scene node.
122 		@return The list of child scene nodes. */
GetChildren()123 	inline const FCDSceneNode** GetChildren() const { return children.begin(); }
124 
125 	/** Creates a new child scene node.
126 		@return The new child scene node. */
127 	FCDSceneNode* AddChildNode();
128 
129 	/** Attaches a existing scene node to this visual scene node.
130 		This function will fail if attaching the given scene node
131 		to this visual scene node creates a cycle within the scene graph.
132 		@param sceneNode The scene node to attach.
133 		@return Whether the given scene node was attached to this scene node. */
134 	bool AddChildNode(FCDSceneNode* sceneNode);
135 
136 	/** Removes a scene node from this scene node direct child list.
137 		This function should be used to detach a scene node with multiple parents.
138 		To completely delete a scene node, you should use the FCDSceneNode::Release function
139 		on the scene node to delete.
140 		If the given child node is instanced multiple times within this scene node,
141 		only the first instance will be removed.
142 		@param childNode The child node to remove from the direct hierarchy. */
143 	void RemoveChildNode(FCDSceneNode* childNode);
144 
145 	/** Retrieves the number of entity instances at this node of the scene graph.
146 		@return The number of entity instances. */
GetInstanceCount()147 	inline size_t GetInstanceCount() const { return instances.size(); };
148 
149 	/** Retrieves a specific entity instance.
150 		@param index The index of the instance.
151 		@return The entity instance at the given index. This pointer will be
152 			NULL if the index is out-of-bounds. */
GetInstance(size_t index)153 	inline FCDEntityInstance* GetInstance(size_t index) { FUAssert(index < instances.size(), return NULL); return instances.at(index); }
GetInstance(size_t index)154 	inline const FCDEntityInstance* GetInstance(size_t index) const { FUAssert(index < instances.size(), return NULL); return instances.at(index); } /**< See above. */
155 
156 	/** Retrieves the list of entity instances at this node of the scene graph.
157 		@return The list of entity instances. */
GetInstances()158 	inline const FCDEntityInstance** GetInstances() const { return instances.begin(); }
159 
160 	/** Creates a new entity instance.
161 		Only geometric entities, controllers, light and cameras
162 		can be instantiated in the scene graph.
163 		To instantiate visual scene nodes, use the AddChildNode function.
164 		@param entity The entity to instantiate. This pointer cannot be NULL.
165 		@return The entity instance structure. This pointer will be NULL
166 			if the entity cannot be instantiated here or if the entity is a scene node. */
167 	FCDEntityInstance* AddInstance(FCDEntity* entity);
168 
169 	/** Creates a new entity instance.
170 		Only geometric entities, controllers, light and cameras
171 		can be instantiated in the scene graph.
172 		To instantiate visual scene nodes, use the AddChildNode function.
173 		@param type The type of entity to instantiate.
174 		@return The entity instance structure. This pointer will be NULL
175 			if the entity cannot be instantiated here. */
176 	FCDEntityInstance* AddInstance(FCDEntity::Type type);
177 
178 	/** Retrieves the number of transforms for this node of the scene graph.
179 		@return The number of transforms. */
GetTransformCount()180 	inline size_t GetTransformCount() const { return transforms.size(); };
181 
182 	/** Retrieves a specific transform.
183 		@param index The index of the transform.
184 		@return The transform at the given index. This pointer will be NULL
185 			if the index is out-of-bounds. */
GetTransform(size_t index)186 	inline FCDTransform* GetTransform(size_t index) { FUAssert(index < transforms.size(), return NULL); return transforms.at(index); }
GetTransform(size_t index)187 	inline const FCDTransform* GetTransform(size_t index) const { FUAssert(index < transforms.size(), return NULL); return transforms.at(index); } /**< See above. */
188 
189 	/** Retrieves the list of transforms for this node of the scene graph.
190 		@return The list of transforms. */
GetTransforms()191 	inline const FCDTransform** GetTransforms() const { return transforms.begin(); } /**< See above. */
192 
193 	/** Creates a new transform for this visual scene node.
194 		The transforms are processed in order and COLLADA is column-major.
195 		For row-major matrix stacks, such as DirectX, this implies that the
196 		transformations will be processed in reverse order.
197 		By default, a transform is added at the end of the list.
198 		@param type The type of transform to create.
199 		@param index The index at which to insert the transform. Set this value to -1
200 			to indicate that you want this transform at the end of the stack.
201 		@return The created transform. */
202 	FCDTransform* AddTransform(FCDTransform::Type type, size_t index = (size_t)-1);
203 
204 	/** Retrieves the asset information structures that affect
205 		this entity in its hierarchy.
206 		@param assets A list of asset information structures to fill in. */
GetHierarchicalAssets(FCDAssetList & assets)207 	inline void GetHierarchicalAssets(FCDAssetList& assets) { GetHierarchicalAssets(*(FCDAssetConstList*) &assets); }
208 	virtual void GetHierarchicalAssets(FCDAssetConstList& assets) const; /**< See above. */
209 
210 	/** Retrieves the visual scene node with the given id.
211 		This function looks through the whole sub-tree of visual scene nodes
212 		for the wanted COLLADA id.
213 		@param daeId The COLLADA id to look for.
214 		@return The visual scene node which has the given COLLADA id. This pointer
215 			will be NULL if no visual scene node can be found with the given COLLADA id. */
FindDaeId(const fm::string & daeId)216 	virtual FCDEntity* FindDaeId(const fm::string& daeId) { return const_cast<FCDEntity*>(const_cast<const FCDSceneNode*>(this)->FindDaeId(daeId)); }
217 	virtual const FCDEntity* FindDaeId(const fm::string& daeId) const; /** < See above. */
218 
219 	/** Retrieves the optional sub-id of the node.
220 		This sub-id is neither unique nor guaranteed to exist.
221 		@return The sub-id of the node. */
GetSubId()222 	inline const fm::string& GetSubId() const { return daeSubId; }
223 
224 	/** Sets the sub-id for this node.
225 		The sub-id of an object is not required to be unique.
226 		@param id The new sub-id of the node. */
227 	void SetSubId(const fm::string& id);
228 
229 	/** Retrieves the visual scene node with the given sub-id.
230 		This function looks through the whole sub-tree of visual scene nodes
231 		for the wanted COLLADA sub-id.
232 		@param subId The COLLADA sub-id to look for.
233 		@return The visual scene node which has the given COLLADA sub-id. This pointer
234 			will be NULL if no visual scene node can be found with the given COLLADA sub-id. */
FindSubId(const fm::string & subId)235 	inline FCDEntity* FindSubId(const fm::string& subId) { return const_cast<FCDEntity*>(const_cast<const FCDSceneNode*>(this)->FindSubId(subId)); }
236 	const FCDEntity* FindSubId(const fm::string& subId) const; /**< See above. */
237 
238 	/** Retrieves whether the visual scene node is visible.
239 		A hidden visual scene node will not be rendered but will
240 		still affect the world. This parameter is a floating-point value
241 		because it is animated. It should be intepreted as a Boolean value.
242 		@return Whether the scene node is visible. */
GetVisibility()243 	inline FCDParameterAnimatableFloat& GetVisibility() { return visibility; }
GetVisibility()244 	inline const FCDParameterAnimatableFloat& GetVisibility() const { return visibility; } /**< See above. */
IsVisible()245 	inline bool IsVisible() const { return visibility > 0.5f; } /**< See above. */
246 
247 	/** Sets the visibility of the visual scene node.
248 		A hidden visual scene node will not be rendered but will
249 		still affect the world.
250 		@param isVisible Whether the visual scene node is visible. */
SetVisibility(bool isVisible)251 	inline void SetVisibility(bool isVisible) { visibility = isVisible ? 1.0f : 0.0f; }
252 
253 	/** Retrieves whether this visual scene node is the target of an entity.
254 		@return Whether this is an entity target. */
IsTarget()255 	inline bool IsTarget() const { return targetCount > 0; }
256 
257 	/** Retrieves whether this visual scene node is a joint.
258 		Joints are called bones in 3dsMax. A joint is a scene node that is used in skinning.
259 		@return Whether this node is a joint. */
IsJoint()260 	DEPRECATED(3.05A, GetJointFlag) bool IsJoint() const { return GetJointFlag(); }
261 
262 	/** Retrieves the local transform for this visual scene node.
263 		This function does not handle or apply animations.
264 		@return The local transform. */
265 	FMMatrix44 ToMatrix() const;
266 
267 	/** Retrieves the local transform for this visual scene node.
268 		This is a shortcut to the above function. The above function
269 		will be deprecated in the future.
270 		@return The local transform. */
CalculateLocalTransform()271 	inline FMMatrix44 CalculateLocalTransform() const { return ToMatrix(); }
272 
273 	/** Retrieves the world transform for this visual scene node.
274 		This function is not optimized and will not work with node instances.
275 		@return The world transform. */
276 	FMMatrix44 CalculateWorldTransform() const;
277 
278 	/** Copies the entity information into a clone.
279 		All the overwriting functions of this function should call this function
280 		to copy the COLLADA id and the other entity-level information.
281 		All the up-classes of this class should implement this function.
282 		The cloned entity may reside in another document.
283 		@param clone The empty clone. If this pointer is NULL, a new entity
284 			will be created and you will need to release the returned pointer manually.
285 		@param cloneChildren Whether to recursively clone this entity's children.
286 		@return The clone. */
287 	virtual FCDEntity* Clone(FCDEntity* clone = NULL, bool cloneChildren = false) const;
288 
289 	/** [INTERNAL] Increments the number of entities target this node.
290 		To set targets, use the FCDTargetedEntity::SetTarget function. */
IncrementTargetCount()291 	inline void IncrementTargetCount() { ++targetCount; }
292 
293 	/** [INTERNAL] Decrements the number of entities target this node.
294 		To set targets, use the FCDTargetedEntity::SetTarget function. */
DecrementTargetCount()295 	inline void DecrementTargetCount() { if (targetCount > 0) --targetCount; }
296 
297 	/** [INTERNAL] Cleans up the sub identifiers.
298 		The sub identifiers must be unique with respect to its parent. This method corrects the sub ids if there are conflicts. */
299 	virtual void CleanSubId();
300 };
301 
302 #endif // _FCD_SCENE_NODE_
303