Bullet Collision Detection & Physics Library
btHeightfieldTerrainShape.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
17
19
20
21
23(
27)
28{
32}
33
34
35
37{
38 // legacy constructor: support only float or unsigned char,
39 // and min height is zero
41 btScalar minHeight = 0.0f;
42
43 // previously, height = uchar * maxHeight / 65535.
44 // So to preserve legacy behavior, heightScale = maxHeight / 65535
46
50}
51
52
53
55(
59)
60{
61 // validation
62 btAssert(heightStickWidth > 1);// && "bad width");
63 btAssert(heightStickLength > 1);// && "bad length");
64 btAssert(heightfieldData);// && "null heightfield data");
65 // btAssert(heightScale) -- do we care? Trust caller here
66 btAssert(minHeight <= maxHeight);// && "bad min/max height");
67 btAssert(upAxis >= 0 && upAxis < 3);// && "bad upAxis--should be in range [0,2]");
68 btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT);// && "Bad height data type enum");
69
70 // initialize member variables
86
87 // determine min/max axis-aligned bounding box (aabb) values
88 switch (m_upAxis)
89 {
90 case 0:
91 {
94 break;
95 }
96 case 1:
97 {
100 break;
101 };
102 case 2:
103 {
106 break;
107 }
108 default:
109 {
110 //need to get valid m_upAxis
111 btAssert(0);// && "Bad m_upAxis");
112 }
113 }
114
115 // remember origin (defined as exact middle of aabb)
117}
118
119
120
122{
123}
124
125
126
128{
130
131 btVector3 localOrigin(0, 0, 0);
134
135 btMatrix3x3 abs_b = t.getBasis().absolute();
136 btVector3 center = t.getOrigin();
139
140 aabbMin = center - extent;
141 aabbMax = center + extent;
142}
143
144
150{
151 btScalar val = 0.f;
152 switch (m_heightDataType)
153 {
154 case PHY_FLOAT:
155 {
157 break;
158 }
159
160 case PHY_UCHAR:
161 {
164 break;
165 }
166
167 case PHY_SHORT:
168 {
171 break;
172 }
173
174 default:
175 {
176 btAssert(!"Bad m_heightDataType");
177 }
178 }
179
180 return val;
181}
182
183
184
185
188{
189 btAssert(x>=0);
190 btAssert(y>=0);
193
195
196 switch (m_upAxis)
197 {
198 case 0:
199 {
200 vertex.setValue(
202 (-m_width/btScalar(2.0)) + x,
203 (-m_length/btScalar(2.0) ) + y
204 );
205 break;
206 }
207 case 1:
208 {
209 vertex.setValue(
210 (-m_width/btScalar(2.0)) + x,
212 (-m_length/btScalar(2.0)) + y
213 );
214 break;
215 };
216 case 2:
217 {
218 vertex.setValue(
219 (-m_width/btScalar(2.0)) + x,
220 (-m_length/btScalar(2.0)) + y,
222 );
223 break;
224 }
225 default:
226 {
227 //need to get valid m_upAxis
228 btAssert(0);
229 }
230 }
231
233}
234
235
236
237static inline int
239(
240btScalar x
241)
242{
243 if (x < 0.0) {
244 return (int) (x - 0.5);
245 }
246 return (int) (x + 0.5);
247}
248
249
250
252
260void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
261{
262 btVector3 clampedPoint(point);
265
266 out[0] = getQuantized(clampedPoint.getX());
267 out[1] = getQuantized(clampedPoint.getY());
268 out[2] = getQuantized(clampedPoint.getZ());
269
270}
271
272
273
275
282{
283 // scale down the input aabb's so they are in local (non-scaled) coordinates
286
287 // account for local origin
290
291 //quantize the aabbMin and aabbMax, and adjust the start/end ranges
292 int quantizedAabbMin[3];
293 int quantizedAabbMax[3];
296
297 // expand the min/max quantized values
298 // this is to catch the case where the input aabb falls between grid points!
299 for (int i = 0; i < 3; ++i) {
300 quantizedAabbMin[i]--;
301 quantizedAabbMax[i]++;
302 }
303
304 int startX=0;
306 int startJ=0;
308
309 switch (m_upAxis)
310 {
311 case 0:
312 {
315 if (quantizedAabbMax[1]<endX)
319 if (quantizedAabbMax[2]<endJ)
321 break;
322 }
323 case 1:
324 {
327 if (quantizedAabbMax[0]<endX)
331 if (quantizedAabbMax[2]<endJ)
333 break;
334 };
335 case 2:
336 {
339 if (quantizedAabbMax[0]<endX)
343 if (quantizedAabbMax[1]<endJ)
345 break;
346 }
347 default:
348 {
349 //need to get valid m_upAxis
350 btAssert(0);
351 }
352 }
353
354
355
356
357 for(int j=startJ; j<endJ; j++)
358 {
359 for(int x=startX; x<endX; x++)
360 {
361 btVector3 vertices[3];
362 if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1))|| (m_useZigzagSubdivision && !(j & 1)))
363 {
364 //first triangle
365 getVertex(x,j,vertices[0]);
366 getVertex(x, j + 1, vertices[1]);
367 getVertex(x + 1, j + 1, vertices[2]);
368 callback->processTriangle(vertices,x,j);
369 //second triangle
370 // getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
371 getVertex(x+1,j+1,vertices[1]);
372 getVertex(x + 1, j, vertices[2]);
373 callback->processTriangle(vertices, x, j);
374
375 } else
376 {
377 //first triangle
378 getVertex(x,j,vertices[0]);
379 getVertex(x,j+1,vertices[1]);
380 getVertex(x+1,j,vertices[2]);
381 callback->processTriangle(vertices,x,j);
382 //second triangle
383 getVertex(x+1,j,vertices[0]);
384 //getVertex(x,j+1,vertices[1]);
385 getVertex(x+1,j+1,vertices[2]);
386 callback->processTriangle(vertices,x,j);
387 }
388 }
389 }
390
391
392
393}
394
396{
397 //moving concave objects not supported
398
399 inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
400}
401
403{
404 m_localScaling = scaling;
405}
407{
408 return m_localScaling;
409}
@ TERRAIN_SHAPE_PROXYTYPE
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
@ PHY_FLOAT
@ PHY_UCHAR
@ PHY_SHORT
static int getQuantized(btScalar x)
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:29
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:292
#define btAssert(x)
Definition btScalar.h:131
virtual btScalar getMargin() const
virtual btScalar getRawHeightFieldValue(int x, int y) const
This returns the "raw" (user's initial) height, not the actual height.
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
void quantizeWithClamp(int *out, const btVector3 &point, int isMax) const
given input vector, return quantized version
void getVertex(int x, int y, btVector3 &vertex) const
this returns the vertex in bullet-local coordinates
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void *heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, PHY_ScalarType heightDataType, bool flipQuadEdges)
preferred constructor
const unsigned char * m_heightfieldDataUnsignedChar
virtual void setLocalScaling(const btVector3 &scaling)
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
process all triangles within the provided axis-aligned bounding box
virtual const btVector3 & getLocalScaling() const
void initialize(int heightStickWidth, int heightStickLength, const void *heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, PHY_ScalarType heightDataType, bool flipQuadEdges)
protected initialization
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:48
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:34
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)=0
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:84
const btScalar & getZ() const
Return the z value.
Definition btVector3.h:577
btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
Definition btVector3.h:731
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:652
const btScalar & getY() const
Return the y value.
Definition btVector3.h:575
const btScalar & getX() const
Return the x value.
Definition btVector3.h:573