diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp index 4ab9795d8..01bf7f67f 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -17,6 +17,47 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const float* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + /*heightScale=*/1, minHeight, maxHeight, upAxis, PHY_FLOAT, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const double* heightfieldData, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + /*heightScale=*/1, minHeight, maxHeight, upAxis, PHY_DOUBLE, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const short* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, PHY_SHORT, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const unsigned char* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, PHY_UCHAR, + flipQuadEdges); +} + btHeightfieldTerrainShape::btHeightfieldTerrainShape( int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, @@ -24,6 +65,10 @@ btHeightfieldTerrainShape::btHeightfieldTerrainShape( :m_userValue3(0), m_triangleInfoMap(0) { + // legacy constructor: Assumes PHY_FLOAT means btScalar. +#ifdef BT_USE_DOUBLE_PRECISION + if (hdt == PHY_FLOAT) hdt = PHY_DOUBLE; +#endif initialize(heightStickWidth, heightStickLength, heightfieldData, heightScale, minHeight, maxHeight, upAxis, hdt, flipQuadEdges); @@ -33,9 +78,12 @@ btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int h : m_userValue3(0), m_triangleInfoMap(0) { - // legacy constructor: support only float or unsigned char, - // and min height is zero + // legacy constructor: support only btScalar or unsigned char data, + // and min height is zero. PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR; +#ifdef BT_USE_DOUBLE_PRECISION + if (hdt == PHY_FLOAT) hdt = PHY_DOUBLE; +#endif btScalar minHeight = 0.0f; // previously, height = uchar * maxHeight / 65535. @@ -59,7 +107,7 @@ void btHeightfieldTerrainShape::initialize( // btAssert(heightScale) -- do we care? Trust caller here btAssert(minHeight <= maxHeight); // && "bad min/max height"); btAssert(upAxis >= 0 && upAxis < 3); // && "bad upAxis--should be in range [0,2]"); - btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT); // && "Bad height data type enum"); + btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_DOUBLE || hdt != PHY_SHORT); // && "Bad height data type enum"); // initialize member variables m_shapeType = TERRAIN_SHAPE_PROXYTYPE; @@ -152,6 +200,12 @@ btHeightfieldTerrainShape::getRawHeightFieldValue(int x, int y) const break; } + case PHY_DOUBLE: + { + val = m_heightfieldDataDouble[(y * m_heightStickWidth) + x]; + break; + } + case PHY_UCHAR: { unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y * m_heightStickWidth) + x]; diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h index 987ea324f..7e251fa71 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -50,17 +50,15 @@ subject to the following restrictions: The heightfield heights are determined from the data type used for the heightfieldData array. - - PHY_UCHAR: height at a point is the uchar value at the + - unsigned char: height at a point is the uchar value at the grid point, multipled by heightScale. uchar isn't recommended because of its inability to deal with negative values, and low resolution (8-bit). - - PHY_SHORT: height at a point is the short int value at that grid + - short: height at a point is the short int value at that grid point, multipled by heightScale. - - PHY_FLOAT: height at a point is the float value at that grid - point. heightScale is ignored when using the float heightfield - data type. + - float or dobule: height at a point is the value at that grid point. Whatever the caller specifies as minHeight and maxHeight will be honored. The class will not inspect the heightfield to discover the actual minimum @@ -103,7 +101,8 @@ protected: union { const unsigned char* m_heightfieldDataUnsignedChar; const short* m_heightfieldDataShort; - const btScalar* m_heightfieldDataFloat; + const float* m_heightfieldDataFloat; + const double* m_heightfieldDataDouble; const void* m_heightfieldDataUnknown; }; @@ -143,11 +142,33 @@ protected: public: BT_DECLARE_ALIGNED_ALLOCATOR(); - /// preferred constructor + /// preferred constructors + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const float* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const double* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const short* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const unsigned char* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + + /// legacy constructor /** This constructor supports a range of heightfield data types, and allows for a non-zero minimum height value. heightScale is needed for any integer-based heightfield data types. + + This legacy constructor considers `PHY_FLOAT` to mean `btScalar`. + With `BT_USE_DOUBLE_PRECISION`, it will expect `heightfieldData` + to be double-precision. */ btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar heightScale, @@ -158,7 +179,7 @@ public: /// legacy constructor /** The legacy constructor assumes the heightfield has a minimum height - of zero. Only unsigned char or floats are supported. For legacy + of zero. Only unsigned char or btScalar data are supported. For legacy compatibility reasons, heightScale is calculated as maxHeight / 65535 (and is only used when useFloatData = false). */