20btHeightfieldTerrainShape::btHeightfieldTerrainShape(
21 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
28 initialize(heightStickWidth, heightStickLength, heightfieldData,
29 heightScale, minHeight, maxHeight, upAxis, hdt,
33btHeightfieldTerrainShape::btHeightfieldTerrainShape(
int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
btScalar maxHeight,
int upAxis,
bool useFloatData,
bool flipQuadEdges)
45 btScalar heightScale = maxHeight / 65535;
47 initialize(heightStickWidth, heightStickLength, heightfieldData,
48 heightScale, minHeight, maxHeight, upAxis, hdt,
52void btHeightfieldTerrainShape::initialize(
53 int heightStickWidth,
int heightStickLength,
const void* heightfieldData,
120btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
125void btHeightfieldTerrainShape::getAabb(
const btTransform& t, btVector3& aabbMin, btVector3& aabbMax)
const
129 btVector3 localOrigin(0, 0, 0);
134 btVector3 center = t.getOrigin();
135 btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
138 aabbMin = center - extent;
139 aabbMax = center + extent;
146btHeightfieldTerrainShape::getRawHeightFieldValue(
int x,
int y)
const
181void btHeightfieldTerrainShape::getVertex(
int x,
int y, btVector3& vertex)
const
232 return (
int)(x - 0.5);
234 return (
int)(x + 0.5);
246void btHeightfieldTerrainShape::quantizeWithClamp(
int* out,
const btVector3& point,
int )
const
248 btVector3 clampedPoint(point);
264void btHeightfieldTerrainShape::processAllTriangles(
btTriangleCallback*
callback,
const btVector3& aabbMin,
const btVector3& aabbMax)
const
275 int quantizedAabbMin[3];
276 int quantizedAabbMax[3];
282 for (
int i = 0; i < 3; ++i)
284 quantizedAabbMin[i]--;
285 quantizedAabbMax[i]++;
297 if (quantizedAabbMin[1] > startX)
298 startX = quantizedAabbMin[1];
299 if (quantizedAabbMax[1] < endX)
300 endX = quantizedAabbMax[1];
301 if (quantizedAabbMin[2] > startJ)
302 startJ = quantizedAabbMin[2];
303 if (quantizedAabbMax[2] < endJ)
304 endJ = quantizedAabbMax[2];
309 if (quantizedAabbMin[0] > startX)
310 startX = quantizedAabbMin[0];
311 if (quantizedAabbMax[0] < endX)
312 endX = quantizedAabbMax[0];
313 if (quantizedAabbMin[2] > startJ)
314 startJ = quantizedAabbMin[2];
315 if (quantizedAabbMax[2] < endJ)
316 endJ = quantizedAabbMax[2];
321 if (quantizedAabbMin[0] > startX)
322 startX = quantizedAabbMin[0];
323 if (quantizedAabbMax[0] < endX)
324 endX = quantizedAabbMax[0];
325 if (quantizedAabbMin[1] > startJ)
326 startJ = quantizedAabbMin[1];
327 if (quantizedAabbMax[1] < endJ)
328 endJ = quantizedAabbMax[1];
340 for (
int j = startJ; j < endJ; j++)
342 for (
int x = startX; x < endX; x++)
344 btVector3 vertices[3];
345 int indices[3] = { 0, 1, 2 };
356 getVertex(x, j + 1, vertices[indices[1]]);
357 getVertex(x + 1, j + 1, vertices[indices[2]]);
358 callback->processTriangle(vertices, 2 * x, j);
361 getVertex(x + 1, j + 1, vertices[indices[1]]);
362 getVertex(x + 1, j, vertices[indices[2]]);
363 callback->processTriangle(vertices, 2 * x+1, j);
369 getVertex(x, j + 1, vertices[indices[1]]);
370 getVertex(x + 1, j, vertices[indices[2]]);
371 callback->processTriangle(vertices, 2 * x, j);
373 getVertex(x + 1, j, vertices[indices[0]]);
375 getVertex(x + 1, j + 1, vertices[indices[2]]);
376 callback->processTriangle(vertices, 2 * x+1, j);
382void btHeightfieldTerrainShape::calculateLocalInertia(
btScalar, btVector3& inertia)
const
389void btHeightfieldTerrainShape::setLocalScaling(
const btVector3& scaling)
393const btVector3& btHeightfieldTerrainShape::getLocalScaling()
const
400 struct GridRaycastState
417template <
typename Action_T>
418void gridRaycast(Action_T& quadAction,
const btVector3& beginPos,
const btVector3& endPos,
int indices[3])
421 rs.maxDistance3d = beginPos.distance(endPos);
422 if (rs.maxDistance3d < 0.0001)
429 btScalar rayDirectionFlatX = endPos[indices[0]] - beginPos[indices[0]];
430 btScalar rayDirectionFlatZ = endPos[indices[2]] - beginPos[indices[2]];
431 rs.maxDistanceFlat =
btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
433 if (rs.maxDistanceFlat < 0.0001)
436 rayDirectionFlatX = 0;
437 rayDirectionFlatZ = 0;
441 rayDirectionFlatX /= rs.maxDistanceFlat;
442 rayDirectionFlatZ /= rs.maxDistanceFlat;
445 const int xiStep = rayDirectionFlatX > 0 ? 1 : rayDirectionFlatX < 0 ? -1 : 0;
446 const int ziStep = rayDirectionFlatZ > 0 ? 1 : rayDirectionFlatZ < 0 ? -1 : 0;
448 const float infinite = 9999999;
449 const btScalar paramDeltaX = xiStep != 0 ? 1.f /
btFabs(rayDirectionFlatX) : infinite;
450 const btScalar paramDeltaZ = ziStep != 0 ? 1.f /
btFabs(rayDirectionFlatZ) : infinite;
462 paramCrossX = (
ceil(beginPos[indices[0]]) - beginPos[indices[0]]) * paramDeltaX;
466 paramCrossX = (beginPos[indices[0]] -
floor(beginPos[indices[0]])) * paramDeltaX;
471 paramCrossX = infinite;
479 paramCrossZ = (
ceil(beginPos[indices[2]]) - beginPos[indices[2]]) * paramDeltaZ;
483 paramCrossZ = (beginPos[indices[2]] -
floor(beginPos[indices[2]])) * paramDeltaZ;
488 paramCrossZ = infinite;
491 rs.x =
static_cast<int>(
floor(beginPos[indices[0]]));
492 rs.z =
static_cast<int>(
floor(beginPos[indices[2]]));
495 if (paramCrossX == 0.0)
497 paramCrossX += paramDeltaX;
506 if (paramCrossZ == 0.0)
508 paramCrossZ += paramDeltaZ;
521 rs.prevParam = rs.param;
523 if (paramCrossX < paramCrossZ)
529 rs.param = paramCrossX;
530 paramCrossX += paramDeltaX;
536 rs.param = paramCrossZ;
537 paramCrossZ += paramDeltaZ;
540 if (rs.param > rs.maxDistanceFlat)
542 rs.param = rs.maxDistanceFlat;
569 btVector3 vertices[3];
577 shape->getVertex(x,
z, vertices[0]);
578 shape->getVertex(x + 1,
z, vertices[1]);
579 shape->getVertex(x + 1,
z + 1, vertices[2]);
583 shape->getVertex(x,
z, vertices[0]);
584 shape->getVertex(x + 1,
z + 1, vertices[1]);
585 shape->getVertex(x,
z + 1, vertices[2]);
591 shape->getVertex(x,
z, vertices[0]);
592 shape->getVertex(x,
z + 1, vertices[1]);
593 shape->getVertex(x + 1,
z, vertices[2]);
597 shape->getVertex(x + 1,
z, vertices[0]);
598 shape->getVertex(x,
z + 1, vertices[1]);
599 shape->getVertex(x + 1,
z + 1, vertices[2]);
606 exec(bs.prev_x, bs.prev_z);
639 const btHeightfieldTerrainShape::Range chunk =
vbounds[x +
z *
width];
644 if (rs.maxDistanceFlat > 0.0001)
647 btScalar enterParam3d = rs.prevParam * flatTo3d;
648 btScalar exitParam3d = rs.param * flatTo3d;
654 if (enterPos[1] > chunk.max && exitPos[
m_indices[1]] > chunk.max)
658 if (enterPos[1] < chunk.min && exitPos[
m_indices[1]] < chunk.min)
680void btHeightfieldTerrainShape::performRaycast(
btTriangleCallback*
callback,
const btVector3& raySource,
const btVector3& rayTarget)
const
689 processTriangles.
shape =
this;
697 int indices[3] = { 0, 1, 2 };
703 int iBeginX =
static_cast<int>(
floor(beginPos[indices[0]]));
704 int iBeginZ =
static_cast<int>(
floor(beginPos[indices[2]]));
705 int iEndX =
static_cast<int>(
floor(endPos[indices[0]]));
706 int iEndZ =
static_cast<int>(
floor(endPos[indices[2]]));
708 if (iBeginX == iEndX && iBeginZ == iEndZ)
713 processTriangles.
exec(iBeginX, iEndZ);
722 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
726 btVector3 rayDiff = endPos - beginPos;
727 btScalar flatDistance2 = rayDiff[indices[0]] * rayDiff[indices[0]] + rayDiff[indices[2]] * rayDiff[indices[2]];
731 gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
737 processVBounds.rayBegin = beginPos;
738 processVBounds.rayEnd = endPos;
739 processVBounds.rayDir = rayDiff.normalized();
740 processVBounds.processTriangles = processTriangles;
750void btHeightfieldTerrainShape::buildAccelerator(
int chunkSize)
778 if (nChunksX == 0 || nChunksZ == 0)
787 for (
int cz = 0; cz < nChunksZ; ++cz)
789 int z0 = cz * chunkSize;
791 for (
int cx = 0; cx < nChunksX; ++cx)
793 int x0 = cx * chunkSize;
816 for (
int z = z0;
z < z0 + chunkSize + 1; ++
z)
823 for (
int x = x0; x < x0 + chunkSize + 1; ++
x)
836 else if (height > r.max)
848void btHeightfieldTerrainShape::clearAccelerator()
virtual void getVertex(int i, btVector3 &vtx) const
@ TERRAIN_SHAPE_PROXYTYPE
btTriangleInfoMap * m_triangleInfoMap
virtual btScalar getMargin() const =0
static int getQuantized(btScalar x)
void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector3 &endPos, int indices[3])
const void * m_heightfieldDataUnknown
btAlignedObjectArray< Range > m_vboundsGrid
PHY_ScalarType m_heightDataType
int m_heightStickWidth
terrain data
virtual btScalar getRawHeightFieldValue(int x, int y) const
bool m_useDiamondSubdivision
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
const short * m_heightfieldDataShort
bool m_useZigzagSubdivision
bool m_flipTriangleWinding
const btScalar * m_heightfieldDataFloat
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short *out, const btVector3 &point2, int isMax) const
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
SIMD_FORCE_INLINE btScalar btFabs(btScalar x)
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)=0
DEGForeachIDComponentCallback callback
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
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