Improved performance of convex collision shapes, cache local AABB instead of recomputation. This fixes issue with very slow performance in larger .bsp levels.
Moved some asserts into 'btFullAssert', which is disabled by default (see btScalar.h to enable them). This is to speed-up debugging.
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
Bullet Continuous Collision Detection and Physics Library
|
Bullet Continuous Collision Detection and Physics Library
|
||||||
Erwin Coumans
|
Erwin Coumans
|
||||||
|
|
||||||
|
|
||||||
|
2007 Feb 25
|
||||||
|
- Improved performance of convex collision shapes, cache local AABB instead of recomputation. This fixes issue with very slow performance in larger .bsp levels
|
||||||
|
|
||||||
2007 Feb 24
|
2007 Feb 24
|
||||||
- Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices.
|
- Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices.
|
||||||
Should be faster and smaller then original version (quantized aabb check is done in integer space)
|
Should be faster and smaller then original version (quantized aabb check is done in integer space)
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ void ConcaveDemo::initPhysics()
|
|||||||
btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays,useQuantizedAabbCompression);
|
btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays,useQuantizedAabbCompression);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
|
// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
|
||||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
|
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
|
||||||
btVector3 worldMin(-1000,-1000,-1000);
|
btVector3 worldMin(-1000,-1000,-1000);
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ void UserCollisionAlgorithm::initPhysics()
|
|||||||
|
|
||||||
delete[] gVertices;
|
delete[] gVertices;
|
||||||
|
|
||||||
btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(trimesh);
|
bool useQuantizedBvhTree = false;
|
||||||
|
// btTriangleMesh uses a subpart for each triangle, this is not compatible with compressed quantized bvh node
|
||||||
|
btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(trimesh,useQuantizedBvhTree);
|
||||||
|
|
||||||
//ConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
//ConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int
|
|||||||
btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
|
btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
|
||||||
m_points[i] = point[0];
|
m_points[i] = point[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
|
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public:
|
|||||||
void addPoint(const btPoint3& point)
|
void addPoint(const btPoint3& point)
|
||||||
{
|
{
|
||||||
m_points.push_back(point);
|
m_points.push_back(point);
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
||||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ protected:
|
|||||||
|
|
||||||
btScalar m_collisionMargin;
|
btScalar m_collisionMargin;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
btConvexShape();
|
btConvexShape();
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ subject to the following restrictions:
|
|||||||
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface)
|
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface)
|
||||||
:m_stridingMesh(meshInterface)
|
:m_stridingMesh(meshInterface)
|
||||||
{
|
{
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -189,5 +190,7 @@ bool btConvexTriangleMeshShape::isInside(const btPoint3& pt,btScalar tolerance)
|
|||||||
void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
|
void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
|
||||||
{
|
{
|
||||||
m_stridingMesh->setScaling(scaling);
|
m_stridingMesh->setScaling(scaling);
|
||||||
|
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,21 +18,28 @@ subject to the following restrictions:
|
|||||||
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
|
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
|
||||||
:btBoxShape(halfExtents)
|
:btBoxShape(halfExtents)
|
||||||
{
|
{
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
|
btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
|
||||||
:btCylinderShape(halfExtents)
|
:btCylinderShape(halfExtents)
|
||||||
{
|
{
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
|
btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
|
||||||
:btCylinderShape(halfExtents)
|
:btCylinderShape(halfExtents)
|
||||||
{
|
{
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
//skip the box 'getAabb'
|
||||||
|
btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
|
inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ public:
|
|||||||
btCylinderShape (const btVector3& halfExtents);
|
btCylinderShape (const btVector3& halfExtents);
|
||||||
|
|
||||||
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
||||||
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||||
{
|
|
||||||
getAabbSlow(t,aabbMin,aabbMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ subject to the following restrictions:
|
|||||||
#include <BulletCollision/CollisionShapes/btPolyhedralConvexShape.h>
|
#include <BulletCollision/CollisionShapes/btPolyhedralConvexShape.h>
|
||||||
|
|
||||||
btPolyhedralConvexShape::btPolyhedralConvexShape()
|
btPolyhedralConvexShape::btPolyhedralConvexShape()
|
||||||
:m_optionalHull(0)
|
:m_optionalHull(0),
|
||||||
|
m_localAabbMin(1,1,1),
|
||||||
|
m_localAabbMax(-1,-1,-1),
|
||||||
|
m_isLocalAabbValid(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -116,3 +119,48 @@ void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& ine
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
|
||||||
|
//lazy evaluation of local aabb
|
||||||
|
btAssert(m_isLocalAabbValid);
|
||||||
|
|
||||||
|
btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX());
|
||||||
|
btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY());
|
||||||
|
btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ());
|
||||||
|
|
||||||
|
|
||||||
|
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
|
||||||
|
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
|
||||||
|
|
||||||
|
btMatrix3x3 abs_b = trans.getBasis().absolute();
|
||||||
|
|
||||||
|
btPoint3 center = trans(localCenter);
|
||||||
|
|
||||||
|
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
|
||||||
|
abs_b[1].dot(localHalfExtents),
|
||||||
|
abs_b[2].dot(localHalfExtents));
|
||||||
|
extent += btVector3(getMargin(),getMargin(),getMargin());
|
||||||
|
|
||||||
|
aabbMin = center - extent;
|
||||||
|
aabbMax = center + extent;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void btPolyhedralConvexShape::recalcLocalAabb()
|
||||||
|
{
|
||||||
|
m_isLocalAabbValid = true;
|
||||||
|
|
||||||
|
for (int i=0;i<3;i++)
|
||||||
|
{
|
||||||
|
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||||
|
vec[i] = btScalar(1.);
|
||||||
|
btVector3 tmp = localGetSupportingVertex(vec);
|
||||||
|
m_localAabbMax[i] = tmp[i]+m_collisionMargin;
|
||||||
|
vec[i] = btScalar(-1.);
|
||||||
|
tmp = localGetSupportingVertex(vec);
|
||||||
|
m_localAabbMin[i] = tmp[i]-m_collisionMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -25,6 +25,10 @@ subject to the following restrictions:
|
|||||||
class btPolyhedralConvexShape : public btConvexShape
|
class btPolyhedralConvexShape : public btConvexShape
|
||||||
{
|
{
|
||||||
|
|
||||||
|
btVector3 m_localAabbMin;
|
||||||
|
btVector3 m_localAabbMax;
|
||||||
|
bool m_isLocalAabbValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btPolyhedralConvexShape();
|
btPolyhedralConvexShape();
|
||||||
@@ -36,6 +40,8 @@ public:
|
|||||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
|
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
|
||||||
|
|
||||||
|
|
||||||
|
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||||
|
void recalcLocalAabb();
|
||||||
|
|
||||||
virtual int getNumVertices() const = 0 ;
|
virtual int getNumVertices() const = 0 ;
|
||||||
virtual int getNumEdges() const = 0;
|
virtual int getNumEdges() const = 0;
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const
|
|||||||
void btBU_Simplex1to4::addVertex(const btPoint3& pt)
|
void btBU_Simplex1to4::addVertex(const btPoint3& pt)
|
||||||
{
|
{
|
||||||
m_vertices[m_numVertices++] = pt;
|
m_vertices[m_numVertices++] = pt;
|
||||||
|
|
||||||
|
recalcLocalAabb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public:
|
|||||||
getVertex((i+1)%3,pb);
|
getVertex((i+1)%3,pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const
|
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const
|
||||||
{
|
{
|
||||||
// btAssert(0);
|
// btAssert(0);
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
|
|||||||
btScalar btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
btScalar btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
btContactSolverInfo info = infoGlobal;
|
btContactSolverInfo info = infoGlobal;
|
||||||
|
|
||||||
int numiter = infoGlobal.m_numIterations;
|
int numiter = infoGlobal.m_numIterations;
|
||||||
|
|||||||
@@ -45,12 +45,12 @@ class btMatrix3x3 {
|
|||||||
zx, zy, zz);
|
zx, zy, zz);
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 getColumn(int i) const
|
SIMD_FORCE_INLINE btVector3 getColumn(int i) const
|
||||||
{
|
{
|
||||||
return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
|
return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const btVector3& getRow(int i) const
|
SIMD_FORCE_INLINE const btVector3& getRow(int i) const
|
||||||
{
|
{
|
||||||
return m_el[i];
|
return m_el[i];
|
||||||
}
|
}
|
||||||
@@ -58,13 +58,13 @@ class btMatrix3x3 {
|
|||||||
|
|
||||||
SIMD_FORCE_INLINE btVector3& operator[](int i)
|
SIMD_FORCE_INLINE btVector3& operator[](int i)
|
||||||
{
|
{
|
||||||
assert(0 <= i && i < 3);
|
btFullAssert(0 <= i && i < 3);
|
||||||
return m_el[i];
|
return m_el[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const btVector3& operator[](int i) const
|
SIMD_FORCE_INLINE const btVector3& operator[](int i) const
|
||||||
{
|
{
|
||||||
assert(0 <= i && i < 3);
|
btFullAssert(0 <= i && i < 3);
|
||||||
return m_el[i];
|
return m_el[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class btMatrix3x3 {
|
|||||||
void setRotation(const btQuaternion& q)
|
void setRotation(const btQuaternion& q)
|
||||||
{
|
{
|
||||||
btScalar d = q.length2();
|
btScalar d = q.length2();
|
||||||
assert(d != btScalar(0.0));
|
btFullAssert(d != btScalar(0.0));
|
||||||
btScalar s = btScalar(2.0) / d;
|
btScalar s = btScalar(2.0) / d;
|
||||||
btScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s;
|
btScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s;
|
||||||
btScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs;
|
btScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs;
|
||||||
@@ -323,7 +323,7 @@ class btMatrix3x3 {
|
|||||||
{
|
{
|
||||||
btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
|
btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
|
||||||
btScalar det = (*this)[0].dot(co);
|
btScalar det = (*this)[0].dot(co);
|
||||||
assert(det != btScalar(0.0));
|
btFullAssert(det != btScalar(0.0));
|
||||||
btScalar s = btScalar(1.0) / det;
|
btScalar s = btScalar(1.0) / det;
|
||||||
return btMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
return btMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
||||||
co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define btAssert assert
|
#define btAssert assert
|
||||||
|
//btFullAssert is optional, slows down a lot
|
||||||
|
#define btFullAssert
|
||||||
#else
|
#else
|
||||||
|
|
||||||
//non-windows systems
|
//non-windows systems
|
||||||
@@ -48,6 +50,8 @@ subject to the following restrictions:
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
#define btAssert assert
|
#define btAssert assert
|
||||||
|
//btFullAssert is optional, slows down a lot
|
||||||
|
#define btFullAssert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
|
/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ public:
|
|||||||
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
|
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
|
||||||
// #define QUATERNION_DERIVATIVE
|
// #define QUATERNION_DERIVATIVE
|
||||||
#ifdef QUATERNION_DERIVATIVE
|
#ifdef QUATERNION_DERIVATIVE
|
||||||
btQuaternion orn = curTrans.getRotation();
|
btQuaternion predictedOrn = curTrans.getRotation();
|
||||||
orn += (angvel * orn) * (timeStep * btScalar(0.5));
|
predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
|
||||||
orn.normalize();
|
predictedOrn.normalize();
|
||||||
#else
|
#else
|
||||||
//exponential map
|
//exponential map
|
||||||
btVector3 axis;
|
btVector3 axis;
|
||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
btQuaternion orn0 = curTrans.getRotation();
|
btQuaternion orn0 = curTrans.getRotation();
|
||||||
|
|
||||||
btQuaternion predictedOrn = dorn * orn0;
|
btQuaternion predictedOrn = dorn * orn0;
|
||||||
|
predictedOrn.normalize();
|
||||||
#endif
|
#endif
|
||||||
predictedTransform.setRotation(predictedOrn);
|
predictedTransform.setRotation(predictedOrn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
|
|
||||||
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
|
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
|
||||||
{
|
{
|
||||||
assert(s != btScalar(0.0));
|
btFullAssert(s != btScalar(0.0));
|
||||||
return *this *= btScalar(1.0) / s;
|
return *this *= btScalar(1.0) / s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
|
SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
|
||||||
{
|
{
|
||||||
btScalar s = btSqrt(length2() * v.length2());
|
btScalar s = btSqrt(length2() * v.length2());
|
||||||
assert(s != btScalar(0.0));
|
btFullAssert(s != btScalar(0.0));
|
||||||
return btAcos(dot(v) / s);
|
return btAcos(dot(v) / s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ operator*(const btScalar& s, const btVector3& v)
|
|||||||
SIMD_FORCE_INLINE btVector3
|
SIMD_FORCE_INLINE btVector3
|
||||||
operator/(const btVector3& v, const btScalar& s)
|
operator/(const btVector3& v, const btScalar& s)
|
||||||
{
|
{
|
||||||
assert(s != btScalar(0.0));
|
btFullAssert(s != btScalar(0.0));
|
||||||
return v * (btScalar(1.0) / s);
|
return v * (btScalar(1.0) / s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user