diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2021-09-30 12:12:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-30 12:12:48 +0200 |
commit | b8c92828146ba22e2bb205da73aecc0619581829 (patch) | |
tree | 12e85ed2af037e8518498517cdfb906edbb3efe3 /thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp | |
parent | 4a9a2315666ecdde98b2e0f61802b005b862203d (diff) | |
parent | b55fd934ee0e4dfc6dede8bbaadb15bf71eff74e (diff) |
Merge pull request #48299 from akien-mga/bullet-3.09
Diffstat (limited to 'thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp')
-rw-r--r-- | thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp | 135 |
1 files changed, 118 insertions, 17 deletions
diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp index cab6980b65..01bf7f67f5 100644 --- a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -18,12 +18,57 @@ 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, PHY_ScalarType hdt, bool flipQuadEdges) :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]; @@ -232,6 +286,30 @@ getQuantized( return (int)(x + 0.5); } +// Equivalent to std::minmax({a, b, c}). +// Performs at most 3 comparisons. +static btHeightfieldTerrainShape::Range minmaxRange(btScalar a, btScalar b, btScalar c) +{ + if (a > b) + { + if (b > c) + return btHeightfieldTerrainShape::Range(c, a); + else if (a > c) + return btHeightfieldTerrainShape::Range(b, a); + else + return btHeightfieldTerrainShape::Range(b, c); + } + else + { + if (a > c) + return btHeightfieldTerrainShape::Range(c, b); + else if (b > c) + return btHeightfieldTerrainShape::Range(a, b); + else + return btHeightfieldTerrainShape::Range(a, c); + } +} + /// given input vector, return quantized version /** This routine is basically determining the gridpoint indices for a given @@ -334,7 +412,8 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback } // TODO If m_vboundsGrid is available, use it to determine if we really need to process this area - + + const Range aabbUpRange(aabbMin[m_upAxis], aabbMax[m_upAxis]); for (int j = startJ; j < endJ; j++) { for (int x = startX; x < endX; x++) @@ -349,29 +428,51 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1))) { - //first triangle getVertex(x, j, vertices[indices[0]]); getVertex(x, j + 1, vertices[indices[1]]); getVertex(x + 1, j + 1, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x, j); - //second triangle - // getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman - getVertex(x + 1, j + 1, vertices[indices[1]]); + + // Skip triangle processing if the triangle is out-of-AABB. + Range upRange = minmaxRange(vertices[0][m_upAxis], vertices[1][m_upAxis], vertices[2][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x, j); + + // already set: getVertex(x, j, vertices[indices[0]]) + + // equivalent to: getVertex(x + 1, j + 1, vertices[indices[1]]); + vertices[indices[1]] = vertices[indices[2]]; + getVertex(x + 1, j, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x+1, j); + upRange.min = btMin(upRange.min, vertices[indices[2]][m_upAxis]); + upRange.max = btMax(upRange.max, vertices[indices[2]][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x + 1, j); } else { - //first triangle getVertex(x, j, vertices[indices[0]]); getVertex(x, j + 1, vertices[indices[1]]); getVertex(x + 1, j, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x, j); - //second triangle - getVertex(x + 1, j, vertices[indices[0]]); - //getVertex(x,j+1,vertices[1]); + + // Skip triangle processing if the triangle is out-of-AABB. + Range upRange = minmaxRange(vertices[0][m_upAxis], vertices[1][m_upAxis], vertices[2][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x, j); + + // already set: getVertex(x, j + 1, vertices[indices[1]]); + + // equivalent to: getVertex(x + 1, j, vertices[indices[0]]); + vertices[indices[0]] = vertices[indices[2]]; + getVertex(x + 1, j + 1, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x+1, j); + upRange.min = btMin(upRange.min, vertices[indices[2]][m_upAxis]); + upRange.max = btMax(upRange.max, vertices[indices[2]][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x + 1, j); } } } @@ -846,4 +947,4 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize) void btHeightfieldTerrainShape::clearAccelerator() { m_vboundsGrid.clear(); -}
\ No newline at end of file +} |