Open Dynamics Engine
heightfield.h
1 /*************************************************************************
2  * *
3  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4  * All rights reserved. Email: russ@q12.org Web: www.q12.org *
5  * *
6  * This library is free software; you can redistribute it and/or *
7  * modify it under the terms of EITHER: *
8  * (1) The GNU Lesser General Public License as published by the Free *
9  * Software Foundation; either version 2.1 of the License, or (at *
10  * your option) any later version. The text of the GNU Lesser *
11  * General Public License is included with this library in the *
12  * file LICENSE.TXT. *
13  * (2) The BSD-style license that is included with this library in *
14  * the file LICENSE-BSD.TXT. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
19  * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
20  * *
21  *************************************************************************/
22 
23 // dHeightfield Collider
24 // Martijn Buijs 2006 http://home.planet.nl/~buijs512/
25 // Based on Terrain & Cone contrib by:
26 // Benoit CHAPEROT 2003-2004 http://www.jstarlab.com
27 
28 #ifndef _DHEIGHTFIELD_H_
29 #define _DHEIGHTFIELD_H_
30 //------------------------------------------------------------------------------
31 
32 #include <ode/common.h>
33 #include "collision_kernel.h"
34 
35 
36 #define HEIGHTFIELDMAXCONTACTPERCELL 10
37 
38 
39 class HeightFieldVertex;
40 class HeightFieldEdge;
42 
43 //
44 // dxHeightfieldData
45 //
46 // Heightfield Data structure
47 //
49 {
50  dReal m_fWidth; // World space heightfield dimension on X axis
51  dReal m_fDepth; // World space heightfield dimension on Z axis
52  dReal m_fSampleWidth; // Vertex spacing on X axis edge (== m_vWidth / (m_nWidthSamples-1))
53  dReal m_fSampleDepth; // Vertex spacing on Z axis edge (== m_vDepth / (m_nDepthSamples-1))
54  dReal m_fSampleZXAspect; // Relation of Z axis spacing to X axis spacing (== m_fSampleDepth / m_fSampleWidth)
55  dReal m_fInvSampleWidth; // Cache of inverse Vertex count on X axis edge (== m_vWidth / (m_nWidthSamples-1))
56  dReal m_fInvSampleDepth; // Cache of inverse Vertex count on Z axis edge (== m_vDepth / (m_nDepthSamples-1))
57 
58  dReal m_fHalfWidth; // Cache of half of m_fWidth
59  dReal m_fHalfDepth; // Cache of half of m_fDepth
60 
61  dReal m_fMinHeight; // Min sample height value (scaled and offset)
62  dReal m_fMaxHeight; // Max sample height value (scaled and offset)
63  dReal m_fThickness; // Surface thickness (added to bottom AABB)
64  dReal m_fScale; // Sample value multiplier
65  dReal m_fOffset; // Vertical sample offset
66 
67  int m_nWidthSamples; // Vertex count on X axis edge (number of samples)
68  int m_nDepthSamples; // Vertex count on Z axis edge (number of samples)
69  int m_bCopyHeightData; // Do we own the sample data?
70  int m_bWrapMode; // Heightfield wrapping mode (0=finite, 1=infinite)
71  int m_nGetHeightMode; // GetHeight mode ( 0=callback, 1=byte, 2=short, 3=float )
72 
73  const void* m_pHeightData; // Sample data array
74  void* m_pUserData; // Callback user data
75 
76  dContactGeom m_contacts[HEIGHTFIELDMAXCONTACTPERCELL];
77 
78  dHeightfieldGetHeight* m_pGetHeightCallback; // Callback pointer.
79 
82 
83  void SetData( int nWidthSamples, int nDepthSamples,
84  dReal fWidth, dReal fDepth,
85  dReal fScale, dReal fOffset,
86  dReal fThickness, int bWrapMode );
87 
88  void ComputeHeightBounds();
89 
90  bool IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner,
91  const dReal * const pos, const bool isABC) const;
92 
93  dReal GetHeight(int x, int z);
94  dReal GetHeight(dReal x, dReal z);
95 
96 };
97 
98 typedef int HeightFieldVertexCoords[2];
99 
101 {
102 public:
103  HeightFieldVertex(){};
104 
105  dVector3 vertex;
106  HeightFieldVertexCoords coords;
107  bool state;
108 };
109 
111 {
112 public:
113  HeightFieldEdge(){};
114 
115  HeightFieldVertex *vertices[2];
116 };
117 
119 {
120 public:
122 
123  inline void setMinMax()
124  {
125  maxAAAB = vertices[0]->vertex[1] > vertices[1]->vertex[1] ? vertices[0]->vertex[1] : vertices[1]->vertex[1];
126  maxAAAB = vertices[2]->vertex[1] > maxAAAB ? vertices[2]->vertex[1] : maxAAAB;
127  };
128 
129  HeightFieldVertex *vertices[3];
130  dReal planeDef[4];
131  dReal maxAAAB;
132 
133  bool isUp;
134  bool state;
135 };
136 
138 {
139 public:
141  trianglelist(0),
142  trianglelistReservedSize(0),
143  trianglelistCurrentSize(0)
144  {
145  }
146 
148  {
149  delete [] trianglelist;
150  }
151 
152  inline void setMinMax()
153  {
154  const size_t asize = trianglelistCurrentSize;
155  if (asize > 0)
156  {
157  maxAAAB = trianglelist[0]->maxAAAB;
158  for (size_t k = 1; asize > k; k++)
159  {
160  if (trianglelist[k]->maxAAAB > maxAAAB)
161  maxAAAB = trianglelist[k]->maxAAAB;
162  }
163  }
164  };
165 
166  void resetTriangleListSize(const size_t newSize)
167  {
168  if (trianglelistReservedSize < newSize)
169  {
170  delete [] trianglelist;
171  trianglelistReservedSize = newSize;
172  trianglelist = new HeightFieldTriangle *[newSize];
173  }
174  trianglelistCurrentSize = 0;
175  }
176 
177  void addTriangle(HeightFieldTriangle *tri)
178  {
179  dIASSERT(trianglelistCurrentSize < trianglelistReservedSize);
180 
181  trianglelist[trianglelistCurrentSize++] = tri;
182  }
183 
184  HeightFieldTriangle **trianglelist;
185  size_t trianglelistReservedSize;
186  size_t trianglelistCurrentSize;
187 
188  dReal maxAAAB;
189  dReal planeDef[4];
190 };
191 
192 //
193 // dxHeightfield
194 //
195 // Heightfield geom structure
196 //
197 struct dxHeightfield : public dxGeom
198 {
199  dxHeightfieldData* m_p_data;
200 
201  dxHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable );
202  ~dxHeightfield();
203 
204  void computeAABB();
205 
206  int dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ,
207  dxGeom *o2, const int numMaxContacts,
208  int flags, dContactGeom *contact, int skip );
209 
210  enum
211  {
212  TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 4,
213  TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X = 4,
214  TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z = 4,
215  TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 1 // Triangles are easy to reallocate and hard to predict
216  };
217 
218  static inline size_t AlignBufferSize(size_t value, size_t alignment) { dIASSERT((alignment & (alignment - 1)) == 0); return (value + (alignment - 1)) & ~(alignment - 1); }
219 
220  void allocateTriangleBuffer(size_t numTri);
221  void resetTriangleBuffer();
222  void allocatePlaneBuffer(size_t numTri);
223  void resetPlaneBuffer();
224  void allocateHeightBuffer(size_t numX, size_t numZ);
225  void resetHeightBuffer();
226 
227  void sortPlanes(const size_t numPlanes);
228 
229  HeightFieldPlane **tempPlaneBuffer;
230  HeightFieldPlane *tempPlaneInstances;
231  size_t tempPlaneBufferSize;
232 
233  HeightFieldTriangle *tempTriangleBuffer;
234  size_t tempTriangleBufferSize;
235 
236  HeightFieldVertex **tempHeightBuffer;
237  HeightFieldVertex *tempHeightInstances;
238  size_t tempHeightBufferSizeX;
239  size_t tempHeightBufferSizeZ;
240 
241 };
242 
243 
244 //------------------------------------------------------------------------------
245 #endif //_DHEIGHTFIELD_H_
Definition: heightfield.h:48
Describe the contact point between two geoms.
Definition: contact.h:88
Definition: heightfield.h:100
dReal dHeightfieldGetHeight(void *p_user_data, int x, int z)
Callback prototype.
Definition: collision.h:1118
Definition: heightfield.h:137
Definition: heightfield.h:197
Definition: heightfield.h:110
Definition: collision_kernel.h:96
Definition: collision_kernel.h:202
Definition: heightfield.h:118