aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/shared/general/HACD/include/dgMeshEffect.h
blob: 148d3d0ef6c1918743ae8f2c05f49cf61a30a0f0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
/* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
* 
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* 
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef __dgMeshEffect_H__
#define __dgMeshEffect_H__

#include "dgTypes.h"
#include "dgRefCounter.h"
#include "dgPolyhedra.h"
#include "dgVector.h"
#include "dgPlane.h"
#include "dgMatrix.h"
#include "SparseArray.h"

class dgMeshEffect;
class dgMeshEffectSolidTree;
class dgMeshTreeCSGEdgePool;
class dgConvexHull3d;
class dgThreadHive;


#define DG_MESH_EFFECT_INITIAL_VERTEX_SIZE	8
#define DG_MESH_EFFECT_BOLLEAN_STACK		512
#define DG_MESH_EFFECT_POINT_SPLITED		512
#define DG_MESH_EFFECT_POLYGON_SPLITED		256
#define DG_MESH_EFFECT_FLAT_CUT_BORDER_EDGE	0x01
#define DG_VERTEXLIST_INDEXLIST_TOL			(double (0.0f))


#define DG_MESH_EFFECT_PRECISION_BITS		30
#define DG_MESH_EFFECT_PRECISION_SCALE		double(1<<DG_MESH_EFFECT_PRECISION_BITS)
#define DG_MESH_EFFECT_PRECISION_SCALE_INV	(double (1.0f) / DG_MESH_EFFECT_PRECISION_SCALE)


#define DG_MESG_EFFECT_BOOLEAN_INIT()					\
	dgMeshEffect* result = NULL;						\
	dgMeshEffect* sourceCoplanar = NULL;				\
	dgMeshEffect* leftMeshSource = NULL;				\
	dgMeshEffect* rightMeshSource = NULL;				\
	dgMeshEffect* clipperCoplanar = NULL;				\
	dgMeshEffect* leftMeshClipper = NULL;				\
	dgMeshEffect* rightMeshClipper = NULL;

#define DG_MESG_EFFECT_BOOLEAN_FINISH()					\
	if (sourceCoplanar) {								\
		sourceCoplanar->Release();						\
	}													\
	if (clipperCoplanar) {								\
		clipperCoplanar->Release();						\
	}													\
	if (leftMeshClipper) {								\
		leftMeshClipper->Release();						\
	}													\
	if (rightMeshClipper) {								\
		rightMeshClipper->Release();					\
	}													\
	if (leftMeshSource) {								\
		leftMeshSource->Release();						\
	}													\
	if (rightMeshSource) {								\
		rightMeshSource->Release();						\
	}													\
	if (result) {										\
		result->ConvertToPolygons();					\
		dgStack<int32_t> map(result->m_pointCount + 1);	\
		result->RemoveUnusedVertices(&map[0]);			\
	}													



class dgMeshEffect: public dgPolyhedra, public dgRefCounter, public UANS::UserAllocated
{
	public:

	class dgVertexAtribute 
	{
		public:
		dgBigVector m_vertex;
		double m_normal_x;
		double m_normal_y;
		double m_normal_z;
		double m_u0;
		double m_v0;
		double m_u1;
		double m_v1;
		double m_material;
	};

	class dgIndexArray 
	{
		public:
		int32_t m_materialCount;
		int32_t m_indexCount;
		int32_t m_materials[256];
		int32_t m_materialsIndexCount[256];
		int32_t* m_indexList;
	};


	dgMeshEffect(bool preAllocaBuffers);
	dgMeshEffect(const dgMeshEffect& source);
	dgMeshEffect(dgPolyhedra& mesh, const dgMeshEffect& source);

	// Create a convex hull Mesh form point cloud
	dgMeshEffect (const double* const vertexCloud, int32_t count, int32_t strideInByte, double distTol);

	// create a convex approximation
	dgMeshEffect (const dgMeshEffect& source, float maxConcavity, int32_t maxCount = 32, hacd::ICallback* callback = NULL);

	// create a planar Mesh
	dgMeshEffect(const dgMatrix& planeMatrix, float witdth, float breadth, int32_t material, const dgMatrix& textureMatrix0, const dgMatrix& textureMatrix1);
	virtual ~dgMeshEffect(void);

	dgMatrix CalculateOOBB (dgBigVector& size) const;
	void CalculateAABB (dgBigVector& min, dgBigVector& max) const;

	void CalculateNormals (double angleInRadians);
	void SphericalMapping (int32_t material);
	void BoxMapping (int32_t front, int32_t side, int32_t top);
	void UniformBoxMapping (int32_t material, const dgMatrix& textruMatrix);
	void CylindricalMapping (int32_t cylinderMaterial, int32_t capMaterial);

	dgEdge* InsertEdgeVertex (dgEdge* const edge, double param);

	dgMeshEffect* GetFirstLayer ();
	dgMeshEffect* GetNextLayer (dgMeshEffect* const layer);

	void Triangulate ();
	void ConvertToPolygons ();

	void RemoveUnusedVertices(int32_t* const vertexRemapTable);
	
	void BeginPolygon ();
	void AddPolygon (int32_t count, const float* const vertexList, int32_t stride, int32_t material);
	void AddPolygon (int32_t count, const double* const vertexList, int32_t stride, int32_t material);
	void EndPolygon (double tol);

	void PackVertexArrays ();

	void BuildFromVertexListIndexList(int32_t faceCount, const int32_t * const faceIndexCount, const int32_t * const faceMaterialIndex, 
		const float* const vertex, int32_t  vertexStrideInBytes, const int32_t * const vertexIndex,
		const float* const normal, int32_t  normalStrideInBytes, const int32_t * const normalIndex,
		const float* const uv0, int32_t  uv0StrideInBytes, const int32_t * const uv0Index,
		const float* const uv1, int32_t  uv1StrideInBytes, const int32_t * const uv1Index);


	int32_t GetVertexCount() const;
	int32_t GetVertexStrideInByte() const;
	double* GetVertexPool () const;

	int32_t GetPropertiesCount() const;
	int32_t GetPropertiesStrideInByte() const;
	double* GetAttributePool() const;
	double* GetNormalPool() const;
	double* GetUV0Pool() const;
	double* GetUV1Pool() const;

	dgEdge* ConectVertex (dgEdge* const e0, dgEdge* const e1);

	int32_t GetTotalFaceCount() const;
	int32_t GetTotalIndexCount() const;
	void GetFaces (int32_t* const faceCount, int32_t* const materials, void** const faceNodeList) const;

	void RepairTJoints (bool triangulate);
	bool SeparateDuplicateLoops (dgEdge* const edge);
	bool HasOpenEdges () const;

	void GetVertexStreams (int32_t vetexStrideInByte, float* const vertex, 
						   int32_t normalStrideInByte, float* const normal, 
						   int32_t uvStrideInByte0, float* const uv0, 
						   int32_t uvStrideInByte1, float* const uv1);

	void GetIndirectVertexStreams(int32_t vetexStrideInByte, double* const vertex, int32_t* const vertexIndices, int32_t* const vertexCount,
								  int32_t normalStrideInByte, double* const normal, int32_t* const normalIndices, int32_t* const normalCount,
								  int32_t uvStrideInByte0, double* const uv0, int32_t* const uvIndices0, int32_t* const uvCount0,
								  int32_t uvStrideInByte1, double* const uv1, int32_t* const uvIndices1, int32_t* const uvCount1);

	

	dgIndexArray* MaterialGeometryBegin();
	void MaterialGeomteryEnd(dgIndexArray* const handle);
	int32_t GetFirstMaterial (dgIndexArray* const handle);
	int32_t GetNextMaterial (dgIndexArray* const handle, int32_t materialHandle);
	int32_t GetMaterialID (dgIndexArray* const handle, int32_t materialHandle);
	int32_t GetMaterialIndexCount (dgIndexArray* const handle, int32_t materialHandle);
	void GetMaterialGetIndexStream (dgIndexArray* const handle, int32_t materialHandle, int32_t* const index);
	void GetMaterialGetIndexStreamShort (dgIndexArray* const handle, int32_t materialHandle, int16_t* const index);
	
	dgConvexHull3d * CreateConvexHull(double tolerance,int32_t maxVertexCount) const;

	dgMeshEffect* CreateConvexApproximation(
		float maxConcavity, 
		float backFaceDistanceFactor, 
		int32_t maxHullsCount, 
		int32_t maxVertexPerHull,
		hacd::ICallback *reportProgressCallback) const;

	// Old, Legacy, 'fast' version
	dgMeshEffect(const dgMeshEffect& source,
				float absoluteconcavity,
				int32_t maxCount,
				hacd::ICallback *callback,
				bool legacyVersion);

	dgMeshEffect* CreateConvexApproximationFast(float maxConcavity, int32_t maxCount,hacd::ICallback *callback) const;

	dgMeshEffect* CreateSimplification(int32_t maxVertexCount, hacd::ICallback *reportProgressCallback) const;

	dgVertexAtribute& GetAttribute (int32_t index) const;
	void TransformMesh (const dgMatrix& matrix);


	void* GetFirstVertex ();
	void* GetNextVertex (const void* const vertex);
	int GetVertexIndex (const void* const vertex) const;

	void* GetFirstPoint ();
	void* GetNextPoint (const void* const point);
	int GetPointIndex (const void* const point) const;
	int GetVertexIndexFromPoint (const void* const point) const;


	void* GetFirstEdge ();
	void* GetNextEdge (const void* const edge);
	void GetEdgeIndex (const void* const edge, int32_t& v0, int32_t& v1) const;
//	void GetEdgeAttributeIndex (const void* edge, int32_t& v0, int32_t& v1) const;

	void* GetFirstFace ();
	void* GetNextFace (const void* const face);
	int IsFaceOpen (const void* const face) const;
	int GetFaceMaterial (const void* const face) const;
	int GetFaceIndexCount (const void* const face) const;
	void GetFaceIndex (const void* const face, int* const indices) const;
	void GetFaceAttributeIndex (const void* const face, int* const indices) const;

	bool Sanity () const;

	protected:
	void ClearAttributeArray ();
	void Init (bool preAllocaBuffers);
	dgBigVector GetOrigin ()const;
	int32_t CalculateMaxAttributes () const;
	double QuantizeCordinade(double val) const;
	int32_t EnumerateAttributeArray (dgVertexAtribute* const attib);
	void ApplyAttributeArray (dgVertexAtribute* const attib,int32_t maxCount);
	void AddVertex(const dgBigVector& vertex);
	void AddAtribute (const dgVertexAtribute& attib);
	void AddPoint(const double* vertexList, int32_t material);
	void FixCylindricalMapping (dgVertexAtribute* const attib) const;

	void MergeFaces (const dgMeshEffect* const source);
	void ReverseMergeFaces (dgMeshEffect* const source);
	dgVertexAtribute InterpolateEdge (dgEdge* const edge, double param) const;
	dgVertexAtribute InterpolateVertex (const dgBigVector& point, dgEdge* const face) const;

	dgMeshEffect* GetNextLayer (int32_t mark);

	void FilterCoplanarFaces (const dgMeshEffect* const otherCap, float sign);

	bool CheckSingleMesh() const;


	int32_t m_pointCount;
	int32_t m_maxPointCount;

	int32_t m_atribCount;
	int32_t m_maxAtribCount;

	dgBigVector* m_points;
	dgVertexAtribute* m_attib;

	
	friend class dgConvexHull3d;
	friend class dgConvexHull4d;
	friend class dgMeshTreeCSGFace;
	friend class dgMeshEffectSolidTree;
};



inline int32_t dgMeshEffect::GetVertexCount() const
{
	return m_pointCount;
}

inline int32_t dgMeshEffect::GetPropertiesCount() const
{
	return m_atribCount;
}

inline int32_t dgMeshEffect::GetMaterialID (dgIndexArray* const handle, int32_t materialHandle)
{
	return handle->m_materials[materialHandle];
}

inline int32_t dgMeshEffect::GetMaterialIndexCount (dgIndexArray* const handle, int32_t materialHandle)
{
	return handle->m_materialsIndexCount[materialHandle];
}

inline dgMeshEffect::dgVertexAtribute& dgMeshEffect::GetAttribute (int32_t index) const 
{
	return m_attib[index];
}

inline int32_t dgMeshEffect::GetPropertiesStrideInByte() const 
{
	return sizeof (dgVertexAtribute);
}

inline double* dgMeshEffect::GetAttributePool() const 
{
	return &m_attib->m_vertex.m_x;
}

inline double* dgMeshEffect::GetNormalPool() const 
{
	return &m_attib->m_normal_x;
}

inline double* dgMeshEffect::GetUV0Pool() const 
{
	return &m_attib->m_u0;
}

inline double* dgMeshEffect::GetUV1Pool() const 
{
	return &m_attib->m_u1;
}

inline int32_t dgMeshEffect::GetVertexStrideInByte() const 
{
	return sizeof (dgBigVector);
}

inline double* dgMeshEffect::GetVertexPool () const 
{
	return &m_points[0].m_x;
}


inline dgMeshEffect* dgMeshEffect::GetFirstLayer ()
{
	return GetNextLayer (IncLRU());
}

inline dgMeshEffect* dgMeshEffect::GetNextLayer (dgMeshEffect* const layerSegment)
{
	if (!layerSegment) {
		return NULL;
	}
	return GetNextLayer (layerSegment->IncLRU() - 1);
}


inline double dgMeshEffect::QuantizeCordinade(double x) const
{
	int32_t exp;
	double mantissa = frexp(x, &exp);
	mantissa = DG_MESH_EFFECT_PRECISION_SCALE_INV * floor (mantissa * DG_MESH_EFFECT_PRECISION_SCALE);

	double x1 = ldexp(mantissa, exp);
	return x1;
}

#endif