ScummVM API documentation
dgPolyhedra.h
1 /* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __dgPolyhedra__
23 #define __dgPolyhedra__
24 
25 #include "dgStdafx.h"
26 #include "dgList.h"
27 #include "dgTree.h"
28 #include "dgHeap.h"
29 #include "dgDebug.h"
30 
31 
32 
33 
34 class dgEdge;
35 class dgPlane;
36 class dgSphere;
37 class dgMatrix;
38 class dgPolyhedra;
39 
40 
41 typedef dgInt64 dgEdgeKey;
42 
43 /*
44 class dgPolyhedraDescriptor
45 {
46  public:
47 
48  dgPolyhedraDescriptor (const dgPolyhedra& polyhedra);
49  ~dgPolyhedraDescriptor ();
50  void Update (const dgPolyhedra& polyhedra);
51 
52  dgInt32 m_faceCount; // total face count including openfaces
53  dgInt32 m_edgeCount; // total edge count count including openfaces
54  dgInt32 m_vertexCount; // total vertex count including openfaces
55  dgInt32 m_maxVertexIndex;
56  dgList<dgEdge*> m_unboundedLoops;
57 };
58 */
59 
60 DG_MSC_VECTOR_ALIGMENT
61 class dgEdge {
62 public:
63  dgEdge();
64  dgEdge(dgInt32 vertex, dgInt32 face, dgUnsigned64 userdata = 0);
65 
66  dgInt32 m_incidentVertex;
67  dgInt32 m_incidentFace;
68  dgUnsigned64 m_userData;
69  dgEdge *m_next;
70  dgEdge *m_prev;
71  dgEdge *m_twin;
72  dgInt32 m_mark;
73 } DG_GCC_VECTOR_ALIGMENT;
74 
75 
76 class dgPolyhedra: public dgTree <dgEdge, dgEdgeKey> {
77 public:
78 
79  struct dgPairKey {
80  dgPairKey();
81  dgPairKey(dgInt64 val);
82  dgPairKey(dgInt32 v0, dgInt32 v1);
83  dgInt64 GetVal() const;
84  dgInt32 GetLowKey() const;
85  dgInt32 GetHighKey() const;
86 
87  private:
88  dgUnsigned64 m_key;
89  };
90 
91  dgPolyhedra(dgMemoryAllocator *const allocator);
92  dgPolyhedra(const dgPolyhedra &polyhedra);
93  virtual ~dgPolyhedra();
94 
95  void BeginFace();
96  dgEdge *AddFace(dgInt32 v0, dgInt32 v1, dgInt32 v2);
97  dgEdge *AddFace(dgInt32 count, const dgInt32 *const index);
98  dgEdge *AddFace(dgInt32 count, const dgInt32 *const index, const dgInt64 *const userdata);
99  void EndFace();
100  void DeleteFace(dgEdge *const edge);
101 
102  dgInt32 GetFaceCount() const;
103  dgInt32 GetEdgeCount() const;
104  dgInt32 GetLastVertexIndex() const;
105 
106  dgInt32 IncLRU() const;
107  void SetLRU(dgInt32 lru) const;
108 
109  dgEdge *FindEdge(dgInt32 v0, dgInt32 v1) const;
110  dgTreeNode *FindEdgeNode(dgInt32 v0, dgInt32 v1) const;
111 
112  dgEdge *AddHalfEdge(dgInt32 v0, dgInt32 v1);
113  void DeleteEdge(dgEdge *const edge);
114  void DeleteEdge(dgInt32 v0, dgInt32 v1);
115 
116  bool FlipEdge(dgEdge *const edge);
117  dgEdge *SpliteEdge(dgInt32 newIndex, dgEdge *const edge);
118  dgBigVector FaceNormal(dgEdge *const face, const dgFloat64 *const vertex, dgInt32 strideInBytes) const;
119 
120  void BeginConectedSurface() const;
121  bool GetConectedSurface(dgPolyhedra &polyhedra) const;
122  void EndConectedSurface() const;
123 
124  dgSphere CalculateSphere(const dgFloat64 *const vertex, dgInt32 strideInBytes, const dgMatrix *const basis = NULL) const;
125  void ChangeEdgeIncidentVertex(dgEdge *const edge, dgInt32 newIndex);
126  void DeleteDegenerateFaces(const dgFloat64 *const pool, dgInt32 dstStrideInBytes, dgFloat64 minArea);
127 
128  void Optimize(const dgFloat64 *const pool, dgInt32 strideInBytes, dgFloat64 tol);
129  void Triangulate(const dgFloat64 *const vertex, dgInt32 strideInBytes, dgPolyhedra *const leftOversOut);
130  void ConvexPartition(const dgFloat64 *const vertex, dgInt32 strideInBytes, dgPolyhedra *const leftOversOut);
131 
132  /*
133  bool SanityCheck() const;
134 
135 
136  // create an edge and add it to the tree.
137  // the edge is not linked to the existing edge list
138 
139 
140  // create a complete edge and add it to the tree
141  // the new edge is linked to the existing edge list
142  // dgEdge* AddEdge (dgInt32 v0, dgInt32 v1);
143 
144  void DeleteEdge (dgInt32 v0, dgInt32 v1);
145  void DeleteEdge (dgEdge* const edge);
146 
147  void DeleteAllFace();
148 
149 
150 
151  dgInt32 GetMaxIndex() const;
152 
153  dgInt32 GetUnboundedFaceCount() const;
154 
155  dgBigVector BigFaceNormal (dgEdge* const face, const dgFloat64* const pool, dgInt32 strideInBytes) const;
156 
157 
158 
159 
160  dgEdge* SpliteEdgeAndTriangulate (dgInt32 newIndex, dgEdge* const edge);
161 
162  dgEdge* FindVertexNode (dgInt32 v0) const;
163 
164  dgInt32 PackVertex (dgFloat64* const destArray, const dgFloat64* const unpackArray, dgInt32 strideInBytes);
165  void DeleteOverlapingFaces (const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 distTol);
166  void InvertWinding ();
167 
168  // find edges edge shared by two or more non adjacent faces
169  // this make impossible to triangulate the polyhedra
170  void GetBadEdges (dgList<dgEdge*>& faceList, const dgFloat64* const pool, dgInt32 strideInBytes) const;
171 
172 
173  void GetCoplanarFaces (dgList<dgEdge*>& faceList, dgEdge* startFace, const dgFloat64* const pool, dgInt32 hisStrideInBytes, dgFloat64 normalDeviation) const;
174  void GetOpenFaces (dgList<dgEdge*>& faceList) const;
175  void CollapseDegenerateFaces (dgPolyhedraDescriptor &desc, const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 area);
176 
177 
178 
179  // this function assume the mesh is a legal mesh;
180  dgInt32 TriangleList (dgUnsigned32 outputBuffer[], dgInt32 maxBufferSize, dgInt32 vertexCacheSize = 12) const;
181  void SwapInfo (dgPolyhedra& source);
182 
183 
184  */
185 
186  // this function ayend to create a better triangulation of a mesh
187  // by first calling the calling quadrangular and then triangulate
188  // all quad strips.
189  // this function assume the mesh is a legal mesh;
190  // note1: recommend a call to Triangulate or OptimalTriangulation
191  // before using this function
192  // note2: a index set to 0xffffffff indicate a run start
193  // return index count
194  // dgInt32 TriangleStrips (dgUnsigned32 outputBuffer[], dgInt32 maxBufferSize, dgInt32 vertexCacheSize = 12) const;
195  // void OptimalTriangulation (const dgFloat64* const vertex, dgInt32 strideInBytes);
196  // void CombineOpenFaces (const dgFloat64* const pool, dgInt32 strideInBytes, dgFloat64 distTol);
197  // bool TriangulateFace (dgEdge* const face, const dgFloat64* const vertex, dgInt32 strideInBytes, dgBigVector& normalOut);
198  // void OptimizeTriangulation (const dgFloat64* const vertex, dgInt32 strideInBytes);
199  // void Quadrangulate (const dgFloat64* const vertex, dgInt32 strideInBytes);
200  // dgEdge* GetBadEdge (dgList<dgEdge*>& faceList const dgFloat64* const pool, dgInt32 strideInBytes) const;
201 
202 private:
203 
204  void RefineTriangulation(const dgFloat64 *const vertex, dgInt32 stride);
205  void RefineTriangulation(const dgFloat64 *const vertex, dgInt32 stride, dgBigVector *const normal, dgInt32 perimeterCount, dgEdge **const perimeter);
206  void OptimizeTriangulation(const dgFloat64 *const vertex, dgInt32 strideInBytes);
207  void MarkAdjacentCoplanarFaces(dgPolyhedra &polyhedraOut, dgEdge *const face, const dgFloat64 *const pool, dgInt32 strideInBytes);
208  dgEdge *FindEarTip(dgEdge *const face, const dgFloat64 *const pool, dgInt32 stride, dgDownHeap<dgEdge *, dgFloat64> &heap, const dgBigVector &normal) const;
209  dgEdge *TriangulateFace(dgEdge *face, const dgFloat64 *const pool, dgInt32 stride, dgDownHeap<dgEdge *, dgFloat64> &heap, dgBigVector *const faceNormalOut);
210 
211  dgFloat64 EdgePenalty(const dgBigVector *const pool, dgEdge *const edge) const;
212 
213  mutable dgInt32 m_baseMark;
214  mutable dgInt32 m_edgeMark;
215  mutable dgInt32 m_faceSecuence;
216 
217  friend class dgPolyhedraDescriptor;
218 
219 };
220 
221 
222 
223 inline dgEdge::dgEdge() {
224 }
225 
226 inline dgEdge::dgEdge(dgInt32 vertex, dgInt32 face, dgUnsigned64 userdata)
227  : m_incidentVertex(vertex)
228  , m_incidentFace(face)
229  , m_userData(userdata)
230  , m_next(NULL)
231  , m_prev(NULL)
232  , m_twin(NULL)
233  , m_mark(0) {
234 }
235 
236 
237 inline dgPolyhedra::dgPairKey::dgPairKey() {
238 }
239 
240 inline dgPolyhedra::dgPairKey::dgPairKey(dgInt64 val)
241  : m_key(dgUnsigned64(val)) {
242 }
243 
244 inline dgPolyhedra::dgPairKey::dgPairKey(dgInt32 v0, dgInt32 v1)
245  : m_key(dgUnsigned64((dgInt64(v0) << 32) | v1)) {
246 }
247 
248 inline dgInt64 dgPolyhedra::dgPairKey::GetVal() const {
249  return dgInt64(m_key);
250 }
251 
252 inline dgInt32 dgPolyhedra::dgPairKey::GetLowKey() const {
253  return dgInt32(m_key >> 32);
254 }
255 
256 inline dgInt32 dgPolyhedra::dgPairKey::GetHighKey() const {
257  return dgInt32(m_key & 0xffffffff);
258 }
259 
260 inline void dgPolyhedra::BeginFace() {
261 }
262 
263 inline dgEdge *dgPolyhedra::AddFace(dgInt32 count, const dgInt32 *const index) {
264  return AddFace(count, index, NULL);
265 }
266 
267 inline dgEdge *dgPolyhedra::AddFace(dgInt32 v0, dgInt32 v1, dgInt32 v2) {
268  dgInt32 vertex[3];
269 
270  vertex [0] = v0;
271  vertex [1] = v1;
272  vertex [2] = v2;
273  return AddFace(3, vertex, NULL);
274 }
275 
276 inline dgInt32 dgPolyhedra::GetEdgeCount() const {
277 #ifdef _DEBUG
278  dgInt32 edgeCount = 0;
279  Iterator iter(*this);
280  for (iter.Begin(); iter; iter ++) {
281  edgeCount ++;
282  }
283  NEWTON_ASSERT(edgeCount == GetCount());;
284 #endif
285  return GetCount();
286 }
287 
288 inline dgInt32 dgPolyhedra::GetLastVertexIndex() const {
289  dgInt32 maxVertexIndex = -1;
290  Iterator iter(*this);
291  for (iter.Begin(); iter; iter ++) {
292  const dgEdge *const edge = &(*iter);
293  if (edge->m_incidentVertex > maxVertexIndex) {
294  maxVertexIndex = edge->m_incidentVertex;
295  }
296  }
297  return maxVertexIndex + 1;
298 }
299 
300 
301 inline dgInt32 dgPolyhedra::IncLRU() const {
302  m_edgeMark ++;
303  NEWTON_ASSERT(m_edgeMark < 0x7fffffff);
304  return m_edgeMark;
305 }
306 
307 inline void dgPolyhedra::SetLRU(dgInt32 lru) const {
308  if (lru > m_edgeMark) {
309  m_edgeMark = lru;
310  }
311 }
312 
313 inline void dgPolyhedra::BeginConectedSurface() const {
314  m_baseMark = IncLRU();
315 }
316 
317 inline void dgPolyhedra::EndConectedSurface() const {
318 }
319 
320 
321 inline dgPolyhedra::dgTreeNode *dgPolyhedra::FindEdgeNode(dgInt32 i0, dgInt32 i1) const {
322  dgPairKey key(i0, i1);
323  return Find(key.GetVal());
324 }
325 
326 
327 inline dgEdge *dgPolyhedra::FindEdge(dgInt32 i0, dgInt32 i1) const {
328  // dgTreeNode *node;
329  // dgPairKey key (i0, i1);
330  // node = Find (key.GetVal());
331  // return node ? &node->GetInfo() : NULL;
332  dgTreeNode *const node = FindEdgeNode(i0, i1);
333  return node ? &node->GetInfo() : NULL;
334 }
335 
336 inline void dgPolyhedra::DeleteEdge(dgInt32 v0, dgInt32 v1) {
337  dgPairKey pairKey(v0, v1);
338  dgTreeNode *const node = Find(pairKey.GetVal());
339  dgEdge *const edge = node ? &node->GetInfo() : NULL;
340  if (!edge) {
341  return;
342  }
343  DeleteEdge(edge);
344 }
345 
346 
347 #endif
348 
Definition: dgPlane.h:29
Definition: dgPolyhedra.h:61
Definition: dgSphere.h:37
Definition: dgTree.h:88
Definition: dgPolyhedra.h:76
Definition: dgHeap.h:75
Definition: dgPolyhedra.h:79
Definition: dgMatrix.h:41
Definition: dgMemory.h:80
Definition: dgVector.h:104