Skip to content

Commit

Permalink
bullet: Sync with upstream 3.17
Browse files Browse the repository at this point in the history
Stop include Bullet headers using `-isystem` for GCC/Clang as it misleads
SCons into not properly rebuilding all files when headers change.

This means we also need to make sure Bullet builds without warning, and
current version fares fairly well, there were just a couple to fix (patch
included).

Increase minimum version for distro packages to 2.90 (this was never released
as the "next" version after 2.89 was 3.05... but that covers it too).

Fixes godotengine#43868.

(cherry picked from commit b7901c7)
  • Loading branch information
akien-mga committed Sep 30, 2021
1 parent 4a9a231 commit 71f8b80
Show file tree
Hide file tree
Showing 24 changed files with 326 additions and 79 deletions.
9 changes: 3 additions & 6 deletions modules/bullet/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ env_bullet = env_modules.Clone()
thirdparty_obj = []

if env["builtin_bullet"]:
# Build only version 2 for now (as of 2.89)
# Build only "Bullet2" API (not "Bullet3" folders).
# Sync file list with relevant upstream CMakeLists.txt for each folder.
if env["float"] == "64":
env.Append(CPPDEFINES=["BT_USE_DOUBLE_PRECISION=1"])
Expand Down Expand Up @@ -189,6 +189,7 @@ if env["builtin_bullet"]:
"LinearMath/btGeometryUtil.cpp",
"LinearMath/btPolarDecomposition.cpp",
"LinearMath/btQuickprof.cpp",
"LinearMath/btReducedVector.cpp",
"LinearMath/btSerializer.cpp",
"LinearMath/btSerializer64.cpp",
"LinearMath/btThreads.cpp",
Expand All @@ -200,11 +201,7 @@ if env["builtin_bullet"]:

thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]

# Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC.
if not env.msvc:
env_bullet.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path])
else:
env_bullet.Prepend(CPPPATH=[thirdparty_dir])
env_bullet.Prepend(CPPPATH=[thirdparty_dir])
if env["target"] == "debug" or env["target"] == "release_debug":
env_bullet.Append(CPPDEFINES=["DEBUG"])

Expand Down
8 changes: 5 additions & 3 deletions thirdparty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ Files extracted from upstream source:
## bullet

- Upstream: https://github.com/bulletphysics/bullet3
- Version: 3.08 (df09fd9ed37e365ceae884ca7f620b61607dae2e, 2020)
- Version: 3.17 (ebe1916b90acae8b13cd8c6b637d8327cdc64e94, 2021)
- License: zlib

Files extracted from upstream source:

- src/* apart from CMakeLists.txt and premake4.lua files
- LICENSE.txt
- `src/*` apart from CMakeLists.txt and premake4.lua files
- `LICENSE.txt`, and `VERSION` as `VERSION.txt`

Includes a warning fix which should be upstreamed soon (see patch in `patches`).


## certs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct ClipVertex
btVector3 v;
int id;
//b2ContactID id;
//b2ContactID id;
};

#define b2Dot(a, b) (a).dot(b)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ subject to the following restrictions:
#define WANTS_DEACTIVATION 3
#define DISABLE_DEACTIVATION 4
#define DISABLE_SIMULATION 5
#define FIXED_BASE_MULTI_BODY 6

struct btBroadphaseProxy;
class btCollisionShape;
Expand Down Expand Up @@ -304,7 +305,7 @@ btCollisionObject

SIMD_FORCE_INLINE bool isActive() const
{
return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
return ((getActivationState() != FIXED_BASE_MULTI_BODY) && (getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
}

void setRestitution(btScalar rest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ struct btSingleSweepCallback : public btBroadphaseRayCallback
m_castShape(castShape)
{
btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin() - m_convexFromTrans.getOrigin());
btVector3 rayDir = unnormalizedRayDir.normalized();
btVector3 rayDir = unnormalizedRayDir.fuzzyZero() ? btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)) : unnormalizedRayDir.normalized();
///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
Expand Down Expand Up @@ -1294,9 +1294,7 @@ class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIn
btVector3 normalColor(1, 1, 0);
m_debugDrawer->drawLine(center, center + normal, normalColor);
}
m_debugDrawer->drawLine(wv0, wv1, m_color);
m_debugDrawer->drawLine(wv1, wv2, m_color);
m_debugDrawer->drawLine(wv2, wv0, m_color);
m_debugDrawer->drawTriangle(wv0, wv1, wv2, m_color, 1.0);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,58 @@ 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);
Expand All @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++)
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -846,4 +947,4 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
void btHeightfieldTerrainShape::clearAccelerator()
{
m_vboundsGrid.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -75,6 +73,14 @@ btHeightfieldTerrainShape : public btConcaveShape
public:
struct Range
{
Range() {}
Range(btScalar min, btScalar max) : min(min), max(max) {}

bool overlaps(const Range& other) const
{
return !(min > other.max || max < other.min);
}

btScalar min;
btScalar max;
};
Expand All @@ -95,7 +101,8 @@ btHeightfieldTerrainShape : public btConcaveShape
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;
};

Expand Down Expand Up @@ -135,11 +142,33 @@ btHeightfieldTerrainShape : public btConcaveShape
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,
Expand All @@ -150,7 +179,7 @@ btHeightfieldTerrainShape : public btConcaveShape
/// 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).
*/
Expand Down Expand Up @@ -218,4 +247,4 @@ btHeightfieldTerrainShape : public btConcaveShape
}
};

#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
Loading

0 comments on commit 71f8b80

Please sign in to comment.