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 FCDGeometryPolygons.h
17 	This file defines the FCDGeometryPolygons class.
18 */
19 
20 #ifndef _FCD_GEOMETRY_POLYGONS_H_
21 #define _FCD_GEOMETRY_POLYGONS_H_
22 
23 #ifndef __FCD_OBJECT_H_
24 #include "FCDocument/FCDObject.h"
25 #endif // __FCD_OBJECT_H_
26 #ifndef _FU_DAE_ENUM_H_
27 #include "FUtils/FUDaeEnum.h"
28 #endif // _FU_DAE_ENUM_H_
29 #ifndef _FU_PARAMETER_H_
30 #include "FUtils/FUParameter.h"
31 #endif // _FU_PARAMETER_H_
32 
33 class FCDocument;
34 class FCDExtra;
35 class FCDMaterial;
36 class FCDGeometryMesh;
37 class FCDGeometrySource;
38 class FCDGeometryPolygonsInput;
39 
40 typedef fm::pvector<FCDGeometryPolygonsInput> FCDGeometryPolygonsInputList; /**< A dynamically-sized array of FCDGeometryPolygonsInput objects. */
41 typedef fm::pvector<const FCDGeometryPolygonsInput> FCDGeometryPolygonsInputConstList; /**< A dynamically-sized array of FCDGeometryPolygonsInput objects. */
42 typedef fm::map<const FCDGeometrySource*, FCDGeometrySource*> FCDGeometrySourceCloneMap; /**< A map of old FCDGeometrySource objects to newly cloned FCDGeometrySource objects. */
43 
44 /**
45 	A mesh polygon set.
46 	Each polygon set contains a list of inputs and the tessellation information
47 	to make polygons out of the data and indices of the input. FCollada
48 	supports triangle lists as well as polygon lists and lists of polygons with holes.
49 	This implies that each face has an undeterminate number of vertices.
50 	The tessellation information creates polygons, but may also creates holes within the polygons.
51 
52 	@ingroup FCDGeometry
53 */
54 class FCOLLADA_EXPORT FCDGeometryPolygons : public FCDObject
55 {
56 public:
57 	/** The types of primitives. */
58 	enum PrimitiveType
59 	{
60 		LINES, /**< A list of lines. Only one element is contained in the face-vertex count list.
61 			It represents the total number of line vertices. The total number of lines is
62 			equal to half the total number of line vertices. */
63 		LINE_STRIPS, /**< A list of continuous lines. Each element in the face-vertex count list
64 			represents the number of consecutive line vertices before restarting. */
65 		POLYGONS, /**< A list of polygons. All the polygons may be triangles.
66 			This is the most common primitive type. The polygons may have holes. Each element in the
67 			face-vertex count list represent the number of vertices for one polygon. */
68 		TRIANGLE_FANS, /**< A list of triangle fans. Each element in the face-vertex count list
69 			represents the number of vertices for one fan. A triangle fan is defined by re-using the first
70 			vertex for every triangle. Advancing pairs are then used in order to generate adjacent triangles
71 			such that if there are 5 vertices, then 3 triangles are created: {0,1,2}, {0,2,3} and {0,3,4}. */
72 		TRIANGLE_STRIPS, /**< A list of continuous triangles. Each element in the face-vertex count list
73 			represents the number of vertices for one strip. A triangle strip is defined by re-using two
74 			advancing vertices from the previous triangle for the next triangle. If there are 5 vertices in
75 			the strip, then 3 triangles are created: {0,1,2}, {1,2,3}, {2,3,4}. Note that vertex winding must
76 			also be taken into consideration and every even triangle in the strip has its vertices swapped
77 			from the above pattern. */
78 		POINTS /**< A list of Camera-facing sprites. The face-vertex count list will contain one element that
79 			represents the total number of points. Two non-COLLADA geometry sources (POINT_SIZE and POINT_ROTATION)
80 			are specific to this type. */
81 	};
82 
83 private:
84 	DeclareObjectType(FCDObject);
85 
86 	FCDGeometryMesh* parent;
87 	DeclareParameterContainer(FCDGeometryPolygonsInput, inputs, FC("Data Inputs"));
88 	DeclareParameterList(UInt32, faceVertexCounts, FC("Per-face Vertex counts"));
89 	DeclareParameterList(UInt32, holeFaces, FC("Hole face indices"));
90 	DeclareParameter(uint32, FUParameterQualifiers::SIMPLE, primitiveType, FC("Primitive Type")); // PrimitiveType
91 
92 	// Buffered statistics
93 	size_t faceVertexCount;
94 	size_t faceOffset;
95 	size_t faceVertexOffset;
96 	size_t holeOffset;
97 
98 	// Material for this set of polygons
99 	DeclareParameter(fstring, FUParameterQualifiers::SIMPLE, materialSemantic, FC("Material Semantic"));
100 
101 	// Extra information tree
102 	DeclareParameterRef(FCDExtra, extra, FC("Extra Tree"));
103 
104 public:
105 	/** Constructor: do not use directly. Instead, use the FCDGeometryMesh::AddPolygons function
106 		to create new polygon sets.
107 		@param document The COLLADA document which owns this polygon set.
108 		@param parent The geometric mesh which contains this polygon set.*/
109 	FCDGeometryPolygons(FCDocument* document, FCDGeometryMesh* parent);
110 
111 	/** Destructor. */
112 	virtual ~FCDGeometryPolygons();
113 
114 	/** Retrieves the geometry that contains this polygons.
115 		@return The parent geometry. */
GetParent()116 	inline FCDGeometryMesh* GetParent() { return parent; }
GetParent()117 	inline const FCDGeometryMesh* GetParent() const { return parent; } /**< See above. */
118 
119 	/** Retrieves the extra information tree for this entity instance. The
120 		prefered way to save extra information in FCollada is at the entity
121 		level. Use this extra information tree to store any information you
122 		want exported and imported back.
123 		@return The extra information tree. */
124 	FCDExtra* GetExtra();
GetExtra()125 	inline const FCDExtra* GetExtra() const { return const_cast<FCDGeometryPolygons*>(this)->GetExtra(); } /**< See above. */
126 
127 	/** Retrieves the primitive type for this polygons set.
128 		@return The primitive type. */
GetPrimitiveType()129 	inline PrimitiveType GetPrimitiveType() const { return (PrimitiveType) *primitiveType; }
130 
131 	/** Sets the primitive type for this polygons set.
132 		Important note: no attempt is made at fixing up the indices. You should
133 		only do this operation of empty polygons set.
134 		@param type The new primitive type. */
SetPrimitiveType(PrimitiveType type)135 	inline void SetPrimitiveType(PrimitiveType type) { primitiveType = type; SetDirtyFlag(); }
136 
137 	/** Retrieves the list of face-vertex counts. Each face within the polygon set
138 		has one or more entry within this list, depending on the number of holes within that face.
139 		Each face-vertex count indicates the number of ordered indices
140 		within the polygon set inputs that are used to generate a face or its holes.
141 		To find out if a face-vertex count represents a face or its holes, check
142 		the hole-faces list retrieved using the GetHoleFaces function.
143 		Indirectly, the face-vertex count indicates the degree of the polygon.
144 		@see GetHoleFaces @see GetHoleCount
145 		@return The list of face-vertex counts.*/
GetFaceVertexCounts()146 	inline const uint32* GetFaceVertexCounts() const { return faceVertexCounts.begin(); } /**< See above. */
147 
148 	/** Adds a new count to the face-vertex count list.
149 		This function only modifies the face-vertex count list.
150 		To also add indices to the inputs for the new face, use the AddFace function.
151 		@param count The number of vertices in the new face. */
152 	void AddFaceVertexCount(uint32 count);
153 
154 	/** Retrieves the number of face-vertex counts within the polygon set.
155 		This value also represents the total the number of faces and holes within the polygon set.
156 		@return The number of face-vertex counts within the polygon set. */
GetFaceVertexCountCount()157 	inline size_t GetFaceVertexCountCount() const { return faceVertexCounts.size(); }
158 
159 	/** Sets the number of face-vertex counts within the polygon set.
160 		Any additional face-vertex count will not be initialized and
161 		any removed face-vertex count will not remove the equivalent
162 		indices within the polygon set inputs.
163 		@param count The new number of face-vertex counts within the polygon set. */
164 	void SetFaceVertexCountCount(size_t count);
165 
166 	/** [DEPRECATED]
167 		Retrieves if the polygons is a list of polygons (returns false), or a list of triangles
168 		(returns true).
169 		@return The boolean answer. */
170 	DEPRECATED(3.05, TestPolyType) bool IsTriangles() const;
171 
172 	/** Tests if the polygon can be aproximated with a constant face count
173 		Returns: 3 if all faces are triangles, 4 if all faces are triangles, else -1 */
174 	int32 TestPolyType() const;
175 
176 	/** Retrieves the number of holes within the faces of the polygon set.
177 		@return The number of holes within the faces of the polygon set. */
GetHoleCount()178 	inline size_t GetHoleCount() const { return holeFaces.size(); }
179 
180 	/** Retrieves the number of faces within the polygon set.
181 		@return The number of faces within the polygon set. */
GetFaceCount()182 	inline size_t GetFaceCount() const { return faceVertexCounts.size() - GetHoleCount(); }
183 
184 	/** Retrieves the number of faces which appear before this polygon set within the geometric mesh.
185 		This value is useful when traversing all the faces of a geometric mesh.
186 		@return The number of faces in previous polygon sets. */
GetFaceOffset()187 	inline size_t GetFaceOffset() const { return faceOffset; }
188 
189 	/** Retrieves the total number of face-vertex pairs within the polygon set.
190 		This value is the total of all the values within the face-vertex count list.
191 		Do remember that the list of face-vertex pairs includes holes.
192 		@return The total number of face-vertex pairs within the polygon set. */
GetFaceVertexCount()193 	inline size_t GetFaceVertexCount() const { return faceVertexCount; }
194 
195 	/** Retrieves the number of face-vertex pairs for a given face.
196 		This value includes face-vertex pairs that create the polygon and its holes.
197 		@param index A face index.
198 		@return The number of face-vertex pairs for a given face. */
199 	size_t GetFaceVertexCount(size_t index) const;
200 
201 	/** Retrieves the total number of face-vertex pairs which appear
202 		before this polygon set within the geometric mesh.
203 		This value is useful when traversing all the face-vertex pairs of a geometric mesh.
204 		@return The number of face-vertex pairs in previous polygon sets. */
GetFaceVertexOffset()205 	inline size_t GetFaceVertexOffset() const { return faceVertexOffset; }
206 
207 	/** Retrieves the number of holes which appear before this polygon set.
208 		This value is useful when traversing all the face-vertex pairs of a geometric mesh. */
GetHoleOffset()209 	inline size_t GetHoleOffset() const { return holeOffset; }
210 
211 	/** Retrieves the number of face-vertex pairs which appear
212 		before a given face within the polygon set.
213 		This value is useful when doing per-vertex mesh operations within the polygon set.
214 		@param index The index of the face.
215 		@return The number of face-vertex pairs before the given face, within the polygon set. */
216 	size_t GetFaceVertexOffset(size_t index) const;
217 
218 	/** [INTERNAL] Sets the number of faces in previous polygon sets.
219 		Used by the FCDGeometryMesh::Recalculate function.
220 		@param offset The number of faces in previous polygon sets. */
SetFaceOffset(size_t offset)221 	inline void SetFaceOffset(size_t offset) { faceOffset = offset; SetDirtyFlag(); }
222 
223 	/** [INTERNAL] Sets the number of face-vertex pairs in previous polygon sets.
224 		Used by the FCDGeometryMesh::Recalculate function.
225 		@param offset The number of face-vertex pairs in previous polygon sets. */
SetFaceVertexOffset(size_t offset)226 	inline void SetFaceVertexOffset(size_t offset) { faceVertexOffset = offset; SetDirtyFlag(); }
227 
228 	/** [INTERNAL] Sets the number of holes in previous polygon sets.
229 		Used by the FCDGeometryMesh::Recalculate function.
230 		@param offset The number of holes in previous polygon sets. */
SetHoleOffset(size_t offset)231 	inline void SetHoleOffset(size_t offset) { holeOffset = offset; SetDirtyFlag(); }
232 
233 	/** Creates a new face.
234 		Enough indices to fill the face will be added to the polygon set inputs: you will
235 		want to overwrite those, as they will all be set to zero.
236 		@param degree The degree of the polygon. This number implies the number of indices
237 			that will be expected, in order, within each of the input index lists. */
238 	virtual void AddFace(uint32 degree);
239 
240 	/** Removes a face.
241 		@param index The index of the face to remove. All the indices associated
242 			with this face will also be removed. */
243 	virtual void RemoveFace(size_t index);
244 
245 	/** Retrieves the list of polygon set inputs.
246 		@see FCDGeometryPolygonsInput
247 		@return The list of polygon set inputs. */
GetInputs()248 	DEPRECATED(3.05A, GetInputCount and GetInput(index)) void GetInputs() {}
249 
250 	/** Retrieves the number of polygon set inputs.
251 		@return The number of polygon set inputs. */
GetInputCount()252 	inline size_t GetInputCount() const { return inputs.size(); }
253 
254 	/** Retrieves a specific polygon set input.
255 		@param index The index of the polygon set input. This index should
256 			not be greater than or equal to the number of polygon set inputs.
257 		@return The specific polygon set input. This pointer will be NULL if the index is out-of-bounds. */
GetInput(size_t index)258 	inline FCDGeometryPolygonsInput* GetInput(size_t index) { FUAssert(index < GetInputCount(), return NULL); return inputs.at(index); }
GetInput(size_t index)259 	inline const FCDGeometryPolygonsInput* GetInput(size_t index) const { FUAssert(index < GetInputCount(), return NULL); return inputs.at(index); } /**< See above. */
260 
261 	/** Creates a new polygon set input.
262 		@param source The data source for the polygon set input.
263 		@param offset The tessellation indices offset for the polygon set input.
264 			If this value is new to the list of polygon inputs, you will need to fill in the indices.
265 			Please use the FindIndices function to verify that the offset is new and that indices need
266 			to be provided. The offset of zero is reserved for per-vertex data sources.
267 		@return The new polygon set input. */
268 	FCDGeometryPolygonsInput* AddInput(FCDGeometrySource* source, uint32 offset);
269 
270 	/** Retrieves the number of hole entries within the face-vertex count list.
271 		@return The number of hole entries within the face-vertex count list. */
GetHoleFaceCount()272 	inline size_t GetHoleFaceCount() const { return holeFaces.size(); }
273 
274 	/** Sets the number of hole entries within the face-vertex count list.
275 		Any additional hole entries will need to be initialized by the application.
276 		Reducing the number of hole entries without taking special care to remove
277 		these entries from the face-vertex count list will result in new, unwanted, faces.
278 		@param count The number of hole entries within the face-vertex count list. */
279 	void SetHoleFaceCount(size_t count);
280 
281 	/** Checks whether a given face-vertex count entries represents a hole.
282 		@param index The index of the face-vertex count entry.
283 		@return Whether this face-vertex count entry is a hole. */
284 	bool IsHoleFaceHole(size_t index);
285 
286 	/** Retrieves the list of entries within the face-vertex count list
287 		that are considered holes. COLLADA does not support holes within holes,
288 		so each entry within this list implies a hole within the previous face.
289 		@see GetFaceVertexCounts
290 		@return The list of hole entries within the face-vertex counts. */
GetHoleFaces()291 	inline const uint32* GetHoleFaces() const { return holeFaces.begin(); } /**< See above. */
292 
293 	/** Adds a new hole identifier.
294 		The face-vertex count entry should already exist and the identifier will be place
295 		in increasing order within the current list of entries within the face-vertex count list.
296 		@param index The index of the hole within the face-vertex count list. */
297 	void AddHole(uint32 index);
298 
299 	/** Retrieves the number of holes within faces of the polygon set that appear
300 		before the given face index. This value is useful when trying to access
301 		a specific face of a mesh, as holes and faces appear together within the
302 		face-vertex degree list.
303 		@param index A face index.
304 		@return The number of holes within the polygon set that appear
305 			before the given face index. */
306 	size_t GetHoleCountBefore(size_t index) const;
307 
308 	/** Retrieves the number of holes within a given face.
309 		@param index A face index.
310 		@return The number of holes within the given face. */
311 	size_t GetHoleCount(size_t index) const;
312 
313 	/** Retrieves the first polygon set input found that has the given data type.
314 		@param semantic A type of geometry data.
315 		@return The polygon set input. This pointer will be NULL if
316 			no polygon set input matches the data type. */
FindInput(FUDaeGeometryInput::Semantic semantic)317 	FCDGeometryPolygonsInput* FindInput(FUDaeGeometryInput::Semantic semantic) { return const_cast<FCDGeometryPolygonsInput*>(const_cast<const FCDGeometryPolygons*>(this)->FindInput(semantic)); }
318 	const FCDGeometryPolygonsInput* FindInput(FUDaeGeometryInput::Semantic semantic) const; /**< See above. */
319 
320 	/** Retrieves the polygon set input that points towards a given data source.
321 		@param source A geometry data source.
322 		@return The polygon set input. This pointer will be NULL if
323 			no polygon set input matches the data source. */
FindInput(const FCDGeometrySource * source)324 	FCDGeometryPolygonsInput* FindInput(const FCDGeometrySource* source) { return const_cast<FCDGeometryPolygonsInput*>(const_cast<const FCDGeometryPolygons*>(this)->FindInput(source)); }
325 	const FCDGeometryPolygonsInput* FindInput(const FCDGeometrySource* source) const; /**< See above. */
326 
327 	/** [INTERNAL] Retrieves the polygon set input that points towards a given data source.
328 		@param sourceId The COLLADA id of a geometry data source.
329 		@return The polygon set input. This pointer will be NULL if
330 			no polygon set input matches the COLLADA id. */
331 	FCDGeometryPolygonsInput* FindInput(const fm::string& sourceId);
332 
333 	/** Retrieves all the polygon set inputs that have the given data type.
334 		@param semantic A type of geometry data.
335 		@param inputs A list of polygon set inputs to fill in. This list is not emptied by the function
336 			and may remain untouched, if no polygon set input matches the given data type. */
FindInputs(FUDaeGeometryInput::Semantic semantic,FCDGeometryPolygonsInputList & inputs)337 	inline void FindInputs(FUDaeGeometryInput::Semantic semantic, FCDGeometryPolygonsInputList& inputs) { const_cast<FCDGeometryPolygons*>(this)->FindInputs(semantic, *(FCDGeometryPolygonsInputConstList*)&inputs); }
338 	void FindInputs(FUDaeGeometryInput::Semantic semantic, FCDGeometryPolygonsInputConstList& inputs) const; /**< See above. */
339 
340 	/** Retrieves the symbolic name for the material used on this polygon set.
341 		Match this symbolic name within a FCDGeometryInstance to get the
342 		correct material instance.
343 		@return A symbolic material name. */
GetMaterialSemantic()344 	inline const fstring& GetMaterialSemantic() const { return materialSemantic; }
345 
346 	/** Sets a symbolic name for the material used on this polygon set.
347 		This symbolic name will be matched in the FCDMaterialInstance contained within
348 		a FCDGeometryInstance to assign the correct material.
349 		@param semantic The symbolic material name. */
SetMaterialSemantic(const fchar * semantic)350 	inline void SetMaterialSemantic(const fchar* semantic) { materialSemantic = semantic; SetDirtyFlag(); }
SetMaterialSemantic(const fstring & semantic)351 	inline void SetMaterialSemantic(const fstring& semantic) { materialSemantic = semantic; SetDirtyFlag(); } /**< See above. */
352 
353 	/** [INTERNAL] Recalculates the buffered offset and count values for this polygon set. */
354 	virtual void Recalculate();
355 
356 	/** [INTERNAL] Creates a copy of this mesh.
357 		You should use the FCDGeometry::Clone function instead of this function.
358 		@param clone The clone polygon set.
359 		@param cloneMap A match-map of the original geometry sources to the clone geometry sources for the mesh.
360 		@return The clone polygon set. */
361 	virtual FCDGeometryPolygons* Clone(FCDGeometryPolygons* clone, const FCDGeometrySourceCloneMap& cloneMap) const;
362 };
363 
364 #endif // _FCD_GEOMETRY_POLYGONS_H_
365