Merge pull request #48299 from akien-mga/bullet-3.09
This commit is contained in:
commit
b8c9282814
|
@ -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"])
|
||||
|
@ -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",
|
||||
|
@ -200,15 +201,11 @@ 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])
|
||||
if env["target"] == "debug" or env["target"] == "release_debug":
|
||||
env_bullet.Append(CPPDEFINES=["DEBUG"])
|
||||
|
||||
env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD"])
|
||||
env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD", "BT_THREADSAFE"])
|
||||
|
||||
env_thirdparty = env_bullet.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -80,6 +80,7 @@ struct ClipVertex
|
|||
btVector3 v;
|
||||
int id;
|
||||
//b2ContactID id;
|
||||
//b2ContactID id;
|
||||
};
|
||||
|
||||
#define b2Dot(a, b) (a).dot(b)
|
||||
|
|
|
@ -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;
|
||||
|
@ -304,7 +305,7 @@ public:
|
|||
|
||||
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)
|
||||
|
|
|
@ -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];
|
||||
|
@ -1294,9 +1294,7 @@ public:
|
|||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -335,6 +413,7 @@ 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]]);
|
||||
|
||||
// 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);
|
||||
//second triangle
|
||||
// getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
|
||||
getVertex(x + 1, j + 1, vertices[indices[1]]);
|
||||
|
||||
// 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]]);
|
||||
|
||||
// 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);
|
||||
//second triangle
|
||||
getVertex(x + 1, j, vertices[indices[0]]);
|
||||
//getVertex(x,j+1,vertices[1]);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -95,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;
|
||||
};
|
||||
|
||||
|
@ -135,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,
|
||||
|
@ -150,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).
|
||||
*/
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
const btScalar SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2)
|
||||
const btScalar SLEEP_TIMEOUT = btScalar(2); // in seconds
|
||||
const btScalar INITIAL_SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2)
|
||||
const btScalar INITIAL_SLEEP_TIMEOUT = btScalar(2); // in seconds
|
||||
} // namespace
|
||||
|
||||
void btMultiBody::spatialTransform(const btMatrix3x3 &rotation_matrix, // rotates vectors in 'from' frame to vectors in 'to' frame
|
||||
|
@ -110,6 +110,9 @@ btMultiBody::btMultiBody(int n_links,
|
|||
m_canSleep(canSleep),
|
||||
m_canWakeup(true),
|
||||
m_sleepTimer(0),
|
||||
m_sleepEpsilon(INITIAL_SLEEP_EPSILON),
|
||||
m_sleepTimeout(INITIAL_SLEEP_TIMEOUT),
|
||||
|
||||
m_userObjectPointer(0),
|
||||
m_userIndex2(-1),
|
||||
m_userIndex(-1),
|
||||
|
@ -1411,7 +1414,7 @@ void btMultiBody::solveImatrix(const btSpatialForceVector &rhs, btSpatialMotionV
|
|||
}
|
||||
}
|
||||
|
||||
void btMultiBody::mulMatrix(btScalar *pA, btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const
|
||||
void btMultiBody::mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const
|
||||
{
|
||||
for (int row = 0; row < rowsA; row++)
|
||||
{
|
||||
|
@ -2104,10 +2107,10 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
|
|||
motion += m_realBuf[i] * m_realBuf[i];
|
||||
}
|
||||
|
||||
if (motion < SLEEP_EPSILON)
|
||||
if (motion < m_sleepEpsilon)
|
||||
{
|
||||
m_sleepTimer += timestep;
|
||||
if (m_sleepTimer > SLEEP_TIMEOUT)
|
||||
if (m_sleepTimer > m_sleepTimeout)
|
||||
{
|
||||
goToSleep();
|
||||
}
|
||||
|
|
|
@ -545,7 +545,10 @@ public:
|
|||
{
|
||||
m_canWakeup = canWakeup;
|
||||
}
|
||||
bool isAwake() const { return m_awake; }
|
||||
bool isAwake() const
|
||||
{
|
||||
return m_awake;
|
||||
}
|
||||
void wakeUp();
|
||||
void goToSleep();
|
||||
void checkMotionAndSleepIfRequired(btScalar timestep);
|
||||
|
@ -726,6 +729,17 @@ public:
|
|||
|
||||
bool isLinkAndAllAncestorsKinematic(const int i) const;
|
||||
|
||||
void setSleepThreshold(btScalar sleepThreshold)
|
||||
{
|
||||
m_sleepEpsilon = sleepThreshold;
|
||||
}
|
||||
|
||||
void setSleepTimeout(btScalar sleepTimeout)
|
||||
{
|
||||
this->m_sleepTimeout = sleepTimeout;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
btMultiBody(const btMultiBody &); // not implemented
|
||||
void operator=(const btMultiBody &); // not implemented
|
||||
|
@ -745,7 +759,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void mulMatrix(btScalar * pA, btScalar * pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const;
|
||||
void mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const;
|
||||
|
||||
private:
|
||||
btMultiBodyLinkCollider *m_baseCollider; //can be NULL
|
||||
|
@ -801,6 +815,8 @@ private:
|
|||
bool m_canSleep;
|
||||
bool m_canWakeup;
|
||||
btScalar m_sleepTimer;
|
||||
btScalar m_sleepEpsilon;
|
||||
btScalar m_sleepTimeout;
|
||||
|
||||
void *m_userObjectPointer;
|
||||
int m_userIndex2;
|
||||
|
|
|
@ -61,7 +61,8 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint(btMultiBodySolverConstra
|
|||
btScalar lowerLimit, btScalar upperLimit,
|
||||
bool angConstraint,
|
||||
btScalar relaxation,
|
||||
bool isFriction, btScalar desiredVelocity, btScalar cfmSlip)
|
||||
bool isFriction, btScalar desiredVelocity, btScalar cfmSlip,
|
||||
btScalar damping)
|
||||
{
|
||||
solverConstraint.m_multiBodyA = m_bodyA;
|
||||
solverConstraint.m_multiBodyB = m_bodyB;
|
||||
|
@ -348,7 +349,7 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint(btMultiBodySolverConstra
|
|||
|
||||
{
|
||||
btScalar positionalError = 0.f;
|
||||
btScalar velocityError = desiredVelocity - rel_vel; // * damping;
|
||||
btScalar velocityError = (desiredVelocity - rel_vel) * damping;
|
||||
|
||||
btScalar erp = infoGlobal.m_erp2;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ protected:
|
|||
bool angConstraint = false,
|
||||
|
||||
btScalar relaxation = 1.f,
|
||||
bool isFriction = false, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
|
||||
bool isFriction = false, btScalar desiredVelocity = 0, btScalar cfmSlip = 0, btScalar damping = 1.0);
|
||||
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
|
|
@ -137,7 +137,14 @@ void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep)
|
|||
btMultiBodyLinkCollider* col = body->getBaseCollider();
|
||||
if (col && col->getActivationState() == ACTIVE_TAG)
|
||||
{
|
||||
if (body->hasFixedBase())
|
||||
{
|
||||
col->setActivationState(FIXED_BASE_MULTI_BODY);
|
||||
} else
|
||||
{
|
||||
col->setActivationState(WANTS_DEACTIVATION);
|
||||
}
|
||||
|
||||
col->setDeactivationTime(0.f);
|
||||
}
|
||||
for (int b = 0; b < body->getNumLinks(); b++)
|
||||
|
|
|
@ -42,6 +42,7 @@ void btMultiBodyJointMotor::finalizeMultiDof()
|
|||
int linkDoF = 0;
|
||||
unsigned int offset = 6 + (m_bodyA->getLink(m_linkA).m_dofOffset + linkDoF);
|
||||
|
||||
// row 0: the lower bound
|
||||
// row 0: the lower bound
|
||||
jacobianA(0)[offset] = 1;
|
||||
|
||||
|
|
|
@ -26,10 +26,13 @@ btMultiBodySphericalJointMotor::btMultiBodySphericalJointMotor(btMultiBody* body
|
|||
: btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 3, true, MULTIBODY_CONSTRAINT_SPHERICAL_MOTOR),
|
||||
m_desiredVelocity(0, 0, 0),
|
||||
m_desiredPosition(0,0,0,1),
|
||||
m_kd(1.),
|
||||
m_kp(0.2),
|
||||
m_use_multi_dof_params(false),
|
||||
m_kd(1., 1., 1.),
|
||||
m_kp(0.2, 0.2, 0.2),
|
||||
m_erp(1),
|
||||
m_rhsClamp(SIMD_INFINITY)
|
||||
m_rhsClamp(SIMD_INFINITY),
|
||||
m_maxAppliedImpulseMultiDof(maxMotorImpulse, maxMotorImpulse, maxMotorImpulse),
|
||||
m_damping(1.0, 1.0, 1.0)
|
||||
{
|
||||
|
||||
m_maxAppliedImpulse = maxMotorImpulse;
|
||||
|
@ -44,6 +47,7 @@ void btMultiBodySphericalJointMotor::finalizeMultiDof()
|
|||
int linkDoF = 0;
|
||||
unsigned int offset = 6 + (m_bodyA->getLink(m_linkA).m_dofOffset + linkDoF);
|
||||
|
||||
// row 0: the lower bound
|
||||
// row 0: the lower bound
|
||||
jacobianA(0)[offset] = 1;
|
||||
|
||||
|
@ -138,7 +142,8 @@ btQuaternion relRot = currentQuat.inverse() * desiredQuat;
|
|||
btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof];
|
||||
btScalar desiredVelocity = this->m_desiredVelocity[row];
|
||||
|
||||
btScalar velocityError = desiredVelocity - currentVelocity;
|
||||
double kd = m_use_multi_dof_params ? m_kd[row % 3] : m_kd[0];
|
||||
btScalar velocityError = (desiredVelocity - currentVelocity) * kd;
|
||||
|
||||
btMatrix3x3 frameAworld;
|
||||
frameAworld.setIdentity();
|
||||
|
@ -151,12 +156,16 @@ btQuaternion relRot = currentQuat.inverse() * desiredQuat;
|
|||
case btMultibodyLink::eSpherical:
|
||||
{
|
||||
btVector3 constraintNormalAng = frameAworld.getColumn(row % 3);
|
||||
posError = m_kp*angleDiff[row % 3];
|
||||
double kp = m_use_multi_dof_params ? m_kp[row % 3] : m_kp[0];
|
||||
posError = kp*angleDiff[row % 3];
|
||||
double max_applied_impulse = m_use_multi_dof_params ? m_maxAppliedImpulseMultiDof[row % 3] : m_maxAppliedImpulse;
|
||||
fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng,
|
||||
btVector3(0,0,0), dummy, dummy,
|
||||
posError,
|
||||
infoGlobal,
|
||||
-m_maxAppliedImpulse, m_maxAppliedImpulse, true);
|
||||
-max_applied_impulse, max_applied_impulse, true,
|
||||
1.0, false, 0, 0,
|
||||
m_damping[row % 3]);
|
||||
constraintRow.m_orgConstraint = this;
|
||||
constraintRow.m_orgDofIndex = row;
|
||||
break;
|
||||
|
|
|
@ -26,10 +26,13 @@ class btMultiBodySphericalJointMotor : public btMultiBodyConstraint
|
|||
protected:
|
||||
btVector3 m_desiredVelocity;
|
||||
btQuaternion m_desiredPosition;
|
||||
btScalar m_kd;
|
||||
btScalar m_kp;
|
||||
bool m_use_multi_dof_params;
|
||||
btVector3 m_kd;
|
||||
btVector3 m_kp;
|
||||
btScalar m_erp;
|
||||
btScalar m_rhsClamp; //maximum error
|
||||
btVector3 m_maxAppliedImpulseMultiDof;
|
||||
btVector3 m_damping;
|
||||
|
||||
public:
|
||||
btMultiBodySphericalJointMotor(btMultiBody* body, int link, btScalar maxMotorImpulse);
|
||||
|
@ -44,16 +47,32 @@ public:
|
|||
btMultiBodyJacobianData& data,
|
||||
const btContactSolverInfo& infoGlobal);
|
||||
|
||||
virtual void setVelocityTarget(const btVector3& velTarget, btScalar kd = 1.f)
|
||||
virtual void setVelocityTarget(const btVector3& velTarget, btScalar kd = 1.0)
|
||||
{
|
||||
m_desiredVelocity = velTarget;
|
||||
m_kd = btVector3(kd, kd, kd);
|
||||
m_use_multi_dof_params = false;
|
||||
}
|
||||
|
||||
virtual void setVelocityTargetMultiDof(const btVector3& velTarget, const btVector3& kd = btVector3(1.0, 1.0, 1.0))
|
||||
{
|
||||
m_desiredVelocity = velTarget;
|
||||
m_kd = kd;
|
||||
m_use_multi_dof_params = true;
|
||||
}
|
||||
|
||||
virtual void setPositionTarget(const btQuaternion& posTarget, btScalar kp = 1.f)
|
||||
virtual void setPositionTarget(const btQuaternion& posTarget, btScalar kp =1.f)
|
||||
{
|
||||
m_desiredPosition = posTarget;
|
||||
m_kp = btVector3(kp, kp, kp);
|
||||
m_use_multi_dof_params = false;
|
||||
}
|
||||
|
||||
virtual void setPositionTargetMultiDof(const btQuaternion& posTarget, const btVector3& kp = btVector3(1.f, 1.f, 1.f))
|
||||
{
|
||||
m_desiredPosition = posTarget;
|
||||
m_kp = kp;
|
||||
m_use_multi_dof_params = true;
|
||||
}
|
||||
|
||||
virtual void setErp(btScalar erp)
|
||||
|
@ -68,6 +87,28 @@ public:
|
|||
{
|
||||
m_rhsClamp = rhsClamp;
|
||||
}
|
||||
|
||||
btScalar getMaxAppliedImpulseMultiDof(int i) const
|
||||
{
|
||||
return m_maxAppliedImpulseMultiDof[i];
|
||||
}
|
||||
|
||||
void setMaxAppliedImpulseMultiDof(const btVector3& maxImp)
|
||||
{
|
||||
m_maxAppliedImpulseMultiDof = maxImp;
|
||||
m_use_multi_dof_params = true;
|
||||
}
|
||||
|
||||
btScalar getDamping(int i) const
|
||||
{
|
||||
return m_damping[i];
|
||||
}
|
||||
|
||||
void setDamping(const btVector3& damping)
|
||||
{
|
||||
m_damping = damping;
|
||||
}
|
||||
|
||||
virtual void debugDraw(class btIDebugDraw* drawer)
|
||||
{
|
||||
//todo(erwincoumans)
|
||||
|
|
|
@ -532,7 +532,7 @@ void btMLCPSolver::createMLCP(const btContactSolverInfo& infoGlobal)
|
|||
J_transpose = J.transpose();
|
||||
|
||||
btMatrixXu& tmp = m_scratchTmp;
|
||||
|
||||
//Minv.printMatrix("Minv=");
|
||||
{
|
||||
{
|
||||
BT_PROFILE("J*Minv");
|
||||
|
@ -543,7 +543,7 @@ void btMLCPSolver::createMLCP(const btContactSolverInfo& infoGlobal)
|
|||
m_A = tmp * J_transpose;
|
||||
}
|
||||
}
|
||||
|
||||
//J.printMatrix("J");
|
||||
if (1)
|
||||
{
|
||||
// add cfm to the diagonal of m_A
|
||||
|
|
|
@ -405,6 +405,10 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt)
|
|||
for (int i = 0; i < m_softBodies.size(); ++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
/* Clear contacts */
|
||||
psb->m_nodeRigidContacts.resize(0);
|
||||
psb->m_faceRigidContacts.resize(0);
|
||||
psb->m_faceNodeContacts.resize(0);
|
||||
|
||||
if (psb->isActive())
|
||||
{
|
||||
|
@ -472,10 +476,6 @@ void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar d
|
|||
{
|
||||
psb->updateFaceTree(true, true);
|
||||
}
|
||||
/* Clear contacts */
|
||||
psb->m_nodeRigidContacts.resize(0);
|
||||
psb->m_faceRigidContacts.resize(0);
|
||||
psb->m_faceNodeContacts.resize(0);
|
||||
/* Optimize dbvt's */
|
||||
// psb->m_ndbvt.optimizeIncremental(1);
|
||||
// psb->m_fdbvt.optimizeIncremental(1);
|
||||
|
|
|
@ -29,7 +29,7 @@ class btDeformableMousePickingForce : public btDeformableLagrangianForce
|
|||
|
||||
public:
|
||||
typedef btAlignedObjectArray<btVector3> TVStack;
|
||||
btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, btVector3 mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce)
|
||||
btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, const btVector3& mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1317,8 +1317,8 @@ public:
|
|||
}
|
||||
for (int k = 0; k < m_faceNodeContacts.size(); ++k)
|
||||
{
|
||||
int i = indices[k];
|
||||
btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i];
|
||||
int idx = indices[k];
|
||||
btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[idx];
|
||||
btSoftBody::Node* node = c.m_node;
|
||||
btSoftBody::Face* face = c.m_face;
|
||||
const btVector3& w = c.m_bary;
|
||||
|
|
|
@ -21,7 +21,7 @@ subject to the following restrictions:
|
|||
|
||||
///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
|
||||
///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
|
||||
///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum.
|
||||
///A class that implements the btIDebugDraw interface will need to provide non-empty implementations of the the drawLine and getDebugMode methods at a minimum.
|
||||
///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
|
||||
class btIDebugDraw
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ subject to the following restrictions:
|
|||
#include <float.h>
|
||||
|
||||
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
||||
#define BT_BULLET_VERSION 308
|
||||
#define BT_BULLET_VERSION 317
|
||||
|
||||
inline int btGetVersion()
|
||||
{
|
||||
|
|
|
@ -480,8 +480,8 @@ public:
|
|||
}
|
||||
|
||||
buffer[9] = '3';
|
||||
buffer[10] = '0';
|
||||
buffer[11] = '8';
|
||||
buffer[10] = '1';
|
||||
buffer[11] = '7';
|
||||
}
|
||||
|
||||
virtual void startSerialization()
|
||||
|
@ -499,7 +499,6 @@ public:
|
|||
writeDNA();
|
||||
|
||||
//if we didn't pre-allocate a buffer, we need to create a contiguous buffer now
|
||||
int mysize = 0;
|
||||
if (!m_totalSize)
|
||||
{
|
||||
if (m_buffer)
|
||||
|
@ -511,14 +510,12 @@ public:
|
|||
unsigned char* currentPtr = m_buffer;
|
||||
writeHeader(m_buffer);
|
||||
currentPtr += BT_HEADER_LENGTH;
|
||||
mysize += BT_HEADER_LENGTH;
|
||||
for (int i = 0; i < m_chunkPtrs.size(); i++)
|
||||
{
|
||||
int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length;
|
||||
memcpy(currentPtr, m_chunkPtrs[i], curLength);
|
||||
btAlignedFree(m_chunkPtrs[i]);
|
||||
currentPtr += curLength;
|
||||
mysize += curLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
3.17
|
|
@ -0,0 +1,42 @@
|
|||
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.h b/thirdparty/bullet/BulletSoftBody/btSoftBody.h
|
||||
index f578487b8c..dfde8fd1e4 100644
|
||||
--- a/thirdparty/bullet/BulletSoftBody/btSoftBody.h
|
||||
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.h
|
||||
@@ -1317,8 +1317,8 @@ public:
|
||||
}
|
||||
for (int k = 0; k < m_faceNodeContacts.size(); ++k)
|
||||
{
|
||||
- int i = indices[k];
|
||||
- btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i];
|
||||
+ int idx = indices[k];
|
||||
+ btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[idx];
|
||||
btSoftBody::Node* node = c.m_node;
|
||||
btSoftBody::Face* face = c.m_face;
|
||||
const btVector3& w = c.m_bary;
|
||||
diff --git a/thirdparty/bullet/LinearMath/btSerializer.h b/thirdparty/bullet/LinearMath/btSerializer.h
|
||||
index ce4fc34e20..11592d2ccd 100644
|
||||
--- a/thirdparty/bullet/LinearMath/btSerializer.h
|
||||
+++ b/thirdparty/bullet/LinearMath/btSerializer.h
|
||||
@@ -499,7 +499,6 @@ public:
|
||||
writeDNA();
|
||||
|
||||
//if we didn't pre-allocate a buffer, we need to create a contiguous buffer now
|
||||
- int mysize = 0;
|
||||
if (!m_totalSize)
|
||||
{
|
||||
if (m_buffer)
|
||||
@@ -511,14 +510,12 @@ public:
|
||||
unsigned char* currentPtr = m_buffer;
|
||||
writeHeader(m_buffer);
|
||||
currentPtr += BT_HEADER_LENGTH;
|
||||
- mysize += BT_HEADER_LENGTH;
|
||||
for (int i = 0; i < m_chunkPtrs.size(); i++)
|
||||
{
|
||||
int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length;
|
||||
memcpy(currentPtr, m_chunkPtrs[i], curLength);
|
||||
btAlignedFree(m_chunkPtrs[i]);
|
||||
currentPtr += curLength;
|
||||
- mysize += curLength;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue