21 int heightStickWidth,
int heightStickLength,
23 int upAxis,
bool flipQuadEdges)
24 : m_userValue3(0), m_triangleInfoMap(0)
26 initialize(heightStickWidth, heightStickLength, heightfieldData,
27 1, minHeight, maxHeight, upAxis,
PHY_FLOAT,
32 int heightStickWidth,
int heightStickLength,
const double* heightfieldData,
34 : m_userValue3(0), m_triangleInfoMap(0)
36 initialize(heightStickWidth, heightStickLength, heightfieldData,
42 int heightStickWidth,
int heightStickLength,
const short* heightfieldData,
btScalar heightScale,
44 : m_userValue3(0), m_triangleInfoMap(0)
46 initialize(heightStickWidth, heightStickLength, heightfieldData,
47 heightScale, minHeight, maxHeight, upAxis,
PHY_SHORT,
52 int heightStickWidth,
int heightStickLength,
const unsigned char* heightfieldData,
btScalar heightScale,
54 : m_userValue3(0), m_triangleInfoMap(0)
56 initialize(heightStickWidth, heightStickLength, heightfieldData,
57 heightScale, minHeight, maxHeight, upAxis,
PHY_UCHAR,
62 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
69#ifdef BT_USE_DOUBLE_PRECISION
72 initialize(heightStickWidth, heightStickLength, heightfieldData,
73 heightScale, minHeight, maxHeight, upAxis, hdt,
84#ifdef BT_USE_DOUBLE_PRECISION
91 btScalar heightScale = maxHeight / 65535;
93 initialize(heightStickWidth, heightStickLength, heightfieldData,
94 heightScale, minHeight, maxHeight, upAxis, hdt,
99 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
109 btAssert(upAxis >= 0 && upAxis < 3);
181 btVector3 extent = halfExtents.
dot3(abs_b[0], abs_b[1], abs_b[2]);
184 aabbMin = center - extent;
185 aabbMax = center + extent;
284 return (
int)(x - 0.5);
286 return (
int)(x + 0.5);
351 int quantizedAabbMin[3];
352 int quantizedAabbMax[3];
358 for (
int i = 0; i < 3; ++i)
360 quantizedAabbMin[i]--;
361 quantizedAabbMax[i]++;
373 if (quantizedAabbMin[1] > startX)
374 startX = quantizedAabbMin[1];
375 if (quantizedAabbMax[1] < endX)
376 endX = quantizedAabbMax[1];
377 if (quantizedAabbMin[2] > startJ)
378 startJ = quantizedAabbMin[2];
379 if (quantizedAabbMax[2] < endJ)
380 endJ = quantizedAabbMax[2];
385 if (quantizedAabbMin[0] > startX)
386 startX = quantizedAabbMin[0];
387 if (quantizedAabbMax[0] < endX)
388 endX = quantizedAabbMax[0];
389 if (quantizedAabbMin[2] > startJ)
390 startJ = quantizedAabbMin[2];
391 if (quantizedAabbMax[2] < endJ)
392 endJ = quantizedAabbMax[2];
397 if (quantizedAabbMin[0] > startX)
398 startX = quantizedAabbMin[0];
399 if (quantizedAabbMax[0] < endX)
400 endX = quantizedAabbMax[0];
401 if (quantizedAabbMin[1] > startJ)
402 startJ = quantizedAabbMin[1];
403 if (quantizedAabbMax[1] < endJ)
404 endJ = quantizedAabbMax[1];
417 for (
int j = startJ; j < endJ; j++)
419 for (
int x = startX; x < endX; x++)
422 int indices[3] = { 0, 1, 2 };
432 getVertex(x, j + 1, vertices[indices[1]]);
433 getVertex(x + 1, j + 1, vertices[indices[2]]);
444 vertices[indices[1]] = vertices[indices[2]];
446 getVertex(x + 1, j, vertices[indices[2]]);
456 getVertex(x, j + 1, vertices[indices[1]]);
457 getVertex(x + 1, j, vertices[indices[2]]);
468 vertices[indices[0]] = vertices[indices[2]];
470 getVertex(x + 1, j + 1, vertices[indices[2]]);
499 struct GridRaycastState
516template <
typename Action_T>
520 rs.maxDistance3d = beginPos.
distance(endPos);
521 if (rs.maxDistance3d < 0.0001)
528 btScalar rayDirectionFlatX = endPos[indices[0]] - beginPos[indices[0]];
529 btScalar rayDirectionFlatZ = endPos[indices[2]] - beginPos[indices[2]];
530 rs.maxDistanceFlat =
btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
532 if (rs.maxDistanceFlat < 0.0001)
535 rayDirectionFlatX = 0;
536 rayDirectionFlatZ = 0;
540 rayDirectionFlatX /= rs.maxDistanceFlat;
541 rayDirectionFlatZ /= rs.maxDistanceFlat;
544 const int xiStep = rayDirectionFlatX > 0 ? 1 : rayDirectionFlatX < 0 ? -1 : 0;
545 const int ziStep = rayDirectionFlatZ > 0 ? 1 : rayDirectionFlatZ < 0 ? -1 : 0;
547 const float infinite = 9999999;
548 const btScalar paramDeltaX = xiStep != 0 ? 1.f /
btFabs(rayDirectionFlatX) : infinite;
549 const btScalar paramDeltaZ = ziStep != 0 ? 1.f /
btFabs(rayDirectionFlatZ) : infinite;
561 paramCrossX = (ceil(beginPos[indices[0]]) - beginPos[indices[0]]) * paramDeltaX;
565 paramCrossX = (beginPos[indices[0]] - floor(beginPos[indices[0]])) * paramDeltaX;
570 paramCrossX = infinite;
578 paramCrossZ = (ceil(beginPos[indices[2]]) - beginPos[indices[2]]) * paramDeltaZ;
582 paramCrossZ = (beginPos[indices[2]] - floor(beginPos[indices[2]])) * paramDeltaZ;
587 paramCrossZ = infinite;
590 rs.x =
static_cast<int>(floor(beginPos[indices[0]]));
591 rs.z =
static_cast<int>(floor(beginPos[indices[2]]));
594 if (paramCrossX == 0.0)
596 paramCrossX += paramDeltaX;
605 if (paramCrossZ == 0.0)
607 paramCrossZ += paramDeltaZ;
620 rs.prevParam = rs.param;
622 if (paramCrossX < paramCrossZ)
628 rs.param = paramCrossX;
629 paramCrossX += paramDeltaX;
635 rs.param = paramCrossZ;
636 paramCrossZ += paramDeltaZ;
639 if (rs.param > rs.maxDistanceFlat)
641 rs.param = rs.maxDistanceFlat;
705 exec(bs.prev_x, bs.prev_z);
743 if (rs.maxDistanceFlat > 0.0001)
746 btScalar enterParam3d = rs.prevParam * flatTo3d;
747 btScalar exitParam3d = rs.param * flatTo3d;
788 processTriangles.
shape =
this;
791 processTriangles.
callback = callback;
796 int indices[3] = { 0, 1, 2 };
802 int iBeginX =
static_cast<int>(floor(beginPos[indices[0]]));
803 int iBeginZ =
static_cast<int>(floor(beginPos[indices[2]]));
804 int iEndX =
static_cast<int>(floor(endPos[indices[0]]));
805 int iEndZ =
static_cast<int>(floor(endPos[indices[2]]));
807 if (iBeginX == iEndX && iBeginZ == iEndZ)
812 processTriangles.
exec(iBeginX, iEndZ);
821 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
826 btScalar flatDistance2 = rayDiff[indices[0]] * rayDiff[indices[0]] + rayDiff[indices[2]] * rayDiff[indices[2]];
830 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
838 processVBounds.
rayEnd = endPos;
878 if (nChunksX == 0 || nChunksZ == 0)
887 for (
int cz = 0; cz < nChunksZ; ++cz)
889 int z0 = cz * chunkSize;
891 for (
int cx = 0; cx < nChunksX; ++cx)
893 int x0 = cx * chunkSize;
916 for (
int z = z0; z < z0 + chunkSize + 1; ++z)
923 for (
int x = x0; x < x0 + chunkSize + 1; ++x)
936 else if (height > r.
max)
@ TERRAIN_SHAPE_PROXYTYPE
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
static btHeightfieldTerrainShape::Range minmaxRange(btScalar a, btScalar b, btScalar c)
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...
const T & btMax(const T &a, const T &b)
const T & btMin(const T &a, const T &b)
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
const double * m_heightfieldDataDouble
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
const unsigned char * m_heightfieldDataUnsignedChar
virtual void setLocalScaling(const btVector3 &scaling)
const float * m_heightfieldDataFloat
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
btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const float *heightfieldData, btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges)
preferred constructors
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.
const btScalar & getZ() const
Return the z value.
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
btScalar distance(const btVector3 &v) const
Return the distance between the ends of this and another vector This is symantically treating the vec...
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.
const btScalar & getX() const
Return the x value.
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
bool overlaps(const Range &other) const