21 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
27 initialize(heightStickWidth, heightStickLength, heightfieldData,
28 heightScale, minHeight, maxHeight, upAxis, hdt,
43 btScalar heightScale = maxHeight / 65535;
45 initialize(heightStickWidth, heightStickLength, heightfieldData,
46 heightScale, minHeight, maxHeight, upAxis, hdt,
51 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
133 btVector3 extent = halfExtents.
dot3(abs_b[0], abs_b[1], abs_b[2]);
136 aabbMin = center - extent;
137 aabbMax = center + extent;
230 return (
int)(x - 0.5);
232 return (
int)(x + 0.5);
273 int quantizedAabbMin[3];
274 int quantizedAabbMax[3];
280 for (
int i = 0; i < 3; ++i)
282 quantizedAabbMin[i]--;
283 quantizedAabbMax[i]++;
295 if (quantizedAabbMin[1] > startX)
296 startX = quantizedAabbMin[1];
297 if (quantizedAabbMax[1] < endX)
298 endX = quantizedAabbMax[1];
299 if (quantizedAabbMin[2] > startJ)
300 startJ = quantizedAabbMin[2];
301 if (quantizedAabbMax[2] < endJ)
302 endJ = quantizedAabbMax[2];
307 if (quantizedAabbMin[0] > startX)
308 startX = quantizedAabbMin[0];
309 if (quantizedAabbMax[0] < endX)
310 endX = quantizedAabbMax[0];
311 if (quantizedAabbMin[2] > startJ)
312 startJ = quantizedAabbMin[2];
313 if (quantizedAabbMax[2] < endJ)
314 endJ = quantizedAabbMax[2];
319 if (quantizedAabbMin[0] > startX)
320 startX = quantizedAabbMin[0];
321 if (quantizedAabbMax[0] < endX)
322 endX = quantizedAabbMax[0];
323 if (quantizedAabbMin[1] > startJ)
324 startJ = quantizedAabbMin[1];
325 if (quantizedAabbMax[1] < endJ)
326 endJ = quantizedAabbMax[1];
338 for (
int j = startJ; j < endJ; j++)
340 for (
int x = startX; x < endX; x++)
343 int indices[3] = { 0, 1, 2 };
354 getVertex(x, j + 1, vertices[indices[1]]);
355 getVertex(x + 1, j + 1, vertices[indices[2]]);
359 getVertex(x + 1, j + 1, vertices[indices[1]]);
360 getVertex(x + 1, j, vertices[indices[2]]);
367 getVertex(x, j + 1, vertices[indices[1]]);
368 getVertex(x + 1, j, vertices[indices[2]]);
371 getVertex(x + 1, j, vertices[indices[0]]);
373 getVertex(x + 1, j + 1, vertices[indices[2]]);
398 struct GridRaycastState
415 template <
typename Action_T>
419 rs.maxDistance3d = beginPos.
distance(endPos);
420 if (rs.maxDistance3d < 0.0001)
427 btScalar rayDirectionFlatX = endPos[indices[0]] - beginPos[indices[0]];
428 btScalar rayDirectionFlatZ = endPos[indices[2]] - beginPos[indices[2]];
429 rs.maxDistanceFlat =
btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
431 if (rs.maxDistanceFlat < 0.0001)
434 rayDirectionFlatX = 0;
435 rayDirectionFlatZ = 0;
439 rayDirectionFlatX /= rs.maxDistanceFlat;
440 rayDirectionFlatZ /= rs.maxDistanceFlat;
443 const int xiStep = rayDirectionFlatX > 0 ? 1 : rayDirectionFlatX < 0 ? -1 : 0;
444 const int ziStep = rayDirectionFlatZ > 0 ? 1 : rayDirectionFlatZ < 0 ? -1 : 0;
446 const float infinite = 9999999;
447 const btScalar paramDeltaX = xiStep != 0 ? 1.f /
btFabs(rayDirectionFlatX) : infinite;
448 const btScalar paramDeltaZ = ziStep != 0 ? 1.f /
btFabs(rayDirectionFlatZ) : infinite;
460 paramCrossX = (ceil(beginPos[indices[0]]) - beginPos[indices[0]]) * paramDeltaX;
464 paramCrossX = (beginPos[indices[0]] - floor(beginPos[indices[0]])) * paramDeltaX;
469 paramCrossX = infinite;
477 paramCrossZ = (ceil(beginPos[indices[2]]) - beginPos[indices[2]]) * paramDeltaZ;
481 paramCrossZ = (beginPos[indices[2]] - floor(beginPos[indices[2]])) * paramDeltaZ;
486 paramCrossZ = infinite;
489 rs.x =
static_cast<int>(floor(beginPos[indices[0]]));
490 rs.z =
static_cast<int>(floor(beginPos[indices[2]]));
493 if (paramCrossX == 0.0)
495 paramCrossX += paramDeltaX;
504 if (paramCrossZ == 0.0)
506 paramCrossZ += paramDeltaZ;
519 rs.prevParam = rs.param;
521 if (paramCrossX < paramCrossZ)
527 rs.param = paramCrossX;
528 paramCrossX += paramDeltaX;
534 rs.param = paramCrossZ;
535 paramCrossZ += paramDeltaZ;
538 if (rs.param > rs.maxDistanceFlat)
540 rs.param = rs.maxDistanceFlat;
604 exec(bs.prev_x, bs.prev_z);
642 if (rs.maxDistanceFlat > 0.0001)
645 btScalar enterParam3d = rs.prevParam * flatTo3d;
646 btScalar exitParam3d = rs.param * flatTo3d;
687 processTriangles.
shape =
this;
690 processTriangles.
callback = callback;
695 int indices[3] = { 0, 1, 2 };
701 int iBeginX =
static_cast<int>(floor(beginPos[indices[0]]));
702 int iBeginZ =
static_cast<int>(floor(beginPos[indices[2]]));
703 int iEndX =
static_cast<int>(floor(endPos[indices[0]]));
704 int iEndZ =
static_cast<int>(floor(endPos[indices[2]]));
706 if (iBeginX == iEndX && iBeginZ == iEndZ)
711 processTriangles.
exec(iBeginX, iEndZ);
720 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
725 btScalar flatDistance2 = rayDiff[indices[0]] * rayDiff[indices[0]] + rayDiff[indices[2]] * rayDiff[indices[2]];
729 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
736 processVBounds.
rayEnd = endPos;
776 if (nChunksX == 0 || nChunksZ == 0)
785 for (
int cz = 0; cz < nChunksZ; ++cz)
787 int z0 = cz * chunkSize;
789 for (
int cx = 0; cx < nChunksX; ++cx)
791 int x0 = cx * chunkSize;
814 for (
int z = z0; z < z0 + chunkSize + 1; ++z)
821 for (
int x = x0; x < x0 + chunkSize + 1; ++x)
834 else if (height > r.
max)
@ TERRAIN_SHAPE_PROXYTYPE
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
static int getQuantized(btScalar x)
void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector3 &endPos, int indices[3])
Iterates through a virtual 2D grid of unit-sized square cells, and executes an action on each cell in...
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btSqrt(btScalar y)
btScalar btFabs(btScalar x)
virtual btScalar getMargin() const
btHeightfieldTerrainShape simulates a 2D heightfield terrain
bool m_flipTriangleWinding
PHY_ScalarType m_heightDataType
bool m_useZigzagSubdivision
bool m_useDiamondSubdivision
virtual btScalar getRawHeightFieldValue(int x, int y) const
This returns the "raw" (user's initial) height, not the actual height.
const short * m_heightfieldDataShort
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
virtual ~btHeightfieldTerrainShape()
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
const void * m_heightfieldDataUnknown
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)
void performRaycast(btTriangleCallback *callback, const btVector3 &raySource, const btVector3 &rayTarget) const
Performs a raycast using a hierarchical Bresenham algorithm.
int m_heightStickWidth
terrain data
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
process all triangles within the provided axis-aligned bounding box
const btScalar * m_heightfieldDataFloat
btAlignedObjectArray< Range > m_vboundsGrid
virtual const btVector3 & getLocalScaling() const
void buildAccelerator(int chunkSize=16)
Builds a grid data structure storing the min and max heights of the terrain in chunks.
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...
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
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.
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
const btScalar & getX() const
Return the x value.
btScalar distance(const btVector3 &v) const
Return the distance between the ends of this and another vector This is symantically treating the vec...
const btScalar & getZ() const
Return the z value.
btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
btVector3 normalized() const
Return a normalized version of this vector.
const btScalar & getY() const
Return the y value.
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
void operator()(const GridRaycastState &bs) const
void exec(int x, int z) const
btTriangleCallback * callback
bool useDiamondSubdivision
const btHeightfieldTerrainShape * shape
void operator()(const GridRaycastState &rs) const
ProcessVBoundsAction(const btAlignedObjectArray< btHeightfieldTerrainShape::Range > &bnd, int *indices)
ProcessTrianglesAction processTriangles
const btAlignedObjectArray< btHeightfieldTerrainShape::Range > & vbounds