File: dgPolyhedra.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (348 lines) | stat: -rw-r--r-- 10,659 bytes parent folder | download | duplicates (3)
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
/* 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 __dgPolyhedra__
#define __dgPolyhedra__

#include "dgStdafx.h"
#include "dgList.h"
#include "dgTree.h"
#include "dgHeap.h"
#include "dgDebug.h"




class dgEdge;
class dgPlane;
class dgSphere;
class dgMatrix;
class dgPolyhedra;


typedef dgInt64 dgEdgeKey;

/*
class dgPolyhedraDescriptor
{
    public:

     dgPolyhedraDescriptor (const dgPolyhedra& polyhedra);
     ~dgPolyhedraDescriptor ();
     void Update (const dgPolyhedra& polyhedra);

    dgInt32 m_faceCount;                             // total face count including openfaces
    dgInt32 m_edgeCount;                             // total edge count count including openfaces
    dgInt32 m_vertexCount;                       // total vertex count including openfaces
    dgInt32 m_maxVertexIndex;
    dgList<dgEdge*> m_unboundedLoops;
};
*/

DG_MSC_VECTOR_ALIGMENT
class dgEdge {
public:
	dgEdge();
	dgEdge(dgInt32 vertex, dgInt32 face, dgUnsigned64 userdata = 0);

	dgInt32 m_incidentVertex;
	dgInt32 m_incidentFace;
	dgUnsigned64 m_userData;
	dgEdge *m_next;
	dgEdge *m_prev;
	dgEdge *m_twin;
	dgInt32 m_mark;
} DG_GCC_VECTOR_ALIGMENT;


class dgPolyhedra: public dgTree <dgEdge, dgEdgeKey> {
public:

	struct dgPairKey {
		dgPairKey();
		dgPairKey(dgInt64 val);
		dgPairKey(dgInt32 v0, dgInt32 v1);
		dgInt64 GetVal() const;
		dgInt32 GetLowKey() const;
		dgInt32 GetHighKey() const;

	private:
		dgUnsigned64 m_key;
	};

	dgPolyhedra(dgMemoryAllocator *const allocator);
	dgPolyhedra(const dgPolyhedra &polyhedra);
	virtual ~dgPolyhedra();

	void BeginFace();
	dgEdge *AddFace(dgInt32 v0, dgInt32 v1, dgInt32 v2);
	dgEdge *AddFace(dgInt32 count, const dgInt32 *const index);
	dgEdge *AddFace(dgInt32 count, const dgInt32 *const index, const dgInt64 *const userdata);
	void EndFace();
	void DeleteFace(dgEdge *const edge);

	dgInt32 GetFaceCount() const;
	dgInt32 GetEdgeCount() const;
	dgInt32 GetLastVertexIndex() const;

	dgInt32 IncLRU() const;
	void SetLRU(dgInt32 lru) const;

	dgEdge *FindEdge(dgInt32 v0, dgInt32 v1) const;
	dgTreeNode *FindEdgeNode(dgInt32 v0, dgInt32 v1) const;

	dgEdge *AddHalfEdge(dgInt32 v0, dgInt32 v1);
	void DeleteEdge(dgEdge *const edge);
	void DeleteEdge(dgInt32 v0, dgInt32 v1);

	bool FlipEdge(dgEdge *const edge);
	dgEdge *SpliteEdge(dgInt32 newIndex, dgEdge *const edge);
	dgBigVector FaceNormal(dgEdge *const face, const dgFloat64 *const vertex, dgInt32 strideInBytes) const;

	void BeginConectedSurface() const;
	bool GetConectedSurface(dgPolyhedra &polyhedra) const;
	void EndConectedSurface() const;

	dgSphere CalculateSphere(const dgFloat64 *const vertex, dgInt32 strideInBytes, const dgMatrix *const basis = NULL) const;
	void ChangeEdgeIncidentVertex(dgEdge *const edge, dgInt32 newIndex);
	void DeleteDegenerateFaces(const dgFloat64 *const pool, dgInt32 dstStrideInBytes, dgFloat64 minArea);

	void Optimize(const dgFloat64 *const pool, dgInt32 strideInBytes, dgFloat64 tol);
	void Triangulate(const dgFloat64 *const vertex, dgInt32 strideInBytes, dgPolyhedra *const leftOversOut);
	void ConvexPartition(const dgFloat64 *const vertex, dgInt32 strideInBytes, dgPolyhedra *const leftOversOut);

	/*
	    bool SanityCheck() const;


	    // create an edge and add it to the tree.
	    // the edge is not linked to the existing edge list


	    // create a complete edge and add it to the tree
	    //  the new edge is linked to the existing edge list
	//  dgEdge* AddEdge (dgInt32 v0, dgInt32 v1);

	    void DeleteEdge (dgInt32 v0, dgInt32 v1);
	    void DeleteEdge (dgEdge* const edge);

	    void DeleteAllFace();



	    dgInt32 GetMaxIndex() const;

	    dgInt32 GetUnboundedFaceCount() const;

	    dgBigVector BigFaceNormal (dgEdge* const face, const dgFloat64* const pool, dgInt32 strideInBytes) const;




	    dgEdge* SpliteEdgeAndTriangulate (dgInt32 newIndex, dgEdge* const edge);

	    dgEdge* FindVertexNode (dgInt32 v0) const;

	    dgInt32 PackVertex (dgFloat64* const destArray, const dgFloat64* const unpackArray, dgInt32 strideInBytes);
	    void DeleteOverlapingFaces (const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 distTol);
	    void InvertWinding ();

	    // find edges edge shared by two or more non adjacent faces
	    // this make impossible to triangulate the polyhedra
	    void GetBadEdges (dgList<dgEdge*>& faceList, const dgFloat64* const pool, dgInt32 strideInBytes) const;


	    void GetCoplanarFaces (dgList<dgEdge*>& faceList, dgEdge* startFace, const dgFloat64* const pool, dgInt32 hisStrideInBytes, dgFloat64 normalDeviation) const;
	    void GetOpenFaces (dgList<dgEdge*>& faceList) const;
	    void CollapseDegenerateFaces (dgPolyhedraDescriptor &desc, const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 area);



	    // this function assume the mesh is a legal mesh;
	    dgInt32 TriangleList (dgUnsigned32 outputBuffer[], dgInt32 maxBufferSize, dgInt32 vertexCacheSize = 12) const;
	    void SwapInfo (dgPolyhedra& source);


	*/

	// this function ayend to create a better triangulation of a mesh
	// by first calling the calling quadrangular and then triangulate
	// all quad strips.
	// this function assume the mesh is a legal mesh;
	// note1: recommend a call to Triangulate or OptimalTriangulation
	//           before using this function
	// note2: a index set to 0xffffffff indicate a run start
	// return index count
	//  dgInt32 TriangleStrips (dgUnsigned32 outputBuffer[], dgInt32 maxBufferSize, dgInt32 vertexCacheSize = 12) const;
	//  void OptimalTriangulation (const dgFloat64* const vertex, dgInt32 strideInBytes);
	//  void CombineOpenFaces (const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 distTol);
	//  bool TriangulateFace (dgEdge* const face, const dgFloat64* const vertex, dgInt32 strideInBytes, dgBigVector& normalOut);
	//  void OptimizeTriangulation (const dgFloat64* const vertex, dgInt32 strideInBytes);
	//  void Quadrangulate (const dgFloat64* const vertex, dgInt32 strideInBytes);
	//  dgEdge* GetBadEdge (dgList<dgEdge*>& faceList  const dgFloat64* const pool, dgInt32 strideInBytes) const;

private:

	void RefineTriangulation(const dgFloat64 *const vertex, dgInt32 stride);
	void RefineTriangulation(const dgFloat64 *const vertex, dgInt32 stride, dgBigVector *const normal, dgInt32 perimeterCount, dgEdge **const perimeter);
	void OptimizeTriangulation(const dgFloat64 *const vertex, dgInt32 strideInBytes);
	void MarkAdjacentCoplanarFaces(dgPolyhedra &polyhedraOut, dgEdge *const face, const dgFloat64 *const pool, dgInt32 strideInBytes);
	dgEdge *FindEarTip(dgEdge *const face, const dgFloat64 *const pool, dgInt32 stride, dgDownHeap<dgEdge *, dgFloat64> &heap, const dgBigVector &normal) const;
	dgEdge *TriangulateFace(dgEdge *face, const dgFloat64 *const pool, dgInt32 stride, dgDownHeap<dgEdge *, dgFloat64> &heap, dgBigVector *const faceNormalOut);

	dgFloat64 EdgePenalty(const dgBigVector *const pool, dgEdge *const edge) const;

	mutable dgInt32 m_baseMark;
	mutable dgInt32 m_edgeMark;
	mutable dgInt32 m_faceSecuence;

	friend class dgPolyhedraDescriptor;

};



inline dgEdge::dgEdge() {
}

inline dgEdge::dgEdge(dgInt32 vertex, dgInt32 face, dgUnsigned64 userdata)
	: m_incidentVertex(vertex)
	, m_incidentFace(face)
	, m_userData(userdata)
	, m_next(NULL)
	, m_prev(NULL)
	, m_twin(NULL)
	, m_mark(0) {
}


inline dgPolyhedra::dgPairKey::dgPairKey() {
}

inline dgPolyhedra::dgPairKey::dgPairKey(dgInt64 val)
	: m_key(dgUnsigned64(val)) {
}

inline dgPolyhedra::dgPairKey::dgPairKey(dgInt32 v0, dgInt32 v1)
	: m_key(dgUnsigned64((dgInt64(v0) << 32) | v1)) {
}

inline dgInt64 dgPolyhedra::dgPairKey::GetVal() const {
	return dgInt64(m_key);
}

inline dgInt32 dgPolyhedra::dgPairKey::GetLowKey() const {
	return dgInt32(m_key >> 32);
}

inline dgInt32 dgPolyhedra::dgPairKey::GetHighKey() const {
	return dgInt32(m_key & 0xffffffff);
}

inline void dgPolyhedra::BeginFace() {
}

inline dgEdge *dgPolyhedra::AddFace(dgInt32 count, const dgInt32 *const index) {
	return AddFace(count, index, NULL);
}

inline dgEdge *dgPolyhedra::AddFace(dgInt32 v0, dgInt32 v1, dgInt32 v2) {
	dgInt32 vertex[3];

	vertex [0] = v0;
	vertex [1] = v1;
	vertex [2] = v2;
	return AddFace(3, vertex, NULL);
}

inline dgInt32 dgPolyhedra::GetEdgeCount() const {
#ifdef _DEBUG
	dgInt32 edgeCount = 0;
	Iterator iter(*this);
	for (iter.Begin(); iter; iter ++) {
		edgeCount ++;
	}
	NEWTON_ASSERT(edgeCount == GetCount());;
#endif
	return GetCount();
}

inline dgInt32 dgPolyhedra::GetLastVertexIndex() const {
	dgInt32 maxVertexIndex = -1;
	Iterator iter(*this);
	for (iter.Begin(); iter; iter ++) {
		const dgEdge *const edge = &(*iter);
		if (edge->m_incidentVertex > maxVertexIndex) {
			maxVertexIndex = edge->m_incidentVertex;
		}
	}
	return maxVertexIndex + 1;
}


inline dgInt32 dgPolyhedra::IncLRU() const {
	m_edgeMark ++;
	NEWTON_ASSERT(m_edgeMark < 0x7fffffff);
	return m_edgeMark;
}

inline void dgPolyhedra::SetLRU(dgInt32 lru) const {
	if (lru > m_edgeMark) {
		m_edgeMark = lru;
	}
}

inline void dgPolyhedra::BeginConectedSurface() const {
	m_baseMark = IncLRU();
}

inline void dgPolyhedra::EndConectedSurface() const {
}


inline dgPolyhedra::dgTreeNode *dgPolyhedra::FindEdgeNode(dgInt32 i0, dgInt32 i1) const {
	dgPairKey key(i0, i1);
	return Find(key.GetVal());
}


inline dgEdge *dgPolyhedra::FindEdge(dgInt32 i0, dgInt32 i1) const {
	//  dgTreeNode *node;
	//  dgPairKey key (i0, i1);
	//  node = Find (key.GetVal());
	//  return node ? &node->GetInfo() : NULL;
	dgTreeNode *const node = FindEdgeNode(i0, i1);
	return node ? &node->GetInfo() : NULL;
}

inline void dgPolyhedra::DeleteEdge(dgInt32 v0, dgInt32 v1) {
	dgPairKey pairKey(v0, v1);
	dgTreeNode *const node = Find(pairKey.GetVal());
	dgEdge *const edge = node ? &node->GetInfo() : NULL;
	if (!edge) {
		return;
	}
	DeleteEdge(edge);
}


#endif