ScummVM API documentation
dgMeshEffect.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 __dgMeshEffect_H__
23 #define __dgMeshEffect_H__
24 
25 #include "hpl1/engine/libraries/newton/core/dg.h"
26 
27 class dgWorld;
28 class dgCollision;
29 class dgMeshEffect;
31 class dgMeshTreeCSGEdgePool;
32 
33 #define DG_MESH_EFFECT_INITIAL_VERTEX_SIZE 8
34 #define DG_MESH_EFFECT_BOLLEAN_STACK 512
35 #define DG_MESH_EFFECT_POINT_SPLITED 512
36 #define DG_MESH_EFFECT_POLYGON_SPLITED 256
37 #define DG_MESH_EFFECT_FLAT_CUT_BORDER_EDGE 0x01
38 #define DG_VERTEXLIST_INDEXLIST_TOL (dgFloat64(0.0f))
39 
40 #define DG_MESH_EFFECT_PRECISION_BITS 30
41 #define DG_MESH_EFFECT_PRECISION_SCALE dgFloat64(1 << DG_MESH_EFFECT_PRECISION_BITS)
42 #define DG_MESH_EFFECT_PRECISION_SCALE_INV (dgFloat64(1.0f) / DG_MESH_EFFECT_PRECISION_SCALE)
43 
44 #define DG_MESG_EFFECT_BOOLEAN_INIT() \
45  dgMeshEffect *result = NULL; \
46  dgMeshEffect *sourceCoplanar = NULL; \
47  dgMeshEffect *leftMeshSource = NULL; \
48  dgMeshEffect *rightMeshSource = NULL; \
49  dgMeshEffect *clipperCoplanar = NULL; \
50  dgMeshEffect *leftMeshClipper = NULL; \
51  dgMeshEffect *rightMeshClipper = NULL;
52 
53 #define DG_MESG_EFFECT_BOOLEAN_FINISH() \
54  if (sourceCoplanar) { \
55  sourceCoplanar->Release(); \
56  } \
57  if (clipperCoplanar) { \
58  clipperCoplanar->Release(); \
59  } \
60  if (leftMeshClipper) { \
61  leftMeshClipper->Release(); \
62  } \
63  if (rightMeshClipper) { \
64  rightMeshClipper->Release(); \
65  } \
66  if (leftMeshSource) { \
67  leftMeshSource->Release(); \
68  } \
69  if (rightMeshSource) { \
70  rightMeshSource->Release(); \
71  } \
72  if (result) { \
73  result->ConvertToPolygons(); \
74  dgStack<dgInt32> map(result->m_pointCount + 1); \
75  result->RemoveUnusedVertices(&map[0]); \
76  }
77 
78 class dgMeshEffect : public dgPolyhedra, public dgRefCounter {
79 public:
81  public:
82  dgBigVector m_vertex;
83  dgFloat64 m_normal_x;
84  dgFloat64 m_normal_y;
85  dgFloat64 m_normal_z;
86  dgFloat64 m_u0;
87  dgFloat64 m_v0;
88  dgFloat64 m_u1;
89  dgFloat64 m_v1;
90  dgFloat64 m_material;
91 
92  void clear() {
93  m_vertex = dgBigVector(0.0f, 0.0f, 0.0f, 0.0f);
94  m_normal_x = 0.0f;
95  m_normal_y = 0.0f;
96  m_normal_z = 0.0f;
97  m_u0 = 0.0f;
98  m_v0 = 0.0f;
99  m_u1 = 0.0f;
100  m_v1 = 0.0f;
101  m_material = 0.0f;
102  }
103  };
104 
105  class dgIndexArray {
106  public:
107  dgInt32 m_materialCount;
108  dgInt32 m_indexCount;
109  dgInt32 m_materials[256];
110  dgInt32 m_materialsIndexCount[256];
111  dgInt32 *m_indexList;
112  };
113 
114  dgMeshEffect(dgMemoryAllocator *const allocator, bool preAllocaBuffers);
115  dgMeshEffect(dgCollision *const collision);
116  dgMeshEffect(const dgMeshEffect &source);
117  dgMeshEffect(dgPolyhedra &mesh, const dgMeshEffect &source);
118 
119  // Create a convex hull Mesh form point cloud
120  dgMeshEffect(dgMemoryAllocator *const allocator, const dgFloat64 *const vertexCloud, dgInt32 count, dgInt32 strideInByte, dgFloat64 distTol);
121 
122  // create a convex approximation
123  dgMeshEffect(const dgMeshEffect &source, dgFloat32 maxConcavity, dgInt32 maxCount = 32);
124 
125  // create a planar Mesh
126  dgMeshEffect(dgMemoryAllocator *const allocator, const dgMatrix &planeMatrix, dgFloat32 witdth, dgFloat32 breadth, dgInt32 material, const dgMatrix &textureMatrix0, const dgMatrix &textureMatrix1);
127  virtual ~dgMeshEffect(void);
128 
129  void ApplyTransform(const dgMatrix &matrix);
130  dgMatrix CalculateOOBB(dgBigVector &size) const;
131  void CalculateAABB(dgBigVector &min, dgBigVector &max) const;
132 
133  void CalculateNormals(dgFloat64 angleInRadians);
134  void SphericalMapping(dgInt32 material);
135  void BoxMapping(dgInt32 front, dgInt32 side, dgInt32 top);
136  void UniformBoxMapping(dgInt32 material, const dgMatrix &textruMatrix);
137  void CylindricalMapping(dgInt32 cylinderMaterial, dgInt32 capMaterial);
138 
139  dgEdge *InsertEdgeVertex(dgEdge *const edge, dgFloat64 param);
140 
141  dgMeshEffect *Union(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
142  dgMeshEffect *Difference(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
143  dgMeshEffect *Intersection(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
144  void ClipMesh(const dgMatrix &matrix, const dgMeshEffect *const clip, dgMeshEffect **const top, dgMeshEffect **const bottom) const;
145 
146  bool CheckIntersection(const dgMeshEffectSolidTree *const solidTree, dgFloat64 scale) const;
147  dgMeshEffectSolidTree *CreateSolidTree() const;
148  static void DestroySolidTree(dgMeshEffectSolidTree *const tree);
149  static bool CheckIntersection(const dgMeshEffect *const meshA, const dgMeshEffectSolidTree *const solidTreeA,
150  const dgMeshEffect *const meshB, const dgMeshEffectSolidTree *const solidTreeB, dgFloat64 scale);
151 
152  dgMeshEffect *GetFirstLayer() const;
153  dgMeshEffect *GetNextLayer(const dgMeshEffect *const layer) const;
154 
155  void Triangulate();
156  void ConvertToPolygons();
157 
158  void RemoveUnusedVertices(dgInt32 *const vertexRemapTable);
159 
160  void BeginPolygon();
161  void AddPolygon(dgInt32 count, const dgFloat32 *const vertexList, dgInt32 stride, dgInt32 material);
162 #ifndef __USE_DOUBLE_PRECISION__
163  void AddPolygon(dgInt32 count, const dgFloat64 *const vertexList, dgInt32 stride, dgInt32 material);
164 #endif
165  void EndPolygon(dgFloat64 tol);
166 
167  void PackVertexArrays();
168 
169  void BuildFromVertexListIndexList(dgInt32 faceCount, const dgInt32 *const faceIndexCount, const dgInt32 *const faceMaterialIndex,
170  const dgFloat32 *const vertex, dgInt32 vertexStrideInBytes, const dgInt32 *const vertexIndex,
171  const dgFloat32 *const normal, dgInt32 normalStrideInBytes, const dgInt32 *const normalIndex,
172  const dgFloat32 *const uv0, dgInt32 uv0StrideInBytes, const dgInt32 *const uv0Index,
173  const dgFloat32 *const uv1, dgInt32 uv1StrideInBytes, const dgInt32 *const uv1Index);
174 
175  dgInt32 GetVertexCount() const;
176  dgInt32 GetVertexStrideInByte() const;
177  dgFloat64 *GetVertexPool() const;
178 
179  dgInt32 GetPropertiesCount() const;
180  dgInt32 GetPropertiesStrideInByte() const;
181  dgFloat64 *GetAttributePool() const;
182  dgFloat64 *GetNormalPool() const;
183  dgFloat64 *GetUV0Pool() const;
184  dgFloat64 *GetUV1Pool() const;
185 
186  dgEdge *ConectVertex(dgEdge *const e0, dgEdge *const e1);
187 
188  dgInt32 GetTotalFaceCount() const;
189  dgInt32 GetTotalIndexCount() const;
190  void GetFaces(dgInt32 *const faceCount, dgInt32 *const materials, void **const faceNodeList) const;
191 
192  void RepairTJoints(bool triangulate);
193  bool SeparateDuplicateLoops(dgEdge *const edge);
194  bool HasOpenEdges() const;
195  dgFloat64 CalculateVolume() const;
196 
197  void GetVertexStreams(dgInt32 vetexStrideInByte, dgFloat32 *const vertex,
198  dgInt32 normalStrideInByte, dgFloat32 *const normal,
199  dgInt32 uvStrideInByte0, dgFloat32 *const uv0,
200  dgInt32 uvStrideInByte1, dgFloat32 *const uv1) const;
201 
202  void GetIndirectVertexStreams(dgInt32 vetexStrideInByte, dgFloat64 *const vertex, dgInt32 *const vertexIndices, dgInt32 *const vertexCount,
203  dgInt32 normalStrideInByte, dgFloat64 *const normal, dgInt32 *const normalIndices, dgInt32 *const normalCount,
204  dgInt32 uvStrideInByte0, dgFloat64 *const uv0, dgInt32 *const uvIndices0, dgInt32 *const uvCount0,
205  dgInt32 uvStrideInByte1, dgFloat64 *const uv1, dgInt32 *const uvIndices1, dgInt32 *const uvCount1);
206 
207  dgIndexArray *MaterialGeometryBegin() const;
208  void MaterialGeomteryEnd(dgIndexArray *const handle) const;
209  dgInt32 GetFirstMaterial(dgIndexArray *const handle) const;
210  dgInt32 GetNextMaterial(dgIndexArray *const handle, dgInt32 materialHandle) const;
211  dgInt32 GetMaterialID(dgIndexArray *const handle, dgInt32 materialHandle) const;
212  dgInt32 GetMaterialIndexCount(dgIndexArray *const handle, dgInt32 materialHandle) const;
213  void GetMaterialGetIndexStream(dgIndexArray *const handle, dgInt32 materialHandle, dgInt32 *const index) const;
214  void GetMaterialGetIndexStreamShort(dgIndexArray *const handle, dgInt32 materialHandle, dgInt16 *const index) const;
215 
216  dgCollision *CreateCollisionTree(dgInt32 shapeID) const;
217  dgCollision *CreateConvexCollision(dgFloat64 tolerance, dgInt32 shapeID, const dgMatrix &matrix = dgGetIdentityMatrix()) const;
218 
219  dgMeshEffect *CreateConvexApproximation(dgFloat32 maxConcavity, dgInt32 maxCount = 32) const;
220  dgMeshEffect *CreateDelanayTretrahedralization(dgInt32 interionMaterial, dgMatrix &matrix) const;
221  dgMeshEffect *CreateVoronoiPartition(dgInt32 pointsCount, dgInt32 pointStrideInBytes, const dgFloat32 *const pointCloud, dgInt32 interionMaterial, dgMatrix &matrix) const;
222 
223  void PlaneClipMesh(const dgMatrix &planeMatrix, const dgMatrix &planeTextMatrix, dgInt32 planeMaterial, dgMeshEffect **const leftMeshSource, dgMeshEffect **const rightMeshSource) const;
224 
225  dgVertexAtribute &GetAttribute(dgInt32 index) const;
226  void TransformMesh(const dgMatrix &matrix);
227 
228  void *GetFirstVertex() const;
229  void *GetNextVertex(void *const vertex) const;
230  dgInt32 GetVertexIndex(void *const vertex) const;
231 
232  void *GetFirstPoint() const;
233  void *GetNextPoint(void *const point) const;
234  dgInt32 GetPointIndex(const void *const point) const;
235  dgInt32 GetVertexIndexFromPoint(void *const point) const;
236 
237  void *GetFirstEdge() const;
238  void *GetNextEdge(void *const edge) const;
239  void GetEdgeIndex(const void *const edge, dgInt32 &v0, dgInt32 &v1) const;
240  // void GetEdgeAttributeIndex (const void* edge, dgInt32& v0, dgInt32& v1) const;
241 
242  void *GetFirstFace() const;
243  void *GetNextFace(void *const face) const;
244  dgInt32 IsFaceOpen(const void *const face) const;
245  dgInt32 GetFaceMaterial(const void *const face) const;
246  dgInt32 GetFaceIndexCount(const void *const face) const;
247  void GetFaceIndex(const void *const face, int *const indices) const;
248  void GetFaceAttributeIndex(const void *const face, int *const indices) const;
249 
250  bool Sanity() const;
251 
252 protected:
253  void Init(bool preAllocaBuffers);
254  dgBigVector GetOrigin() const;
255  dgInt32 CalculateMaxAttributes() const;
256  dgFloat64 QuantizeCordinade(dgFloat64 val) const;
257  dgInt32 EnumerateAttributeArray(dgVertexAtribute *const attib);
258  void ApplyAttributeArray(dgVertexAtribute *const attib, dgInt32 maxCount);
259  void AddVertex(const dgBigVector &vertex);
260  void AddAtribute(const dgVertexAtribute &attib);
261  void AddPoint(const dgFloat64 *vertexList, dgInt32 material);
262  void FixCylindricalMapping(dgVertexAtribute *const attib) const;
263 
264  void MergeFaces(const dgMeshEffect *const source);
265  void ReverseMergeFaces(dgMeshEffect *const source);
266  dgVertexAtribute InterpolateEdge(dgEdge *const edge, dgFloat64 param) const;
267  dgVertexAtribute InterpolateVertex(const dgBigVector &point, dgEdge *const face) const;
268 
269  dgMeshEffect *GetNextLayer(dgInt32 mark) const;
270 
271  void FilterCoplanarFaces(const dgMeshEffect *const otherCap, dgFloat32 sign);
272  void ClipMesh(const dgMeshEffect *const clipMesh, dgMeshEffect **const back, dgMeshEffect **const front, dgMeshEffect **const coplanar) const;
273  void ClipMesh(const dgMeshEffectSolidTree *const clipper, dgMeshEffect **const back, dgMeshEffect **const front, dgMeshEffect **const coplanar) const;
274 
275  dgInt32 PlaneApplyCap(const dgMeshEffect *planeMesh, const dgBigPlane &normal);
276  void PlaneClipMesh(const dgMeshEffect *planeMesh, dgMeshEffect **leftMeshSource, dgMeshEffect **rightMeshSource) const;
277 
278  dgMeshEffect *MakeDelanayIntersection(dgMeshEffectSolidTree *const tree, dgBigVector *const points, dgInt32 count, dgInt32 materialId, const dgMatrix &textureProjectionMatrix, dgFloat32 normalAngleInRadians) const;
279 
280  bool CheckSingleMesh() const;
281 
282  dgInt32 m_pointCount;
283  dgInt32 m_maxPointCount;
284 
285  dgInt32 m_atribCount;
286  dgInt32 m_maxAtribCount;
287 
288  dgBigVector *m_points;
289  dgVertexAtribute *m_attib;
290 
291  friend class dgConvexHull3d;
292  friend class dgConvexHull4d;
293  friend class dgMeshTreeCSGFace;
294  friend class dgMeshEffectSolidTree;
295 };
296 
297 inline dgInt32 dgMeshEffect::GetVertexCount() const {
298  return m_pointCount;
299 }
300 
301 inline dgInt32 dgMeshEffect::GetPropertiesCount() const {
302  return m_atribCount;
303 }
304 
305 inline dgInt32 dgMeshEffect::GetMaterialID(dgIndexArray *const handle, dgInt32 materialHandle) const {
306  return handle->m_materials[materialHandle];
307 }
308 
309 inline dgInt32 dgMeshEffect::GetMaterialIndexCount(dgIndexArray *const handle, dgInt32 materialHandle) const {
310  return handle->m_materialsIndexCount[materialHandle];
311 }
312 
313 inline dgMeshEffect::dgVertexAtribute &dgMeshEffect::GetAttribute(dgInt32 index) const {
314  return m_attib[index];
315 }
316 
317 inline dgInt32 dgMeshEffect::GetPropertiesStrideInByte() const {
318  return sizeof(dgVertexAtribute);
319 }
320 
321 inline dgFloat64 *dgMeshEffect::GetAttributePool() const {
322  return &m_attib->m_vertex.m_x;
323 }
324 
325 inline dgFloat64 *dgMeshEffect::GetNormalPool() const {
326  return &m_attib->m_normal_x;
327 }
328 
329 inline dgFloat64 *dgMeshEffect::GetUV0Pool() const {
330  return &m_attib->m_u0;
331 }
332 
333 inline dgFloat64 *dgMeshEffect::GetUV1Pool() const {
334  return &m_attib->m_u1;
335 }
336 
337 inline bool dgMeshEffect::CheckIntersection(const dgMeshEffect *const meshA, const dgMeshEffectSolidTree *const solidTreeA, const dgMeshEffect *const meshB, const dgMeshEffectSolidTree *const solidTreeB, dgFloat64 scale) {
338  return (meshA->CheckIntersection(solidTreeB, scale) || meshB->CheckIntersection(solidTreeA, scale));
339 }
340 
341 inline dgInt32 dgMeshEffect::GetVertexStrideInByte() const {
342  return sizeof(dgBigVector);
343 }
344 
345 inline dgFloat64 *dgMeshEffect::GetVertexPool() const {
346  return &m_points[0].m_x;
347 }
348 
349 inline dgMeshEffect *dgMeshEffect::GetFirstLayer() const {
350  return GetNextLayer(IncLRU());
351 }
352 
353 inline dgMeshEffect *dgMeshEffect::GetNextLayer(const dgMeshEffect *const layerSegment) const {
354  if (!layerSegment) {
355  return NULL;
356  }
357  return GetNextLayer(layerSegment->IncLRU() - 1);
358 }
359 
360 inline dgFloat64 dgMeshEffect::QuantizeCordinade(dgFloat64 x) const {
361  int exp;
362  dgFloat64 mantissa = frexp(x, &exp);
363  mantissa = DG_MESH_EFFECT_PRECISION_SCALE_INV * floor(mantissa * DG_MESH_EFFECT_PRECISION_SCALE);
364 
365  dgFloat64 x1 = ldexp(mantissa, exp);
366  return x1;
367 }
368 
369 #endif
Definition: dgConvexHull3d.h:52
Definition: dgRefCounter.h:25
Definition: dgPolyhedra.h:61
Definition: dgMeshEffect.h:78
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: dgPolyhedra.h:76
Definition: dgMeshEffect.h:80
Definition: dgConvexHull4d.h:96
Definition: dgPlane.h:41
Definition: dgMeshEffect.h:105
Definition: dgCollision.h:178
Definition: dgMatrix.h:41
Definition: dgMemory.h:80
Definition: dgWorld.h:118
Definition: dgMeshEffectSolidTree.h:58
Definition: dgMeshEffectSolidTree.h:31
Definition: dgVector.h:104