2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #ifndef BT_HEIGHTFIELD_TERRAIN_SHAPE_H
17 #define BT_HEIGHTFIELD_TERRAIN_SHAPE_H
19 #include "btConcaveShape.h"
20 #include "LinearMath/btAlignedObjectArray.h"
22 ///btHeightfieldTerrainShape simulates a 2D heightfield terrain
24 The caller is responsible for maintaining the heightfield array; this
25 class does not make a copy.
27 The heightfield can be dynamic so long as the min/max height values
28 capture the extremes (heights must always be in that range).
30 The local origin of the heightfield is assumed to be the exact
31 center (as determined by width and length and height, with each
32 axis multiplied by the localScaling).
34 \b NOTE: be careful with coordinates. If you have a heightfield with a local
35 min height of -100m, and a max height of +500m, you may be tempted to place it
36 at the origin (0,0) and expect the heights in world coordinates to be
38 Actually, the heights will be -300 to +300m, because bullet will re-center
39 the heightfield based on its AABB (which is determined by the min/max
40 heights). So keep in mind that once you create a btHeightfieldTerrainShape
41 object, the heights will be adjusted relative to the center of the AABB. This
42 is different to the behavior of many rendering engines, but is useful for
45 Most (but not all) rendering and heightfield libraries assume upAxis = 1
46 (that is, the y-axis is "up"). This class allows any of the 3 coordinates
47 to be "up". Make sure your choice of axis is consistent with your rendering
50 The heightfield heights are determined from the data type used for the
51 heightfieldData array.
53 - unsigned char: height at a point is the uchar value at the
54 grid point, multipled by heightScale. uchar isn't recommended
55 because of its inability to deal with negative values, and
56 low resolution (8-bit).
58 - short: height at a point is the short int value at that grid
59 point, multipled by heightScale.
61 - float or dobule: height at a point is the value at that grid point.
63 Whatever the caller specifies as minHeight and maxHeight will be honored.
64 The class will not inspect the heightfield to discover the actual minimum
65 or maximum heights. These values are used to determine the heightfield's
66 axis-aligned bounding box, multiplied by localScaling.
68 For usage and testing see the TerrainDemo.
70 ATTRIBUTE_ALIGNED16(class)
71 btHeightfieldTerrainShape : public btConcaveShape
77 Range(btScalar min, btScalar max) : min(min), max(max) {}
79 bool overlaps(const Range& other) const
81 return !(min > other.max || max < other.min);
89 btVector3 m_localAabbMin;
90 btVector3 m_localAabbMax;
91 btVector3 m_localOrigin;
94 int m_heightStickWidth;
95 int m_heightStickLength;
100 btScalar m_heightScale;
102 const unsigned char* m_heightfieldDataUnsignedChar;
103 const short* m_heightfieldDataShort;
104 const float* m_heightfieldDataFloat;
105 const double* m_heightfieldDataDouble;
106 const void* m_heightfieldDataUnknown;
109 PHY_ScalarType m_heightDataType;
110 bool m_flipQuadEdges;
111 bool m_useDiamondSubdivision;
112 bool m_useZigzagSubdivision;
113 bool m_flipTriangleWinding;
116 btVector3 m_localScaling;
119 btAlignedObjectArray<Range> m_vboundsGrid;
120 int m_vboundsGridWidth;
121 int m_vboundsGridLength;
122 int m_vboundsChunkSize;
125 btScalar m_userValue3;
127 struct btTriangleInfoMap* m_triangleInfoMap;
129 virtual btScalar getRawHeightFieldValue(int x, int y) const;
130 void quantizeWithClamp(int* out, const btVector3& point, int isMax) const;
132 /// protected initialization
134 Handles the work of constructors so that public constructors can be
135 backwards-compatible without a lot of copy/paste.
137 void initialize(int heightStickWidth, int heightStickLength,
138 const void* heightfieldData, btScalar heightScale,
139 btScalar minHeight, btScalar maxHeight, int upAxis,
140 PHY_ScalarType heightDataType, bool flipQuadEdges);
143 BT_DECLARE_ALIGNED_ALLOCATOR();
145 /// preferred constructors
146 btHeightfieldTerrainShape(
147 int heightStickWidth, int heightStickLength,
148 const float* heightfieldData, btScalar minHeight, btScalar maxHeight,
149 int upAxis, bool flipQuadEdges);
150 btHeightfieldTerrainShape(
151 int heightStickWidth, int heightStickLength,
152 const double* heightfieldData, btScalar minHeight, btScalar maxHeight,
153 int upAxis, bool flipQuadEdges);
154 btHeightfieldTerrainShape(
155 int heightStickWidth, int heightStickLength,
156 const short* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight,
157 int upAxis, bool flipQuadEdges);
158 btHeightfieldTerrainShape(
159 int heightStickWidth, int heightStickLength,
160 const unsigned char* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight,
161 int upAxis, bool flipQuadEdges);
163 /// legacy constructor
165 This constructor supports a range of heightfield
166 data types, and allows for a non-zero minimum height value.
167 heightScale is needed for any integer-based heightfield data types.
169 This legacy constructor considers `PHY_FLOAT` to mean `btScalar`.
170 With `BT_USE_DOUBLE_PRECISION`, it will expect `heightfieldData`
171 to be double-precision.
173 btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,
174 const void* heightfieldData, btScalar heightScale,
175 btScalar minHeight, btScalar maxHeight,
176 int upAxis, PHY_ScalarType heightDataType,
179 /// legacy constructor
181 The legacy constructor assumes the heightfield has a minimum height
182 of zero. Only unsigned char or btScalar data are supported. For legacy
183 compatibility reasons, heightScale is calculated as maxHeight / 65535
184 (and is only used when useFloatData = false).
186 btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar maxHeight, int upAxis, bool useFloatData, bool flipQuadEdges);
188 virtual ~btHeightfieldTerrainShape();
190 void setUseDiamondSubdivision(bool useDiamondSubdivision = true) { m_useDiamondSubdivision = useDiamondSubdivision; }
192 ///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
193 void setUseZigzagSubdivision(bool useZigzagSubdivision = true) { m_useZigzagSubdivision = useZigzagSubdivision; }
195 void setFlipTriangleWinding(bool flipTriangleWinding)
197 m_flipTriangleWinding = flipTriangleWinding;
199 virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
201 virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
203 virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const;
205 virtual void setLocalScaling(const btVector3& scaling);
207 virtual const btVector3& getLocalScaling() const;
209 void getVertex(int x, int y, btVector3& vertex) const;
211 void performRaycast(btTriangleCallback * callback, const btVector3& raySource, const btVector3& rayTarget) const;
213 void buildAccelerator(int chunkSize = 16);
214 void clearAccelerator();
216 int getUpAxis() const
221 virtual const char* getName() const { return "HEIGHTFIELD"; }
224 void setUserValue3(btScalar value)
226 m_userValue3 = value;
228 btScalar getUserValue3() const
232 const struct btTriangleInfoMap* getTriangleInfoMap() const
234 return m_triangleInfoMap;
236 struct btTriangleInfoMap* getTriangleInfoMap()
238 return m_triangleInfoMap;
240 void setTriangleInfoMap(btTriangleInfoMap* map)
242 m_triangleInfoMap = map;
244 const unsigned char* getHeightfieldRawData() const
246 return m_heightfieldDataUnsignedChar;
250 #endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H