Update to bullet 2.79 (somewhat work-in-progress, but it appears to be working fine so far).

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10122 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2011-11-07 08:51:51 +00:00
parent a8d0f14cbf
commit 91ae822c25
175 changed files with 7549 additions and 1641 deletions

View File

@@ -10,9 +10,11 @@ add_library(bulletmath
src/LinearMath/btAlignedObjectArray.h src/LinearMath/btQuaternion.h
src/LinearMath/btConvexHull.cpp src/LinearMath/btQuickprof.cpp
src/LinearMath/btConvexHull.h src/LinearMath/btQuickprof.h
src/LinearMath/btConvexHullComputer.h src/LinearMath/btConvexHullComputer.cpp
src/LinearMath/btDefaultMotionState.h src/LinearMath/btRandom.h
src/LinearMath/btGeometryUtil.cpp src/LinearMath/btScalar.h
src/LinearMath/btGeometryUtil.h src/LinearMath/btSerializer.cpp
src/LinearMath/btGrahamScan2dConvexHull.h
src/LinearMath/btHashMap.h src/LinearMath/btSerializer.h
src/LinearMath/btIDebugDraw.h src/LinearMath/btStackAlloc.h
src/LinearMath/btList.h src/LinearMath/btTransform.h
@@ -126,6 +128,8 @@ add_library(bulletcollision
src/BulletCollision/CollisionShapes/btConvexInternalShape.h
src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
src/BulletCollision/CollisionShapes/btConvexPolyhedron.h
src/BulletCollision/CollisionShapes/btConvexShape.cpp
src/BulletCollision/CollisionShapes/btConvexShape.h
src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
@@ -233,6 +237,8 @@ add_library(bulletcollision
src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
@@ -272,8 +278,6 @@ add_library(bulletdynamics
src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
src/BulletDynamics/ConstraintSolver/btSolverBody.h
src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
src/BulletDynamics/ConstraintSolver/btSorLcp.cpp
src/BulletDynamics/ConstraintSolver/btSorLcp.h
src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp

View File

@@ -1 +1 @@
2.77
2.79

View File

@@ -44,9 +44,3 @@ echo "1) btDiscreteDynamicsWorld.cpp:
}
"
echo "2) btRaycastVehicle.cpp
From:
rel_pos[2] *= wheelInfo.m_rollInfluence;
to
rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
"

View File

@@ -65,7 +65,7 @@ extern "C" {
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
extern plPhysicsSdkHandle plNewBulletSdk(void); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
@@ -116,16 +116,16 @@ extern "C" {
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCompoundShape();
extern plCollisionShapeHandle plNewCompoundShape(void);
extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionShapeHandle shape);
/* Convex Meshes */
extern plCollisionShapeHandle plNewConvexHullShape();
extern plCollisionShapeHandle plNewConvexHullShape(void);
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface();
extern plMeshInterfaceHandle plNewMeshInterface(void);
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);

View File

@@ -16,8 +16,8 @@
//
// 3. This notice may not be removed or altered from any source distribution.
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
#ifndef BT_AXIS_SWEEP_3_H
#define BT_AXIS_SWEEP_3_H
#include "LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_INTERFACE_H
#define BROADPHASE_INTERFACE_H
#ifndef BT_BROADPHASE_INTERFACE_H
#define BT_BROADPHASE_INTERFACE_H
@@ -79,4 +79,4 @@ public:
};
#endif //BROADPHASE_INTERFACE_H
#endif //BT_BROADPHASE_INTERFACE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
#ifndef BT_BROADPHASE_PROXY_H
#define BT_BROADPHASE_PROXY_H
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btVector3.h"
@@ -266,5 +266,5 @@ SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphaseP
}
#endif //BROADPHASE_PROXY_H
#endif //BT_BROADPHASE_PROXY_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
#ifndef BT_COLLISION_ALGORITHM_H
#define BT_COLLISION_ALGORITHM_H
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
@@ -44,7 +44,7 @@ struct btCollisionAlgorithmConstructionInfo
btDispatcher* m_dispatcher1;
btPersistentManifold* m_manifold;
int getDispatcherId();
// int getDispatcherId();
};
@@ -59,7 +59,7 @@ protected:
btDispatcher* m_dispatcher;
protected:
int getDispatcherId();
// int getDispatcherId();
public:
@@ -77,4 +77,4 @@ public:
};
#endif //COLLISION_ALGORITHM_H
#endif //BT_COLLISION_ALGORITHM_H

View File

@@ -13,9 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
#ifndef BT_DISPATCHER_H
#define BT_DISPATCHER_H
#include "LinearMath/btScalar.h"
class btCollisionAlgorithm;
@@ -27,6 +26,7 @@ class btOverlappingPairCache;
class btPersistentManifold;
class btStackAlloc;
class btPoolAllocator;
struct btDispatcherInfo
{
@@ -40,7 +40,7 @@ struct btDispatcherInfo
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_useContinuous(true),
m_debugDraw(0),
m_enableSatConvex(false),
m_enableSPU(true),
@@ -48,7 +48,6 @@ struct btDispatcherInfo
m_allowedCcdPenetration(btScalar(0.04)),
m_useConvexConservativeDistanceUtil(false),
m_convexConservativeDistanceThreshold(0.0f),
m_convexMaxDistanceUseCPT(false),
m_stackAllocator(0)
{
@@ -65,7 +64,6 @@ struct btDispatcherInfo
btScalar m_allowedCcdPenetration;
bool m_useConvexConservativeDistanceUtil;
btScalar m_convexConservativeDistanceThreshold;
bool m_convexMaxDistanceUseCPT;
btStackAlloc* m_stackAllocator;
};
@@ -98,6 +96,10 @@ public:
virtual btPersistentManifold** getInternalManifoldPointer() = 0;
virtual btPoolAllocator* getInternalManifoldPool() = 0;
virtual const btPoolAllocator* getInternalManifoldPool() const = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void freeCollisionAlgorithm(void* ptr) = 0;
@@ -105,4 +107,4 @@ public:
};
#endif //_DISPATCHER_H
#endif //BT_DISPATCHER_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OVERLAPPING_PAIR_CACHE_H
#define OVERLAPPING_PAIR_CACHE_H
#ifndef BT_OVERLAPPING_PAIR_CACHE_H
#define BT_OVERLAPPING_PAIR_CACHE_H
#include "btBroadphaseInterface.h"
@@ -464,6 +464,6 @@ public:
};
#endif //OVERLAPPING_PAIR_CACHE_H
#endif //BT_OVERLAPPING_PAIR_CACHE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef QUANTIZED_BVH_H
#define QUANTIZED_BVH_H
#ifndef BT_QUANTIZED_BVH_H
#define BT_QUANTIZED_BVH_H
class btSerializer;
@@ -107,9 +107,9 @@ ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
//for child nodes
int m_subPart;
int m_triangleIndex;
int m_padding[5];//bad, due to alignment
//pad the size to 64 bytes
char m_padding[20];
};
@@ -576,4 +576,4 @@ SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const
#endif //QUANTIZED_BVH_H
#endif //BT_QUANTIZED_BVH_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SIMPLE_BROADPHASE_H
#define SIMPLE_BROADPHASE_H
#ifndef BT_SIMPLE_BROADPHASE_H
#define BT_SIMPLE_BROADPHASE_H
#include "btOverlappingPairCache.h"
@@ -167,5 +167,5 @@ public:
#endif //SIMPLE_BROADPHASE_H
#endif //BT_SIMPLE_BROADPHASE_H

View File

@@ -57,8 +57,6 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
}
#define MAX_OVERLAP btScalar(0.)
// See also geometrictools.com
@@ -93,48 +91,39 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
return pointInTriangle(vertices, lnormal, &lp);
}
///combined discrete/continuous sphere-triangle
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
{
const btVector3* vertices = &m_triangle->getVertexPtr(0);
const btVector3& c = sphereCenter;
btScalar r = m_sphere->getRadius();
btVector3 delta (0,0,0);
btScalar radius = m_sphere->getRadius();
btScalar radiusWithThreshold = radius + contactBreakingThreshold;
btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
normal.normalize();
btVector3 p1ToCentre = c - vertices[0];
btVector3 p1ToCentre = sphereCenter - vertices[0];
btScalar distanceFromPlane = p1ToCentre.dot(normal);
if (distanceFromPlane < btScalar(0.))
{
//triangle facing the other way
distanceFromPlane *= btScalar(-1.);
normal *= btScalar(-1.);
}
btScalar contactMargin = contactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;
btScalar deltaDotNormal = delta.dot(normal);
if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0))
return false;
// Check for contact / intersection
bool hasContact = false;
btVector3 contactPoint;
if (isInsideContactPlane) {
if (facecontains(c,vertices,normal)) {
if (facecontains(sphereCenter,vertices,normal)) {
// Inside the contact wedge - touches a point on the shell plane
hasContact = true;
contactPoint = c - normal*distanceFromPlane;
contactPoint = sphereCenter - normal*distanceFromPlane;
} else {
// Could be inside one of the contact capsules
btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;
btVector3 nearestOnEdge;
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
@@ -143,7 +132,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
m_triangle->getEdge(i,pa,pb);
btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
btScalar distanceSqr = SegmentSqrDistance(pa,pb,sphereCenter, nearestOnEdge);
if (distanceSqr < contactCapsuleRadiusSqr) {
// Yep, we're inside a capsule
hasContact = true;
@@ -155,24 +144,27 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
}
if (hasContact) {
btVector3 contactToCentre = c - contactPoint;
btVector3 contactToCentre = sphereCenter - contactPoint;
btScalar distanceSqr = contactToCentre.length2();
if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) {
btScalar distance = btSqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal.normalize();
point = contactPoint;
depth = -(r-distance);
if (distanceSqr < radiusWithThreshold*radiusWithThreshold)
{
if (distanceSqr>SIMD_EPSILON)
{
btScalar distance = btSqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal.normalize();
point = contactPoint;
depth = -(radius-distance);
} else
{
btScalar distance = 0.f;
resultNormal = normal;
point = contactPoint;
depth = -radius;
}
return true;
}
if (delta.dot(contactToCentre) >= btScalar(0.0))
return false;
// Moving towards the contact point -> collision
point = contactPoint;
timeOfImpact = btScalar(0.0);
return true;
}
return false;

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
#ifndef BT_SPHERE_TRIANGLE_DETECTOR_H
#define BT_SPHERE_TRIANGLE_DETECTOR_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
@@ -47,5 +47,5 @@ private:
btScalar m_contactBreakingThreshold;
};
#endif //SPHERE_TRIANGLE_DETECTOR_H
#endif //BT_SPHERE_TRIANGLE_DETECTOR_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#define BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#ifndef BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#define BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -62,5 +62,5 @@ public:
};
#endif //BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#endif //BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_BOX__COLLISION_ALGORITHM_H
#define BOX_BOX__COLLISION_ALGORITHM_H
#ifndef BT_BOX_BOX__COLLISION_ALGORITHM_H
#define BT_BOX_BOX__COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -62,5 +62,5 @@ public:
};
#endif //BOX_BOX__COLLISION_ALGORITHM_H
#endif //BT_BOX_BOX__COLLISION_ALGORITHM_H

View File

@@ -16,8 +16,8 @@ subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_BOX_DETECTOR_H
#define BOX_BOX_DETECTOR_H
#ifndef BT_BOX_BOX_DETECTOR_H
#define BT_BOX_BOX_DETECTOR_H
class btBoxShape;

View File

@@ -15,6 +15,7 @@ subject to the following restrictions:
#ifndef BT_COLLISION_CONFIGURATION
#define BT_COLLISION_CONFIGURATION
struct btCollisionAlgorithmCreateFunc;
class btStackAlloc;

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_CREATE_FUNC
#define COLLISION_CREATE_FUNC
#ifndef BT_COLLISION_CREATE_FUNC
#define BT_COLLISION_CREATE_FUNC
#include "LinearMath/btAlignedObjectArray.h"
class btCollisionAlgorithm;
@@ -41,5 +41,5 @@ struct btCollisionAlgorithmCreateFunc
return 0;
}
};
#endif //COLLISION_CREATE_FUNC
#endif //BT_COLLISION_CREATE_FUNC

View File

@@ -92,8 +92,16 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
} else
{
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
//we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
if ((m_dispatcherFlags&CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION)==0)
{
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
} else
{
btAssert(0);
//make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration
return 0;
}
}
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
manifold->m_index1a = m_manifoldsPtr.size();
@@ -172,8 +180,7 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
if (!(m_dispatcherFlags & btCollisionDispatcher::CD_STATIC_STATIC_REPORTED))
{
//broadphase filtering already deals with this
if ((body0->isStaticObject() || body0->isKinematicObject()) &&
(body1->isStaticObject() || body1->isKinematicObject()))
if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject())
{
m_dispatcherFlags |= btCollisionDispatcher::CD_STATIC_STATIC_REPORTED;
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
#ifndef BT_COLLISION__DISPATCHER_H
#define BT_COLLISION__DISPATCHER_H
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@@ -42,8 +42,11 @@ typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispa
///Time of Impact, Closest Points and Penetration Depth.
class btCollisionDispatcher : public btDispatcher
{
protected:
int m_dispatcherFlags;
btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
btManifoldResult m_defaultManifoldResult;
@@ -64,7 +67,8 @@ public:
enum DispatcherFlags
{
CD_STATIC_STATIC_REPORTED = 1,
CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2
CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2,
CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION = 4
};
int getDispatcherFlags() const
@@ -74,8 +78,7 @@ public:
void setDispatcherFlags(int flags)
{
(void) flags;
m_dispatcherFlags = 0;
m_dispatcherFlags = flags;
}
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
@@ -153,7 +156,17 @@ public:
m_collisionConfiguration = config;
}
virtual btPoolAllocator* getInternalManifoldPool()
{
return m_persistentManifoldPoolAllocator;
}
virtual const btPoolAllocator* getInternalManifoldPool() const
{
return m_persistentManifoldPoolAllocator;
}
};
#endif //COLLISION__DISPATCHER_H
#endif //BT_COLLISION__DISPATCHER_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
#ifndef BT_COLLISION_OBJECT_H
#define BT_COLLISION_OBJECT_H
#include "LinearMath/btTransform.h"
@@ -521,4 +521,4 @@ SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const
#endif //COLLISION_OBJECT_H
#endif //BT_COLLISION_OBJECT_H

View File

@@ -28,10 +28,15 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btAabbUtil2.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btSerializer.h"
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
//#define USE_BRUTEFORCE_RAYBROADPHASE 1
//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
@@ -150,6 +155,16 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
minAabb -= contactThreshold;
maxAabb += contactThreshold;
if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
{
btVector3 minAabb2,maxAabb2;
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
}
btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
//moving objects should be moderately sized, probably something wrong if not
@@ -420,51 +435,117 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
} else {
// BT_PROFILE("rayTestCompound");
///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
if (collisionShape->isCompound())
{
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
struct LocalInfoAdder2 : public RayResultCallback
{
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
// replace collision shape so that callback can determine the triangle
btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
struct LocalInfoAdder2 : public RayResultCallback {
RayResultCallback* m_userCallback;
int m_i;
LocalInfoAdder2 (int i, RayResultCallback *user)
: m_userCallback(user),
m_i(i)
{
m_closestHitFraction = m_userCallback->m_closestHitFraction;
}
virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = -1;
shapeInfo.m_triangleIndex = m_i;
if (r.m_localShapeInfo == NULL)
r.m_localShapeInfo = &shapeInfo;
RayResultCallback* m_userCallback;
int m_i;
LocalInfoAdder2 (int i, RayResultCallback *user)
: m_userCallback(user), m_i(i)
{
m_closestHitFraction = m_userCallback->m_closestHitFraction;
}
virtual bool needsCollision(btBroadphaseProxy* p) const
{
return m_userCallback->needsCollision(p);
}
const btScalar result = m_userCallback->addSingleResult(r, b);
m_closestHitFraction = m_userCallback->m_closestHitFraction;
return result;
}
};
virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = -1;
shapeInfo.m_triangleIndex = m_i;
if (r.m_localShapeInfo == NULL)
r.m_localShapeInfo = &shapeInfo;
LocalInfoAdder2 my_cb(i, &resultCallback);
const btScalar result = m_userCallback->addSingleResult(r, b);
m_closestHitFraction = m_userCallback->m_closestHitFraction;
return result;
}
};
struct RayTester : btDbvt::ICollide
{
btCollisionObject* m_collisionObject;
const btCompoundShape* m_compoundShape;
const btTransform& m_colObjWorldTransform;
const btTransform& m_rayFromTrans;
const btTransform& m_rayToTrans;
RayResultCallback& m_resultCallback;
RayTester(btCollisionObject* collisionObject,
const btCompoundShape* compoundShape,
const btTransform& colObjWorldTransform,
const btTransform& rayFromTrans,
const btTransform& rayToTrans,
RayResultCallback& resultCallback):
m_collisionObject(collisionObject),
m_compoundShape(compoundShape),
m_colObjWorldTransform(colObjWorldTransform),
m_rayFromTrans(rayFromTrans),
m_rayToTrans(rayToTrans),
m_resultCallback(resultCallback)
{
}
void Process(int i)
{
const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
const btTransform& childTrans = m_compoundShape->getChildTransform(i);
btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
// replace collision shape so that callback can determine the triangle
btCollisionShape* saveCollisionShape = m_collisionObject->getCollisionShape();
m_collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
rayTestSingle(rayFromTrans,rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
my_cb);
// restore
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
LocalInfoAdder2 my_cb(i, &m_resultCallback);
rayTestSingle(
m_rayFromTrans,
m_rayToTrans,
m_collisionObject,
childCollisionShape,
childWorldTrans,
my_cb);
// restore
m_collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
}
void Process(const btDbvtNode* leaf)
{
Process(leaf->dataAsInt);
}
};
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
RayTester rayCB(
collisionObject,
compoundShape,
colObjWorldTransform,
rayFromTrans,
rayToTrans,
resultCallback);
#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
if (dbvt)
{
btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
}
else
#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
{
for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
{
rayCB.Process(i);
}
}
}
}
@@ -576,72 +657,109 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
tccb.m_allowedPenetration = allowedPenetration;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
} else
{
//BT_PROFILE("convexSweepConcave");
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btConcaveShape* m_triangleMesh;
btConvexCast::CastResult castResult;
castResult.m_allowedPenetration = allowedPenetration;
castResult.m_fraction = resultCallback.m_closestHitFraction;
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
btContinuousConvexCollision convexCaster1(castShape,planeShape);
btConvexCast* castPtr = &convexCaster1;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
if (hitFraction <= m_resultCallback->m_closestHitFraction)
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
castResult.m_normal.normalize();
btCollisionWorld::LocalConvexResult localConvexResult
(
collisionObject,
0,
castResult.m_normal,
castResult.m_hitPoint,
castResult.m_fraction
);
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
bool normalInWorldSpace = true;
resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
}
}
return hitFraction;
}
};
} else
{
//BT_PROFILE("convexSweepConcave");
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btConcaveShape* m_triangleMesh;
btVector3 rayAabbMinLocal = convexFromLocal;
rayAabbMinLocal.setMin(convexToLocal);
btVector3 rayAabbMaxLocal = convexFromLocal;
rayAabbMaxLocal.setMax(convexToLocal);
rayAabbMinLocal += boxMinLocal;
rayAabbMaxLocal += boxMaxLocal;
concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
if (hitFraction <= m_resultCallback->m_closestHitFraction)
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
}
return hitFraction;
}
};
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
tccb.m_allowedPenetration = allowedPenetration;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
btVector3 rayAabbMinLocal = convexFromLocal;
rayAabbMinLocal.setMin(convexToLocal);
btVector3 rayAabbMaxLocal = convexFromLocal;
rayAabbMaxLocal.setMax(convexToLocal);
rayAabbMinLocal += boxMinLocal;
rayAabbMaxLocal += boxMaxLocal;
concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
}
}
} else {
///@todo : use AABB tree or other BVH acceleration structure!
@@ -667,6 +785,10 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
m_closestHitFraction = m_userCallback->m_closestHitFraction;
}
virtual bool needsCollision(btBroadphaseProxy* p) const
{
return m_userCallback->needsCollision(p);
}
virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b)
{
btCollisionWorld::LocalShapeInfo shapeInfo;
@@ -1109,215 +1231,164 @@ void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const
} else
{
switch (shape->getShapeType())
/// for polyhedral shapes
if (shape->isPolyhedral())
{
btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
case BOX_SHAPE_PROXYTYPE:
int i;
if (polyshape->getConvexPolyhedron())
{
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
break;
}
case SPHERE_SHAPE_PROXYTYPE:
{
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
getDebugDrawer()->drawSphere(radius, worldTransform, color);
break;
}
case MULTI_SPHERE_SHAPE_PROXYTYPE:
{
const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
btTransform childTransform;
childTransform.setIdentity();
for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
for (i=0;i<poly->m_faces.size();i++)
{
childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
}
break;
}
case CAPSULE_SHAPE_PROXYTYPE:
{
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
btScalar radius = capsuleShape->getRadius();
btScalar halfHeight = capsuleShape->getHalfHeight();
int upAxis = capsuleShape->getUpAxis();
btVector3 capStart(0.f,0.f,0.f);
capStart[upAxis] = -halfHeight;
btVector3 capEnd(0.f,0.f,0.f);
capEnd[upAxis] = halfHeight;
// Draw the ends
{
btTransform childTransform = worldTransform;
childTransform.getOrigin() = worldTransform * capStart;
getDebugDrawer()->drawSphere(radius, childTransform, color);
}
{
btTransform childTransform = worldTransform;
childTransform.getOrigin() = worldTransform * capEnd;
getDebugDrawer()->drawSphere(radius, childTransform, color);
}
// Draw some additional lines
btVector3 start = worldTransform.getOrigin();
capStart[(upAxis+1)%3] = radius;
capEnd[(upAxis+1)%3] = radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
capStart[(upAxis+1)%3] = -radius;
capEnd[(upAxis+1)%3] = -radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
capStart[(upAxis+1)%3] = 0.f;
capEnd[(upAxis+1)%3] = 0.f;
capStart[(upAxis+2)%3] = radius;
capEnd[(upAxis+2)%3] = radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
capStart[(upAxis+2)%3] = -radius;
capEnd[(upAxis+2)%3] = -radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
break;
}
case CONE_SHAPE_PROXYTYPE:
{
const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
btScalar height = coneShape->getHeight();//+coneShape->getMargin();
btVector3 start = worldTransform.getOrigin();
int upAxis= coneShape->getConeUpIndex();
btVector3 offsetHeight(0,0,0);
offsetHeight[upAxis] = height * btScalar(0.5);
btVector3 offsetRadius(0,0,0);
offsetRadius[(upAxis+1)%3] = radius;
btVector3 offset2Radius(0,0,0);
offset2Radius[(upAxis+2)%3] = radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color);
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color);
// Drawing the base of the cone
btVector3 yaxis(0,0,0);
yaxis[upAxis] = btScalar(1.0);
btVector3 xaxis(0,0,0);
xaxis[(upAxis+1)%3] = btScalar(1.0);
getDebugDrawer()->drawArc(start-worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0);
break;
}
case CYLINDER_SHAPE_PROXYTYPE:
{
const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
int upAxis = cylinder->getUpAxis();
btScalar radius = cylinder->getRadius();
btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
btVector3 start = worldTransform.getOrigin();
btVector3 offsetHeight(0,0,0);
offsetHeight[upAxis] = halfHeight;
btVector3 offsetRadius(0,0,0);
offsetRadius[(upAxis+1)%3] = radius;
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
// Drawing top and bottom caps of the cylinder
btVector3 yaxis(0,0,0);
yaxis[upAxis] = btScalar(1.0);
btVector3 xaxis(0,0,0);
xaxis[(upAxis+1)%3] = btScalar(1.0);
getDebugDrawer()->drawArc(start-worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
getDebugDrawer()->drawArc(start+worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
break;
}
case STATIC_PLANE_PROXYTYPE:
{
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
btScalar planeConst = staticPlaneShape->getPlaneConstant();
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
btVector3 planeOrigin = planeNormal * planeConst;
btVector3 vec0,vec1;
btPlaneSpace1(planeNormal,vec0,vec1);
btScalar vecLen = 100.f;
btVector3 pt0 = planeOrigin + vec0*vecLen;
btVector3 pt1 = planeOrigin - vec0*vecLen;
btVector3 pt2 = planeOrigin + vec1*vecLen;
btVector3 pt3 = planeOrigin - vec1*vecLen;
getDebugDrawer()->drawLine(worldTransform*pt0,worldTransform*pt1,color);
getDebugDrawer()->drawLine(worldTransform*pt2,worldTransform*pt3,color);
break;
}
default:
{
if (shape->isConcave())
{
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
///@todo pass camera, for some culling? no -> we are not a graphics lib
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
}
if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
{
btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
//todo: pass camera for some culling
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
//DebugDrawcallback drawCallback;
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
}
/// for polyhedral shapes
if (shape->isPolyhedral())
{
btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
int i;
for (i=0;i<polyshape->getNumEdges();i++)
btVector3 centroid(0,0,0);
int numVerts = poly->m_faces[i].m_indices.size();
if (numVerts)
{
btVector3 a,b;
polyshape->getEdge(i,a,b);
btVector3 wa = worldTransform * a;
btVector3 wb = worldTransform * b;
getDebugDrawer()->drawLine(wa,wb,color);
int lastV = poly->m_faces[i].m_indices[numVerts-1];
for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
{
int curVert = poly->m_faces[i].m_indices[v];
centroid+=poly->m_vertices[curVert];
getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
lastV = curVert;
}
}
centroid*= btScalar(1.f)/btScalar(numVerts);
btVector3 normalColor(1,1,0);
btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
//getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
}
} else
{
for (i=0;i<polyshape->getNumEdges();i++)
{
btVector3 a,b;
polyshape->getEdge(i,a,b);
btVector3 wa = worldTransform * a;
btVector3 wb = worldTransform * b;
getDebugDrawer()->drawLine(wa,wb,color);
}
}
}
else
{
switch (shape->getShapeType())
{
case BOX_SHAPE_PROXYTYPE:
{
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
break;
}
case SPHERE_SHAPE_PROXYTYPE:
{
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
getDebugDrawer()->drawSphere(radius, worldTransform, color);
break;
}
case MULTI_SPHERE_SHAPE_PROXYTYPE:
{
const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
btTransform childTransform;
childTransform.setIdentity();
for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
{
childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
}
break;
}
case CAPSULE_SHAPE_PROXYTYPE:
{
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
btScalar radius = capsuleShape->getRadius();
btScalar halfHeight = capsuleShape->getHalfHeight();
int upAxis = capsuleShape->getUpAxis();
getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
break;
}
case CONE_SHAPE_PROXYTYPE:
{
const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
btScalar height = coneShape->getHeight();//+coneShape->getMargin();
int upAxis= coneShape->getConeUpIndex();
getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
break;
}
case CYLINDER_SHAPE_PROXYTYPE:
{
const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
int upAxis = cylinder->getUpAxis();
btScalar radius = cylinder->getRadius();
btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
break;
}
case STATIC_PLANE_PROXYTYPE:
{
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
btScalar planeConst = staticPlaneShape->getPlaneConstant();
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
break;
}
default:
{
if (shape->isConcave())
{
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
///@todo pass camera, for some culling? no -> we are not a graphics lib
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
}
if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
{
btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
//todo: pass camera for some culling
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
//DebugDrawcallback drawCallback;
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
}
}
}
}
}
}
}
@@ -1343,7 +1414,7 @@ void btCollisionWorld::debugDrawWorld()
}
}
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
{
int i;
@@ -1352,7 +1423,7 @@ void btCollisionWorld::debugDrawWorld()
btCollisionObject* colObj = m_collisionObjects[i];
if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
{
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
{
btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
switch(colObj->getActivationState())
@@ -1380,6 +1451,21 @@ void btCollisionWorld::debugDrawWorld()
btVector3 minAabb,maxAabb;
btVector3 colorvec(1,0,0);
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
minAabb -= contactThreshold;
maxAabb += contactThreshold;
btVector3 minAabb2,maxAabb2;
if(colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
{
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
}
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
}
}

View File

@@ -62,8 +62,8 @@ subject to the following restrictions:
#ifndef COLLISION_WORLD_H
#define COLLISION_WORLD_H
#ifndef BT_COLLISION_WORLD_H
#define BT_COLLISION_WORLD_H
class btStackAlloc;
class btCollisionShape;
@@ -506,4 +506,4 @@ public:
};
#endif //COLLISION_WORLD_H
#endif //BT_COLLISION_WORLD_H

View File

@@ -234,7 +234,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
resultOut->setPersistentManifold(0);//??necessary?
}
}
manifoldArray.clear();
manifoldArray.resize(0);
}
}
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
#ifndef BT_COMPOUND_COLLISION_ALGORITHM_H
#define BT_COMPOUND_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
@@ -83,4 +83,4 @@ public:
};
#endif //COMPOUND_COLLISION_ALGORITHM_H
#endif //BT_COMPOUND_COLLISION_ALGORITHM_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_2D_CONVEX_2D_ALGORITHM_H
#define CONVEX_2D_CONVEX_2D_ALGORITHM_H
#ifndef BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H
#define BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@@ -92,4 +92,4 @@ public:
};
#endif //CONVEX_2D_CONVEX_2D_ALGORITHM_H
#endif //BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H

View File

@@ -91,7 +91,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
#if 0
///debug drawing of the overlapping triangles
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
{
@@ -100,17 +100,8 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
//btVector3 center = triangle[0] + triangle[1]+triangle[2];
//center *= btScalar(0.333333);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
}
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
#endif
if (m_convexBody->getCollisionShape()->isConvex())
{
@@ -119,7 +110,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionShape* tmpShape = ob->getCollisionShape();
ob->internalSetTemporaryCollisionShape( &tm );
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
if (m_resultOut->getBody0Internal() == m_triBody)

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#ifndef BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
@@ -113,4 +113,4 @@ public:
};
#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#endif //BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H

View File

@@ -17,6 +17,7 @@ subject to the following restrictions:
///If you experience problems with capsule-capsule collision, try to define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER and report it in the Bullet forums
///with reproduction case
//define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1
//#define ZERO_MARGIN
#include "btConvexConvexAlgorithm.h"
@@ -26,6 +27,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@@ -48,7 +51,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
///////////
@@ -331,6 +334,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
#ifdef USE_SEPDISTANCE_UTIL2
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
{
@@ -357,13 +362,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
} else
#endif //USE_SEPDISTANCE_UTIL2
{
if (dispatchInfo.m_convexMaxDistanceUseCPT)
{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
} else
{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
}
//if (dispatchInfo.m_convexMaxDistanceUseCPT)
//{
// input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
//} else
//{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
// }
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
}
@@ -371,7 +377,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
@@ -389,6 +395,155 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
#endif //USE_SEPDISTANCE_UTIL2
if (min0->isPolyhedral() && min1->isPolyhedral())
{
struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result
{
virtual void setShapeIdentifiersA(int partId0,int index0){}
virtual void setShapeIdentifiersB(int partId1,int index1){}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
}
};
btDummyResult dummy;
btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0;
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
{
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar minDist = -1e30f;
btVector3 sepNormalWorldSpace;
bool foundSepAxis = true;
if (dispatchInfo.m_enableSatConvex)
{
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(),
sepNormalWorldSpace);
} else
{
#ifdef ZERO_MARGIN
gjkPairDetector.setIgnoreMargin(true);
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#else
//gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
#endif //ZERO_MARGIN
btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
if (l2>SIMD_EPSILON)
{
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
//minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance();
minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
#ifdef ZERO_MARGIN
foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f;
#else
foundSepAxis = gjkPairDetector.getCachedSeparatingDistance()<(min0->getMargin()+min1->getMargin());
#endif
}
}
if (foundSepAxis)
{
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(), minDist-threshold, threshold, *resultOut);
}
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
} else
{
//we can also deal with convex versus triangle (without connectivity data)
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE)
{
btVertexArray vertices;
btTriangleShape* tri = (btTriangleShape*)polyhedronB;
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[0]);
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[1]);
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[2]);
//tri->initializePolyhedralFeatures();
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btVector3 sepNormalWorldSpace;
btScalar minDist =-1e30f;
btScalar maxDist = threshold;
bool foundSepAxis = false;
if (0)
{
polyhedronB->initializePolyhedralFeatures();
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(),
sepNormalWorldSpace);
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
} else
{
#ifdef ZERO_MARGIN
gjkPairDetector.setIgnoreMargin(true);
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#else
gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
#endif//ZERO_MARGIN
btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
if (l2>SIMD_EPSILON)
{
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
//minDist = gjkPairDetector.getCachedSeparatingDistance();
//maxDist = threshold;
minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
foundSepAxis = true;
}
}
if (foundSepAxis)
{
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
body0->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
}
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
}
}
}
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
@@ -398,66 +553,70 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
int i;
btVector3 v0,v1;
btVector3 sepNormalWorldSpace;
btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
btPlaneSpace1(sepNormalWorldSpace,v0,v1);
bool perturbeA = true;
const btScalar angleLimit = 0.125f * SIMD_PI;
btScalar perturbeAngle;
btScalar radiusA = min0->getAngularMotionDisc();
btScalar radiusB = min1->getAngularMotionDisc();
if (radiusA < radiusB)
if (l2>SIMD_EPSILON)
{
perturbeAngle = gContactBreakingThreshold /radiusA;
perturbeA = true;
} else
{
perturbeAngle = gContactBreakingThreshold / radiusB;
perturbeA = false;
}
if ( perturbeAngle > angleLimit )
perturbeAngle = angleLimit;
btTransform unPerturbedTransform;
if (perturbeA)
{
unPerturbedTransform = input.m_transformA;
} else
{
unPerturbedTransform = input.m_transformB;
}
for ( i=0;i<m_numPerturbationIterations;i++)
{
if (v0.length2()>SIMD_EPSILON)
{
btQuaternion perturbeRot(v0,perturbeAngle);
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
if (perturbeA)
btPlaneSpace1(sepNormalWorldSpace,v0,v1);
bool perturbeA = true;
const btScalar angleLimit = 0.125f * SIMD_PI;
btScalar perturbeAngle;
btScalar radiusA = min0->getAngularMotionDisc();
btScalar radiusB = min1->getAngularMotionDisc();
if (radiusA < radiusB)
{
input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
input.m_transformB = body1->getWorldTransform();
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
#endif //DEBUG_CONTACTS
perturbeAngle = gContactBreakingThreshold /radiusA;
perturbeA = true;
} else
{
input.m_transformA = body0->getWorldTransform();
input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
perturbeAngle = gContactBreakingThreshold / radiusB;
perturbeA = false;
}
if ( perturbeAngle > angleLimit )
perturbeAngle = angleLimit;
btTransform unPerturbedTransform;
if (perturbeA)
{
unPerturbedTransform = input.m_transformA;
} else
{
unPerturbedTransform = input.m_transformB;
}
btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
for ( i=0;i<m_numPerturbationIterations;i++)
{
if (v0.length2()>SIMD_EPSILON)
{
btQuaternion perturbeRot(v0,perturbeAngle);
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
if (perturbeA)
{
input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
input.m_transformB = body1->getWorldTransform();
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
#endif //DEBUG_CONTACTS
} else
{
input.m_transformA = body0->getWorldTransform();
input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
}
btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
}
}
}
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
#ifndef BT_CONVEX_CONVEX_ALGORITHM_H
#define BT_CONVEX_CONVEX_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@@ -106,4 +106,4 @@ public:
};
#endif //CONVEX_CONVEX_ALGORITHM_H
#endif //BT_CONVEX_CONVEX_ALGORITHM_H

View File

@@ -96,23 +96,41 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
if (!m_manifoldPtr)
return;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
//const btScalar& planeConstant = planeShape->getPlaneConstant();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform planeInConvex;
planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform();
btTransform convexInPlaneTrans;
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform();
//first perform a collision query with the non-perturbated collision objects
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
btQuaternion rotq(0,0,0,1);
collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
/// report a contact. internally this will be kept persistent, and contact reduction is done
btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
//the perturbation algorithm doesn't work well with implicit surfaces such as spheres, cylinder and cones:
//they keep on rolling forever because of the additional off-center contact points
//so only enable the feature for polyhedral shapes (btBoxShape, btConvexHullShape etc)
if (convexShape->isPolyhedral() && resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
{
btVector3 v0,v1;
btPlaneSpace1(planeNormal,v0,v1);

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_PLANE_COLLISION_ALGORITHM_H
#define CONVEX_PLANE_COLLISION_ALGORITHM_H
#ifndef BT_CONVEX_PLANE_COLLISION_ALGORITHM_H
#define BT_CONVEX_PLANE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -61,7 +61,7 @@ public:
CreateFunc()
: m_numPerturbationIterations(1),
m_minimumPointsPerturbationThreshold(1)
m_minimumPointsPerturbationThreshold(0)
{
}
@@ -80,5 +80,5 @@ public:
};
#endif //CONVEX_PLANE_COLLISION_ALGORITHM_H
#endif //BT_CONVEX_PLANE_COLLISION_ALGORITHM_H

View File

@@ -296,3 +296,10 @@ void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int nu
convexConvex->m_numPerturbationIterations = numPerturbationIterations;
convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}
void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
{
btConvexPlaneCollisionAlgorithm::CreateFunc* planeCreateFunc = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_planeConvexCF;
planeCreateFunc->m_numPerturbationIterations = numPerturbationIterations;
planeCreateFunc->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}

View File

@@ -129,6 +129,8 @@ public:
///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
void setPlaneConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
};
#endif //BT_DEFAULT_COLLISION_CONFIGURATION

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EMPTY_ALGORITH
#define EMPTY_ALGORITH
#ifndef BT_EMPTY_ALGORITH
#define BT_EMPTY_ALGORITH
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
@@ -51,4 +51,4 @@ public:
} ATTRIBUTE_ALIGNED(16);
#endif //EMPTY_ALGORITH
#endif //BT_EMPTY_ALGORITH

View File

@@ -1,6 +1,7 @@
#include "btInternalEdgeUtility.h"
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
@@ -9,7 +10,6 @@
//#define DEBUG_INTERNAL_EDGE
#ifdef DEBUG_INTERNAL_EDGE
#include <stdio.h>
#endif //DEBUG_INTERNAL_EDGE
@@ -456,8 +456,14 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
return;
btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)colObj0->getRootCollisionShape();
btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
btBvhTriangleMeshShape* trimesh = 0;
if( colObj0->getRootCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE )
trimesh = ((btScaledBvhTriangleMeshShape*)colObj0->getRootCollisionShape())->getChildShape();
else
trimesh = (btBvhTriangleMeshShape*)colObj0->getRootCollisionShape();
btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
if (!triangleInfoMapPtr)
return;
@@ -501,14 +507,63 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
localContactNormalOnB.normalize();//is this necessary?
if ((info->m_edgeV0V1Angle)< SIMD_2_PI)
// Get closest edge
int bestedge=-1;
float disttobestedge=BT_LARGE_FLOAT;
//
// Edge 0 -> 1
if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v0, v1, nearest );
float len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=0;
disttobestedge=len;
}
}
// Edge 1 -> 2
if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v1, v2, nearest );
float len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=1;
disttobestedge=len;
}
}
// Edge 2 -> 0
if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v2, v0, nearest );
float len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=2;
disttobestedge=len;
}
}
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 upfix=tri_normal * btVector3(0.1f,0.1f,0.1f);
btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red );
#endif
if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
#endif
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==0 )
{
btVector3 edge(v0-v1);
isNearEdge = true;
@@ -577,7 +632,11 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
if ((info->m_edgeV1V2Angle)< SIMD_2_PI)
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix , green );
#endif
if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
@@ -587,6 +646,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==1 )
{
isNearEdge = true;
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
@@ -658,8 +718,11 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix , blue );
#endif
if ((info->m_edgeV2V0Angle)< SIMD_2_PI)
if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
@@ -668,6 +731,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==2 )
{
isNearEdge = true;
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
@@ -759,11 +823,17 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal;
} else
{
btVector3 newNormal = tri_normal *frontFacing;
//if the tri_normal is pointing opposite direction as the current local contact normal, skip it
btScalar d = newNormal.dot(localContactNormalOnB) ;
if (d< 0)
{
return;
}
//modify the normal to be the triangle normal (or backfacing normal)
cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *(tri_normal *frontFacing);
cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *newNormal;
}
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);

View File

@@ -63,8 +63,9 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
{
btAssert(m_manifoldPtr);
//order in manifold needs to match
if (depth > m_manifoldPtr->getContactBreakingThreshold())
// if (depth > m_manifoldPtr->getContactProcessingThreshold())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;

View File

@@ -14,8 +14,8 @@ subject to the following restrictions:
*/
#ifndef MANIFOLD_RESULT_H
#define MANIFOLD_RESULT_H
#ifndef BT_MANIFOLD_RESULT_H
#define BT_MANIFOLD_RESULT_H
class btCollisionObject;
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@@ -125,4 +125,4 @@ public:
};
#endif //MANIFOLD_RESULT_H
#endif //BT_MANIFOLD_RESULT_H

View File

@@ -47,6 +47,8 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
{
btOverlappingPairCache* pairCachePtr = colWorld->getPairCache();
const int numOverlappingPairs = pairCachePtr->getNumOverlappingPairs();
if (numOverlappingPairs)
{
btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr();
for (int i=0;i<numOverlappingPairs;i++)
@@ -63,6 +65,7 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
(colObj1)->getIslandTag());
}
}
}
}
}
@@ -392,15 +395,15 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
bool islandSleeping = false;
bool islandSleeping = true;
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
{
int i = getUnionFind().getElement(endIslandIndex).m_sz;
btCollisionObject* colObj0 = collisionObjects[i];
m_islandBodies.push_back(colObj0);
if (!colObj0->isActive())
islandSleeping = true;
if (colObj0->isActive())
islandSleeping = false;
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SIMULATION_ISLAND_MANAGER_H
#define SIMULATION_ISLAND_MANAGER_H
#ifndef BT_SIMULATION_ISLAND_MANAGER_H
#define BT_SIMULATION_ISLAND_MANAGER_H
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
@@ -77,5 +77,5 @@ public:
};
#endif //SIMULATION_ISLAND_MANAGER_H
#endif //BT_SIMULATION_ISLAND_MANAGER_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_BOX_COLLISION_ALGORITHM_H
#define BT_SPHERE_BOX_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -71,5 +71,5 @@ public:
};
#endif //SPHERE_BOX_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_BOX_COLLISION_ALGORITHM_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -62,5 +62,5 @@ public:
};
#endif //SPHERE_SPHERE_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -65,5 +65,5 @@ public:
};
#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef UNION_FIND_H
#define UNION_FIND_H
#ifndef BT_UNION_FIND_H
#define BT_UNION_FIND_H
#include "LinearMath/btAlignedObjectArray.h"
@@ -126,4 +126,4 @@ class btUnionFind
};
#endif //UNION_FIND_H
#endif //BT_UNION_FIND_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OBB_BOX_2D_SHAPE_H
#define OBB_BOX_2D_SHAPE_H
#ifndef BT_OBB_BOX_2D_SHAPE_H
#define BT_OBB_BOX_2D_SHAPE_H
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -83,6 +83,7 @@ public:
}
///a btBox2dShape is a flat 2D box in the X-Y plane (Z extents are zero)
btBox2dShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape(),
m_centroid(0,0,0)
@@ -97,6 +98,11 @@ public:
m_normals[2].setValue(0,1,0);
m_normals[3].setValue(-1,0,0);
btScalar minDimension = boxHalfExtents.getX();
if (minDimension>boxHalfExtents.getY())
minDimension = boxHalfExtents.getY();
setSafeMargin(minDimension);
m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
@@ -358,6 +364,6 @@ public:
};
#endif //OBB_BOX_2D_SHAPE_H
#endif //BT_OBB_BOX_2D_SHAPE_H

View File

@@ -14,8 +14,18 @@ subject to the following restrictions:
*/
#include "btBoxShape.h"
btBoxShape::btBoxShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape()
{
m_shapeType = BOX_SHAPE_PROXYTYPE;
setSafeMargin(boxHalfExtents);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
//{
void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OBB_BOX_MINKOWSKI_H
#define OBB_BOX_MINKOWSKI_H
#ifndef BT_OBB_BOX_MINKOWSKI_H
#define BT_OBB_BOX_MINKOWSKI_H
#include "btPolyhedralConvexShape.h"
#include "btCollisionMargin.h"
@@ -80,13 +80,7 @@ public:
}
btBoxShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape()
{
m_shapeType = BOX_SHAPE_PROXYTYPE;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
btBoxShape( const btVector3& boxHalfExtents);
virtual void setMargin(btScalar collisionMargin)
{
@@ -145,7 +139,7 @@ public:
virtual void getVertex(int i,btVector3& vtx) const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
btVector3 halfExtents = getHalfExtentsWithMargin();
vtx = btVector3(
halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
@@ -313,6 +307,6 @@ public:
};
#endif //OBB_BOX_MINKOWSKI_H
#endif //BT_OBB_BOX_MINKOWSKI_H

View File

@@ -277,13 +277,13 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
nodeSubPart);
unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT||indicestype==PHY_UCHAR);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:indicestype==PHY_INTEGER?gfxbase[j]:((unsigned char*)gfxbase)[j];
#ifdef DEBUG_TRIANGLE_MESH

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BVH_TRIANGLE_MESH_SHAPE_H
#define BVH_TRIANGLE_MESH_SHAPE_H
#ifndef BT_BVH_TRIANGLE_MESH_SHAPE_H
#define BT_BVH_TRIANGLE_MESH_SHAPE_H
#include "btTriangleMeshShape.h"
#include "btOptimizedBvh.h"
@@ -39,7 +39,7 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_triangleInfoMap(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
@@ -136,4 +136,4 @@ SIMD_FORCE_INLINE int btBvhTriangleMeshShape::calculateSerializeBufferSize() con
#endif //BVH_TRIANGLE_MESH_SHAPE_H
#endif //BT_BVH_TRIANGLE_MESH_SHAPE_H

View File

@@ -13,14 +13,15 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_MARGIN_H
#define COLLISION_MARGIN_H
//used by Gjk and some other algorithms
#ifndef BT_COLLISION_MARGIN_H
#define BT_COLLISION_MARGIN_H
///The CONVEX_DISTANCE_MARGIN is a default collision margin for convex collision shapes derived from btConvexInternalShape.
///This collision margin is used by Gjk and some other algorithms
///Note that when creating small objects, you need to make sure to set a smaller collision margin, using the 'setMargin' API
#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01)
#endif //COLLISION_MARGIN_H
#endif //BT_COLLISION_MARGIN_H

View File

@@ -116,4 +116,4 @@ void btCollisionShape::serializeSingleShape(btSerializer* serializer) const
btChunk* chunk = serializer->allocate(len,1);
const char* structType = serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this);
}
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_SHAPE_H
#define COLLISION_SHAPE_H
#ifndef BT_COLLISION_SHAPE_H
#define BT_COLLISION_SHAPE_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
@@ -146,5 +146,5 @@ SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const
#endif //COLLISION_SHAPE_H
#endif //BT_COLLISION_SHAPE_H

View File

@@ -85,7 +85,7 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
}
void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform,bool shouldRecalculateLocalAabb)
{
m_children[childIndex].m_transform = newChildTransform;
@@ -99,7 +99,10 @@ void btCompoundShape::updateChildTransform(int childIndex, const btTransform& ne
m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
}
recalculateLocalAabb();
if (shouldRecalculateLocalAabb)
{
recalculateLocalAabb();
}
}
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
@@ -283,10 +286,12 @@ void btCompoundShape::setLocalScaling(const btVector3& scaling)
childScale = childScale * scaling / m_localScaling;
m_children[i].m_childShape->setLocalScaling(childScale);
childTrans.setOrigin((childTrans.getOrigin())*scaling);
updateChildTransform(i, childTrans);
recalculateLocalAabb();
updateChildTransform(i, childTrans,false);
}
m_localScaling = scaling;
recalculateLocalAabb();
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COMPOUND_SHAPE_H
#define COMPOUND_SHAPE_H
#ifndef BT_COMPOUND_SHAPE_H
#define BT_COMPOUND_SHAPE_H
#include "btCollisionShape.h"
@@ -106,7 +106,7 @@ public:
}
///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
void updateChildTransform(int childIndex, const btTransform& newChildTransform);
void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true);
btCompoundShapeChild* getChildList()
@@ -143,8 +143,12 @@ public:
return "Compound";
}
btDbvt* getDynamicAabbTree()
const btDbvt* getDynamicAabbTree() const
{
return m_dynamicAabbTree;
}
btDbvt* getDynamicAabbTree()
{
return m_dynamicAabbTree;
}
@@ -205,4 +209,4 @@ SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const
#endif //COMPOUND_SHAPE_H
#endif //BT_COMPOUND_SHAPE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONCAVE_SHAPE_H
#define CONCAVE_SHAPE_H
#ifndef BT_CONCAVE_SHAPE_H
#define BT_CONCAVE_SHAPE_H
#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -57,4 +57,4 @@ public:
};
#endif //CONCAVE_SHAPE_H
#endif //BT_CONCAVE_SHAPE_H

View File

@@ -131,3 +131,13 @@ btVector3 btConeShape::localGetSupportingVertex(const btVector3& vec) const
}
void btConeShape::setLocalScaling(const btVector3& scaling)
{
int axis = m_coneIndices[1];
int r1 = m_coneIndices[0];
int r2 = m_coneIndices[2];
m_height *= scaling[axis] / m_localScaling[axis];
m_radius *= (scaling[r1] / m_localScaling[r1] + scaling[r2] / m_localScaling[r2]) / 2;
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
btConvexInternalShape::setLocalScaling(scaling);
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONE_MINKOWSKI_H
#define CONE_MINKOWSKI_H
#ifndef BT_CONE_MINKOWSKI_H
#define BT_CONE_MINKOWSKI_H
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -81,6 +81,9 @@ public:
{
return m_coneIndices[1];
}
virtual void setLocalScaling(const btVector3& scaling);
};
///btConeShape implements a Cone shape, around the X axis
@@ -96,5 +99,5 @@ class btConeShapeZ : public btConeShape
public:
btConeShapeZ(btScalar radius,btScalar height);
};
#endif //CONE_MINKOWSKI_H
#endif //BT_CONE_MINKOWSKI_H

View File

@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///The btConvex2dShape allows to use arbitrary convex shapes are 2d convex shapes, with the Z component assumed to be 0.
///The btConvex2dShape allows to use arbitrary convex shapes as 2d convex shapes, with the Z component assumed to be 0.
///For 2d boxes, the btBox2dShape is recommended.
class btConvex2dShape : public btConvexShape
{

View File

@@ -208,4 +208,48 @@ const char* btConvexHullShape::serialize(void* dataBuffer, btSerializer* seriali
return "btConvexHullShapeData";
}
void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, float& min, float& max) const
{
#if 1
min = FLT_MAX;
max = -FLT_MAX;
btVector3 witnesPtMin;
btVector3 witnesPtMax;
int numVerts = m_unscaledPoints.size();
for(int i=0;i<numVerts;i++)
{
btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
btVector3 pt = trans * vtx;
float dp = pt.dot(dir);
if(dp < min)
{
min = dp;
witnesPtMin = pt;
}
if(dp > max)
{
max = dp;
witnesPtMax=pt;
}
}
#else
btVector3 localAxis = dir*trans.getBasis();
btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
min = vtx1.dot(dir);
max = vtx2.dot(dir);
#endif
if(min>max)
{
float tmp = min;
min = max;
max = tmp;
}
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_HULL_SHAPE_H
#define CONVEX_HULL_SHAPE_H
#ifndef BT_CONVEX_HULL_SHAPE_H
#define BT_CONVEX_HULL_SHAPE_H
#include "btPolyhedralConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -73,6 +73,8 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
virtual void project(const btTransform& trans, const btVector3& dir, float& min, float& max) const;
//debugging
virtual const char* getName()const {return "Convex";}
@@ -116,5 +118,5 @@ SIMD_FORCE_INLINE int btConvexHullShape::calculateSerializeBufferSize() const
}
#endif //CONVEX_HULL_SHAPE_H
#endif //BT_CONVEX_HULL_SHAPE_H

View File

@@ -21,6 +21,11 @@ subject to the following restrictions:
///The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
///The btConvexInternalShape uses a default collision margin set to CONVEX_DISTANCE_MARGIN.
///This collision margin used by Gjk and some other algorithms, see also btCollisionMargin.h
///Note that when creating small shapes (derived from btConvexInternalShape),
///you need to make sure to set a smaller collision margin, using the 'setMargin' API
///There is a automatic mechanism 'setSafeMargin' used by btBoxShape and btCylinderShape
class btConvexInternalShape : public btConvexShape
{
@@ -62,6 +67,23 @@ public:
m_implicitShapeDimensions = dimensions;
}
void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier = 0.1f)
{
btScalar safeMargin = defaultMarginMultiplier*minDimension;
if (safeMargin < getMargin())
{
setMargin(safeMargin);
}
}
void setSafeMargin(const btVector3& halfExtents, btScalar defaultMarginMultiplier = 0.1f)
{
//see http://code.google.com/p/bullet/issues/detail?id=349
//this margin check could could be added to other collision shapes too,
//or add some assert/warning somewhere
btScalar minDimension=halfExtents[halfExtents.minAxis()];
setSafeMargin(minDimension, defaultMarginMultiplier);
}
///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
{

View File

@@ -0,0 +1,296 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///This file was written by Erwin Coumans
///Separating axis rest based on work from Pierre Terdiman, see
///And contact clipping based on work from Simon Hobbs
#include "btConvexPolyhedron.h"
#include "LinearMath/btHashMap.h"
btConvexPolyhedron::btConvexPolyhedron()
{
}
btConvexPolyhedron::~btConvexPolyhedron()
{
}
inline bool IsAlmostZero(const btVector3& v)
{
if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false;
return true;
}
struct btInternalVertexPair
{
btInternalVertexPair(short int v0,short int v1)
:m_v0(v0),
m_v1(v1)
{
if (m_v1>m_v0)
btSwap(m_v0,m_v1);
}
short int m_v0;
short int m_v1;
int getHash() const
{
return m_v0+(m_v1<<16);
}
bool equals(const btInternalVertexPair& other) const
{
return m_v0==other.m_v0 && m_v1==other.m_v1;
}
};
struct btInternalEdge
{
btInternalEdge()
:m_face0(-1),
m_face1(-1)
{
}
short int m_face0;
short int m_face1;
};
//
#ifdef TEST_INTERNAL_OBJECTS
bool btConvexPolyhedron::testContainment() const
{
for(int p=0;p<8;p++)
{
btVector3 LocalPt;
if(p==0) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], m_extents[2]);
else if(p==1) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], -m_extents[2]);
else if(p==2) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], m_extents[2]);
else if(p==3) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], -m_extents[2]);
else if(p==4) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], m_extents[2]);
else if(p==5) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], -m_extents[2]);
else if(p==6) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], m_extents[2]);
else if(p==7) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], -m_extents[2]);
for(int i=0;i<m_faces.size();i++)
{
const btVector3 Normal(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
const btScalar d = LocalPt.dot(Normal) + m_faces[i].m_plane[3];
if(d>0.0f)
return false;
}
}
return true;
}
#endif
void btConvexPolyhedron::initialize()
{
btHashMap<btInternalVertexPair,btInternalEdge> edges;
btScalar TotalArea = 0.0f;
m_localCenter.setValue(0, 0, 0);
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
int NbTris = numVertices;
for(int j=0;j<NbTris;j++)
{
int k = (j+1)%numVertices;
btInternalVertexPair vp(m_faces[i].m_indices[j],m_faces[i].m_indices[k]);
btInternalEdge* edptr = edges.find(vp);
btVector3 edge = m_vertices[vp.m_v1]-m_vertices[vp.m_v0];
edge.normalize();
bool found = false;
for (int p=0;p<m_uniqueEdges.size();p++)
{
if (IsAlmostZero(m_uniqueEdges[p]-edge) ||
IsAlmostZero(m_uniqueEdges[p]+edge))
{
found = true;
break;
}
}
if (!found)
{
m_uniqueEdges.push_back(edge);
}
if (edptr)
{
btAssert(edptr->m_face0>=0);
btAssert(edptr->m_face1<0);
edptr->m_face1 = i;
} else
{
btInternalEdge ed;
ed.m_face0 = i;
edges.insert(vp,ed);
}
}
}
#ifdef USE_CONNECTED_FACES
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
m_faces[i].m_connectedFaces.resize(numVertices);
for(int j=0;j<numVertices;j++)
{
int k = (j+1)%numVertices;
btInternalVertexPair vp(m_faces[i].m_indices[j],m_faces[i].m_indices[k]);
btInternalEdge* edptr = edges.find(vp);
btAssert(edptr);
btAssert(edptr->m_face0>=0);
btAssert(edptr->m_face1>=0);
int connectedFace = (edptr->m_face0==i)?edptr->m_face1:edptr->m_face0;
m_faces[i].m_connectedFaces[j] = connectedFace;
}
}
#endif//USE_CONNECTED_FACES
for(int i=0;i<m_faces.size();i++)
{
int numVertices = m_faces[i].m_indices.size();
int NbTris = numVertices-2;
const btVector3& p0 = m_vertices[m_faces[i].m_indices[0]];
for(int j=1;j<=NbTris;j++)
{
int k = (j+1)%numVertices;
const btVector3& p1 = m_vertices[m_faces[i].m_indices[j]];
const btVector3& p2 = m_vertices[m_faces[i].m_indices[k]];
btScalar Area = ((p0 - p1).cross(p0 - p2)).length() * 0.5f;
btVector3 Center = (p0+p1+p2)/3.0f;
m_localCenter += Area * Center;
TotalArea += Area;
}
}
m_localCenter /= TotalArea;
#ifdef TEST_INTERNAL_OBJECTS
if(1)
{
m_radius = FLT_MAX;
for(int i=0;i<m_faces.size();i++)
{
const btVector3 Normal(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
const btScalar dist = btFabs(m_localCenter.dot(Normal) + m_faces[i].m_plane[3]);
if(dist<m_radius)
m_radius = dist;
}
btScalar MinX = FLT_MAX;
btScalar MinY = FLT_MAX;
btScalar MinZ = FLT_MAX;
btScalar MaxX = -FLT_MAX;
btScalar MaxY = -FLT_MAX;
btScalar MaxZ = -FLT_MAX;
for(int i=0; i<m_vertices.size(); i++)
{
const btVector3& pt = m_vertices[i];
if(pt.x()<MinX) MinX = pt.x();
if(pt.x()>MaxX) MaxX = pt.x();
if(pt.y()<MinY) MinY = pt.y();
if(pt.y()>MaxY) MaxY = pt.y();
if(pt.z()<MinZ) MinZ = pt.z();
if(pt.z()>MaxZ) MaxZ = pt.z();
}
mC.setValue(MaxX+MinX, MaxY+MinY, MaxZ+MinZ);
mE.setValue(MaxX-MinX, MaxY-MinY, MaxZ-MinZ);
// const btScalar r = m_radius / sqrtf(2.0f);
const btScalar r = m_radius / sqrtf(3.0f);
const int LargestExtent = mE.maxAxis();
const btScalar Step = (mE[LargestExtent]*0.5f - r)/1024.0f;
m_extents[0] = m_extents[1] = m_extents[2] = r;
m_extents[LargestExtent] = mE[LargestExtent]*0.5f;
bool FoundBox = false;
for(int j=0;j<1024;j++)
{
if(testContainment())
{
FoundBox = true;
break;
}
m_extents[LargestExtent] -= Step;
}
if(!FoundBox)
{
m_extents[0] = m_extents[1] = m_extents[2] = r;
}
else
{
// Refine the box
const btScalar Step = (m_radius - r)/1024.0f;
const int e0 = (1<<LargestExtent) & 3;
const int e1 = (1<<e0) & 3;
for(int j=0;j<1024;j++)
{
const btScalar Saved0 = m_extents[e0];
const btScalar Saved1 = m_extents[e1];
m_extents[e0] += Step;
m_extents[e1] += Step;
if(!testContainment())
{
m_extents[e0] = Saved0;
m_extents[e1] = Saved1;
break;
}
}
}
}
#endif
}
void btConvexPolyhedron::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
{
min = FLT_MAX;
max = -FLT_MAX;
int numVerts = m_vertices.size();
for(int i=0;i<numVerts;i++)
{
btVector3 pt = trans * m_vertices[i];
btScalar dp = pt.dot(dir);
if(dp < min) min = dp;
if(dp > max) max = dp;
}
if(min>max)
{
btScalar tmp = min;
min = max;
max = tmp;
}
}

View File

@@ -0,0 +1,62 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///This file was written by Erwin Coumans
#ifndef _BT_POLYHEDRAL_FEATURES_H
#define _BT_POLYHEDRAL_FEATURES_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btAlignedObjectArray.h"
#define TEST_INTERNAL_OBJECTS 1
struct btFace
{
btAlignedObjectArray<int> m_indices;
// btAlignedObjectArray<int> m_connectedFaces;
btScalar m_plane[4];
};
class btConvexPolyhedron
{
public:
btConvexPolyhedron();
virtual ~btConvexPolyhedron();
btAlignedObjectArray<btVector3> m_vertices;
btAlignedObjectArray<btFace> m_faces;
btAlignedObjectArray<btVector3> m_uniqueEdges;
btVector3 m_localCenter;
btVector3 m_extents;
btScalar m_radius;
btVector3 mC;
btVector3 mE;
void initialize();
bool testContainment() const;
void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const;
};
#endif //_BT_POLYHEDRAL_FEATURES_H

View File

@@ -43,6 +43,23 @@ btConvexShape::~btConvexShape()
}
void btConvexShape::project(const btTransform& trans, const btVector3& dir, float& min, float& max) const
{
btVector3 localAxis = dir*trans.getBasis();
btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
min = vtx1.dot(dir);
max = vtx2.dot(dir);
if(min>max)
{
float tmp = min;
min = max;
max = tmp;
}
}
static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling)
{

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_SHAPE_INTERFACE1
#define CONVEX_SHAPE_INTERFACE1
#ifndef BT_CONVEX_SHAPE_INTERFACE1
#define BT_CONVEX_SHAPE_INTERFACE1
#include "btCollisionShape.h"
@@ -52,6 +52,8 @@ public:
btScalar getMarginNonVirtual () const;
void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
virtual void project(const btTransform& trans, const btVector3& dir, float& min, float& max) const;
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
@@ -79,4 +81,4 @@ public:
#endif //CONVEX_SHAPE_INTERFACE1
#endif //BT_CONVEX_SHAPE_INTERFACE1

View File

@@ -12,8 +12,8 @@ subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_TRIANGLEMESH_SHAPE_H
#define CONVEX_TRIANGLEMESH_SHAPE_H
#ifndef BT_CONVEX_TRIANGLEMESH_SHAPE_H
#define BT_CONVEX_TRIANGLEMESH_SHAPE_H
#include "btPolyhedralConvexShape.h"
@@ -69,7 +69,7 @@ public:
#endif //CONVEX_TRIANGLEMESH_SHAPE_H
#endif //BT_CONVEX_TRIANGLEMESH_SHAPE_H

View File

@@ -19,6 +19,8 @@ btCylinderShape::btCylinderShape (const btVector3& halfExtents)
:btConvexInternalShape(),
m_upAxis(1)
{
setSafeMargin(halfExtents);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
@@ -47,7 +49,64 @@ void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3&
void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
//approximation of box shape, todo: implement cylinder shape inertia before people notice ;-)
//Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility
//#define USE_BOX_INERTIA_APPROXIMATION 1
#ifndef USE_BOX_INERTIA_APPROXIMATION
/*
cylinder is defined as following:
*
* - principle axis aligned along y by default, radius in x, z-value not used
* - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used
* - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used
*
*/
btScalar radius2; // square of cylinder radius
btScalar height2; // square of cylinder height
btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension
btScalar div12 = mass / 12.f;
btScalar div4 = mass / 4.f;
btScalar div2 = mass / 2.f;
int idxRadius, idxHeight;
switch (m_upAxis) // get indices of radius and height of cylinder
{
case 0: // cylinder is aligned along x
idxRadius = 1;
idxHeight = 0;
break;
case 2: // cylinder is aligned along z
idxRadius = 0;
idxHeight = 2;
break;
default: // cylinder is aligned along y
idxRadius = 0;
idxHeight = 1;
}
// calculate squares
radius2 = halfExtents[idxRadius] * halfExtents[idxRadius];
height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight];
// calculate tensor terms
btScalar t1 = div12 * height2 + div4 * radius2;
btScalar t2 = div2 * radius2;
switch (m_upAxis) // set diagonal elements of inertia tensor
{
case 0: // cylinder is aligned along x
inertia.setValue(t2,t1,t1);
break;
case 2: // cylinder is aligned along z
inertia.setValue(t1,t1,t2);
break;
default: // cylinder is aligned along y
inertia.setValue(t1,t2,t1);
}
#else //USE_BOX_INERTIA_APPROXIMATION
//approximation of box shape
btVector3 halfExtents = getHalfExtentsWithMargin();
btScalar lx=btScalar(2.)*(halfExtents.x());
@@ -57,7 +116,7 @@ void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) co
inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
mass/(btScalar(12.0)) * (lx*lx + lz*lz),
mass/(btScalar(12.0)) * (lx*lx + ly*ly));
#endif //USE_BOX_INERTIA_APPROXIMATION
}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CYLINDER_MINKOWSKI_H
#define CYLINDER_MINKOWSKI_H
#ifndef BT_CYLINDER_MINKOWSKI_H
#define BT_CYLINDER_MINKOWSKI_H
#include "btBoxShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -196,5 +196,5 @@ SIMD_FORCE_INLINE const char* btCylinderShape::serialize(void* dataBuffer, btSer
#endif //CYLINDER_MINKOWSKI_H
#endif //BT_CYLINDER_MINKOWSKI_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EMPTY_SHAPE_H
#define EMPTY_SHAPE_H
#ifndef BT_EMPTY_SHAPE_H
#define BT_EMPTY_SHAPE_H
#include "btConcaveShape.h"
@@ -67,4 +67,4 @@ protected:
#endif //EMPTY_SHAPE_H
#endif //BT_EMPTY_SHAPE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef HEIGHTFIELD_TERRAIN_SHAPE_H
#define HEIGHTFIELD_TERRAIN_SHAPE_H
#ifndef BT_HEIGHTFIELD_TERRAIN_SHAPE_H
#define BT_HEIGHTFIELD_TERRAIN_SHAPE_H
#include "btConcaveShape.h"
@@ -158,4 +158,4 @@ public:
};
#endif //HEIGHTFIELD_TERRAIN_SHAPE_H
#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H

View File

@@ -15,8 +15,8 @@ subject to the following restrictions:
/// This file was created by Alex Silverman
#ifndef MATERIAL_H
#define MATERIAL_H
#ifndef BT_MATERIAL_H
#define BT_MATERIAL_H
// Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties
class btMaterial
@@ -31,5 +31,5 @@ public:
btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; }
};
#endif // MATERIAL_H
#endif // BT_MATERIAL_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MINKOWSKI_SUM_SHAPE_H
#define MINKOWSKI_SUM_SHAPE_H
#ifndef BT_MINKOWSKI_SUM_SHAPE_H
#define BT_MINKOWSKI_SUM_SHAPE_H
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -57,4 +57,4 @@ public:
}
};
#endif //MINKOWSKI_SUM_SHAPE_H
#endif //BT_MINKOWSKI_SUM_SHAPE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MULTI_SPHERE_MINKOWSKI_H
#define MULTI_SPHERE_MINKOWSKI_H
#ifndef BT_MULTI_SPHERE_MINKOWSKI_H
#define BT_MULTI_SPHERE_MINKOWSKI_H
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -96,4 +96,4 @@ SIMD_FORCE_INLINE int btMultiSphereShape::calculateSerializeBufferSize() const
#endif //MULTI_SPHERE_MINKOWSKI_H
#endif //BT_MULTI_SPHERE_MINKOWSKI_H

View File

@@ -15,8 +15,8 @@ subject to the following restrictions:
/// This file was created by Alex Silverman
#ifndef BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
#define BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
#ifndef BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
#define BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
#include "btBvhTriangleMeshShape.h"
#include "btMaterial.h"
@@ -31,7 +31,6 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;}
btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true):
btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh)
{
@@ -118,4 +117,4 @@ public:
}
;
#endif //BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
#endif //BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H

View File

@@ -15,8 +15,8 @@ subject to the following restrictions:
///Contains contributions from Disney Studio's
#ifndef OPTIMIZED_BVH_H
#define OPTIMIZED_BVH_H
#ifndef BT_OPTIMIZED_BVH_H
#define BT_OPTIMIZED_BVH_H
#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h"
@@ -60,6 +60,6 @@ public:
};
#endif //OPTIMIZED_BVH_H
#endif //BT_OPTIMIZED_BVH_H

View File

@@ -14,12 +14,246 @@ subject to the following restrictions:
*/
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "btConvexPolyhedron.h"
#include "LinearMath/btConvexHullComputer.h"
#include <new>
#include "LinearMath/btGeometryUtil.h"
#include "LinearMath/btGrahamScan2dConvexHull.h"
btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape()
btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
m_polyhedron(0)
{
}
btPolyhedralConvexShape::~btPolyhedralConvexShape()
{
if (m_polyhedron)
{
btAlignedFree(m_polyhedron);
}
}
bool btPolyhedralConvexShape::initializePolyhedralFeatures()
{
if (m_polyhedron)
btAlignedFree(m_polyhedron);
void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron),16);
m_polyhedron = new (mem) btConvexPolyhedron;
btAlignedObjectArray<btVector3> orgVertices;
for (int i=0;i<getNumVertices();i++)
{
btVector3& newVertex = orgVertices.expand();
getVertex(i,newVertex);
}
#if 0
btAlignedObjectArray<btVector3> planeEquations;
btGeometryUtil::getPlaneEquationsFromVertices(orgVertices,planeEquations);
btAlignedObjectArray<btVector3> shiftedPlaneEquations;
for (int p=0;p<planeEquations.size();p++)
{
btVector3 plane = planeEquations[p];
plane[3] -= getMargin();
shiftedPlaneEquations.push_back(plane);
}
btAlignedObjectArray<btVector3> tmpVertices;
btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,tmpVertices);
btConvexHullComputer conv;
conv.compute(&tmpVertices[0].getX(), sizeof(btVector3),tmpVertices.size(),0.f,0.f);
#else
btConvexHullComputer conv;
conv.compute(&orgVertices[0].getX(), sizeof(btVector3),orgVertices.size(),0.f,0.f);
#endif
btAlignedObjectArray<btVector3> faceNormals;
int numFaces = conv.faces.size();
faceNormals.resize(numFaces);
btConvexHullComputer* convexUtil = &conv;
btAlignedObjectArray<btFace> tmpFaces;
tmpFaces.resize(numFaces);
int numVertices = convexUtil->vertices.size();
m_polyhedron->m_vertices.resize(numVertices);
for (int p=0;p<numVertices;p++)
{
m_polyhedron->m_vertices[p] = convexUtil->vertices[p];
}
for (int i=0;i<numFaces;i++)
{
int face = convexUtil->faces[i];
//printf("face=%d\n",face);
const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face];
const btConvexHullComputer::Edge* edge = firstEdge;
btVector3 edges[3];
int numEdges = 0;
//compute face normals
btScalar maxCross2 = 0.f;
int chosenEdge = -1;
do
{
int src = edge->getSourceVertex();
tmpFaces[i].m_indices.push_back(src);
int targ = edge->getTargetVertex();
btVector3 wa = convexUtil->vertices[src];
btVector3 wb = convexUtil->vertices[targ];
btVector3 newEdge = wb-wa;
newEdge.normalize();
if (numEdges<2)
edges[numEdges++] = newEdge;
edge = edge->getNextEdgeOfFace();
} while (edge!=firstEdge);
btScalar planeEq = 1e30f;
if (numEdges==2)
{
faceNormals[i] = edges[0].cross(edges[1]);
faceNormals[i].normalize();
tmpFaces[i].m_plane[0] = faceNormals[i].getX();
tmpFaces[i].m_plane[1] = faceNormals[i].getY();
tmpFaces[i].m_plane[2] = faceNormals[i].getZ();
tmpFaces[i].m_plane[3] = planeEq;
}
else
{
btAssert(0);//degenerate?
faceNormals[i].setZero();
}
for (int v=0;v<tmpFaces[i].m_indices.size();v++)
{
btScalar eq = m_polyhedron->m_vertices[tmpFaces[i].m_indices[v]].dot(faceNormals[i]);
if (planeEq>eq)
{
planeEq=eq;
}
}
tmpFaces[i].m_plane[3] = -planeEq;
}
//merge coplanar faces and copy them to m_polyhedron
btScalar faceWeldThreshold= 0.999f;
btAlignedObjectArray<int> todoFaces;
for (int i=0;i<tmpFaces.size();i++)
todoFaces.push_back(i);
while (todoFaces.size())
{
btAlignedObjectArray<int> coplanarFaceGroup;
int refFace = todoFaces[todoFaces.size()-1];
coplanarFaceGroup.push_back(refFace);
btFace& faceA = tmpFaces[refFace];
todoFaces.pop_back();
btVector3 faceNormalA(faceA.m_plane[0],faceA.m_plane[1],faceA.m_plane[2]);
for (int j=todoFaces.size()-1;j>=0;j--)
{
int i = todoFaces[j];
btFace& faceB = tmpFaces[i];
btVector3 faceNormalB(faceB.m_plane[0],faceB.m_plane[1],faceB.m_plane[2]);
if (faceNormalA.dot(faceNormalB)>faceWeldThreshold)
{
coplanarFaceGroup.push_back(i);
todoFaces.remove(i);
}
}
if (coplanarFaceGroup.size()>1)
{
//do the merge: use Graham Scan 2d convex hull
btAlignedObjectArray<GrahamVector2> orgpoints;
for (int i=0;i<coplanarFaceGroup.size();i++)
{
// m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]);
btFace& face = tmpFaces[coplanarFaceGroup[i]];
btVector3 faceNormal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
btVector3 xyPlaneNormal(0,0,1);
btQuaternion rotationArc = shortestArcQuat(faceNormal,xyPlaneNormal);
for (int f=0;f<face.m_indices.size();f++)
{
int orgIndex = face.m_indices[f];
btVector3 pt = m_polyhedron->m_vertices[orgIndex];
btVector3 rotatedPt = quatRotate(rotationArc,pt);
rotatedPt.setZ(0);
bool found = false;
for (int i=0;i<orgpoints.size();i++)
{
if ((rotatedPt-orgpoints[i]).length2()<0.001)
{
found=true;
break;
}
}
if (!found)
orgpoints.push_back(GrahamVector2(rotatedPt,orgIndex));
}
}
btFace combinedFace;
for (int i=0;i<4;i++)
combinedFace.m_plane[i] = tmpFaces[coplanarFaceGroup[0]].m_plane[i];
btAlignedObjectArray<GrahamVector2> hull;
GrahamScanConvexHull2D(orgpoints,hull);
for (int i=0;i<hull.size();i++)
{
combinedFace.m_indices.push_back(hull[i].m_orgIndex);
}
m_polyhedron->m_faces.push_back(combinedFace);
} else
{
for (int i=0;i<coplanarFaceGroup.size();i++)
{
m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]);
}
}
}
m_polyhedron->initialize();
return true;
}
btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
@@ -183,11 +417,14 @@ void btPolyhedralConvexAabbCachingShape::recalcLocalAabb()
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 tmp = localGetSupportingVertex(vec);
m_localAabbMax[i] = tmp[i]+m_collisionMargin;
m_localAabbMax[i] = tmp[i];
vec[i] = btScalar(-1.);
tmp = localGetSupportingVertex(vec);
m_localAabbMin[i] = tmp[i]-m_collisionMargin;
m_localAabbMin[i] = tmp[i];
}
#endif
}

View File

@@ -13,23 +13,37 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BU_SHAPE
#define BU_SHAPE
#ifndef BT_POLYHEDRAL_CONVEX_SHAPE_H
#define BT_POLYHEDRAL_CONVEX_SHAPE_H
#include "LinearMath/btMatrix3x3.h"
#include "btConvexInternalShape.h"
class btConvexPolyhedron;
///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
class btPolyhedralConvexShape : public btConvexInternalShape
{
protected:
btConvexPolyhedron* m_polyhedron;
public:
btPolyhedralConvexShape();
virtual ~btPolyhedralConvexShape();
///optional method mainly used to generate multiple contact points by clipping polyhedral features (faces/edges)
virtual bool initializePolyhedralFeatures();
const btConvexPolyhedron* getConvexPolyhedron() const
{
return m_polyhedron;
}
//brute force implementations
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -95,4 +109,4 @@ public:
};
#endif //BU_SHAPE
#endif //BT_POLYHEDRAL_CONVEX_SHAPE_H

View File

@@ -62,10 +62,12 @@ void btScaledBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callb
scaledAabbMin[0] = m_localScaling.getX() >= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
scaledAabbMin[1] = m_localScaling.getY() >= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
scaledAabbMin[2] = m_localScaling.getZ() >= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
scaledAabbMin[3] = 0.f;
scaledAabbMax[0] = m_localScaling.getX() <= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
scaledAabbMax[1] = m_localScaling.getY() <= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
scaledAabbMax[2] = m_localScaling.getZ() <= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
scaledAabbMax[3] = 0.f;
m_bvhTriMeshShape->processAllTriangles(&scaledCallback,scaledAabbMin,scaledAabbMax);

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SCALED_BVH_TRIANGLE_MESH_SHAPE_H
#define SCALED_BVH_TRIANGLE_MESH_SHAPE_H
#ifndef BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H
#define BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
@@ -57,6 +57,37 @@ public:
//debugging
virtual const char* getName()const {return "SCALEDBVHTRIANGLEMESH";}
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
};
#endif //BVH_TRIANGLE_MESH_SHAPE_H
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btScaledTriangleMeshShapeData
{
btTriangleMeshShapeData m_trimeshShapeData;
btVector3FloatData m_localScaling;
};
SIMD_FORCE_INLINE int btScaledBvhTriangleMeshShape::calculateSerializeBufferSize() const
{
return sizeof(btScaledTriangleMeshShapeData);
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE const char* btScaledBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
btScaledTriangleMeshShapeData* scaledMeshData = (btScaledTriangleMeshShapeData*) dataBuffer;
m_bvhTriMeshShape->serialize(&scaledMeshData->m_trimeshShapeData,serializer);
scaledMeshData->m_trimeshShapeData.m_collisionShapeData.m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
m_localScaling.serializeFloat(scaledMeshData->m_localScaling);
return "btScaledTriangleMeshShapeData";
}
#endif //BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H

View File

@@ -15,8 +15,8 @@ subject to the following restrictions:
///btShapeHull implemented by John McCutchan.
#ifndef _SHAPE_HULL_H
#define _SHAPE_HULL_H
#ifndef BT_SHAPE_HULL_H
#define BT_SHAPE_HULL_H
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
@@ -56,4 +56,4 @@ public:
}
};
#endif //_SHAPE_HULL_H
#endif //BT_SHAPE_HULL_H

View File

@@ -12,8 +12,8 @@ subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_MINKOWSKI_H
#define SPHERE_MINKOWSKI_H
#ifndef BT_SPHERE_MINKOWSKI_H
#define BT_SPHERE_MINKOWSKI_H
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@@ -70,4 +70,4 @@ public:
};
#endif //SPHERE_MINKOWSKI_H
#endif //BT_SPHERE_MINKOWSKI_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef STATIC_PLANE_SHAPE_H
#define STATIC_PLANE_SHAPE_H
#ifndef BT_STATIC_PLANE_SHAPE_H
#define BT_STATIC_PLANE_SHAPE_H
#include "btConcaveShape.h"
@@ -97,7 +97,7 @@ SIMD_FORCE_INLINE const char* btStaticPlaneShape::serialize(void* dataBuffer, bt
}
#endif //STATIC_PLANE_SHAPE_H
#endif //BT_STATIC_PLANE_SHAPE_H

View File

@@ -88,6 +88,21 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
}
break;
}
case PHY_UCHAR:
{
for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{
unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
callback->internalProcessTriangleIndex(triangle,part,gfxindex);
}
break;
}
default:
btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
}
@@ -130,6 +145,21 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
}
break;
}
case PHY_UCHAR:
{
for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{
unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
callback->internalProcessTriangleIndex(triangle,part,gfxindex);
}
break;
}
default:
btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
}
@@ -266,6 +296,24 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
}
break;
}
case PHY_UCHAR:
{
if (numtriangles)
{
btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{
unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
tmpIndices[gfxindex].m_values[0] = tri_indices[0];
tmpIndices[gfxindex].m_values[1] = tri_indices[1];
tmpIndices[gfxindex].m_values[2] = tri_indices[2];
}
serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
}
break;
}
default:
{
btAssert(0);

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef STRIDING_MESHINTERFACE_H
#define STRIDING_MESHINTERFACE_H
#ifndef BT_STRIDING_MESHINTERFACE_H
#define BT_STRIDING_MESHINTERFACE_H
#include "LinearMath/btVector3.h"
#include "btTriangleCallback.h"
@@ -116,6 +116,13 @@ struct btShortIntIndexTripletData
char m_pad[2];
};
struct btCharIndexTripletData
{
unsigned char m_values[3];
char m_pad;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btMeshPartData
{
@@ -124,6 +131,7 @@ struct btMeshPartData
btIntIndexData *m_indices32;
btShortIntIndexTripletData *m_3indices16;
btCharIndexTripletData *m_3indices8;
btShortIntIndexData *m_indices16;//backwards compatibility
@@ -151,4 +159,4 @@ SIMD_FORCE_INLINE int btStridingMeshInterface::calculateSerializeBufferSize() co
#endif //STRIDING_MESHINTERFACE_H
#endif //BT_STRIDING_MESHINTERFACE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BU_SIMPLEX_1TO4_SHAPE
#define BU_SIMPLEX_1TO4_SHAPE
#ifndef BT_SIMPLEX_1TO4_SHAPE
#define BT_SIMPLEX_1TO4_SHAPE
#include "btPolyhedralConvexShape.h"
@@ -71,4 +71,4 @@ public:
};
#endif //BU_SIMPLEX_1TO4_SHAPE
#endif //BT_SIMPLEX_1TO4_SHAPE

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TRIANGLE_CALLBACK_H
#define TRIANGLE_CALLBACK_H
#ifndef BT_TRIANGLE_CALLBACK_H
#define BT_TRIANGLE_CALLBACK_H
#include "LinearMath/btVector3.h"
@@ -39,4 +39,4 @@ public:
#endif //TRIANGLE_CALLBACK_H
#endif //BT_TRIANGLE_CALLBACK_H

View File

@@ -61,6 +61,7 @@ struct btTriangleInfoMap : public btInternalTriangleInfoMap
btScalar m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle
btScalar m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared'
btScalar m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge"
btScalar m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold
btScalar m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold)
@@ -71,6 +72,7 @@ struct btTriangleInfoMap : public btInternalTriangleInfoMap
m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001);
m_edgeDistanceThreshold = btScalar(0.1);
m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001);
m_maxEdgeAngleThreshold = SIMD_2_PI;
}
virtual ~btTriangleInfoMap() {}

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TRIANGLE_MESH_H
#define TRIANGLE_MESH_H
#ifndef BT_TRIANGLE_MESH_H
#define BT_TRIANGLE_MESH_H
#include "btTriangleIndexVertexArray.h"
#include "LinearMath/btVector3.h"
@@ -65,5 +65,5 @@ class btTriangleMesh : public btTriangleIndexVertexArray
};
#endif //TRIANGLE_MESH_H
#endif //BT_TRIANGLE_MESH_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TRIANGLE_MESH_SHAPE_H
#define TRIANGLE_MESH_SHAPE_H
#ifndef BT_TRIANGLE_MESH_SHAPE_H
#define BT_TRIANGLE_MESH_SHAPE_H
#include "btConcaveShape.h"
#include "btStridingMeshInterface.h"
@@ -86,4 +86,4 @@ public:
#endif //TRIANGLE_MESH_SHAPE_H
#endif //BT_TRIANGLE_MESH_SHAPE_H

View File

@@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OBB_TRIANGLE_MINKOWSKI_H
#define OBB_TRIANGLE_MINKOWSKI_H
#ifndef BT_OBB_TRIANGLE_MINKOWSKI_H
#define BT_OBB_TRIANGLE_MINKOWSKI_H
#include "btConvexShape.h"
#include "btBoxShape.h"
@@ -178,5 +178,5 @@ public:
};
#endif //OBB_TRIANGLE_MINKOWSKI_H
#endif //BT_OBB_TRIANGLE_MINKOWSKI_H

View File

@@ -64,25 +64,70 @@ void btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inert
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void btUniformScalingShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
void btUniformScalingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
m_childConvexShape->getAabb(t,aabbMin,aabbMax);
btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5);
btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor;
aabbMin = aabbCenter - scaledAabbHalfExtends;
aabbMax = aabbCenter + scaledAabbHalfExtends;
getAabbSlow(trans,aabbMin,aabbMax);
}
void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax);
btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5);
btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor;
#if 1
btVector3 _directions[] =
{
btVector3( 1., 0., 0.),
btVector3( 0., 1., 0.),
btVector3( 0., 0., 1.),
btVector3( -1., 0., 0.),
btVector3( 0., -1., 0.),
btVector3( 0., 0., -1.)
};
btVector3 _supporting[] =
{
btVector3( 0., 0., 0.),
btVector3( 0., 0., 0.),
btVector3( 0., 0., 0.),
btVector3( 0., 0., 0.),
btVector3( 0., 0., 0.),
btVector3( 0., 0., 0.)
};
aabbMin = aabbCenter - scaledAabbHalfExtends;
aabbMax = aabbCenter + scaledAabbHalfExtends;
for (int i=0;i<6;i++)
{
_directions[i] = _directions[i]*t.getBasis();
}
batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6);
btVector3 aabbMin1(0,0,0),aabbMax1(0,0,0);
for ( int i = 0; i < 3; ++i )
{
aabbMax1[i] = t(_supporting[i])[i];
aabbMin1[i] = t(_supporting[i + 3])[i];
}
btVector3 marginVec(getMargin(),getMargin(),getMargin());
aabbMin = aabbMin1-marginVec;
aabbMax = aabbMax1+marginVec;
#else
btScalar margin = getMargin();
for (int i=0;i<3;i++)
{
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 sv = localGetSupportingVertex(vec*t.getBasis());
btVector3 tmp = t(sv);
aabbMax[i] = tmp[i]+margin;
vec[i] = btScalar(-1.);
sv = localGetSupportingVertex(vec*t.getBasis());
tmp = t(sv);
aabbMin[i] = tmp[i]-margin;
}
#endif
}
void btUniformScalingShape::setLocalScaling(const btVector3& scaling)

View File

@@ -22,20 +22,72 @@ subject to the following restrictions:
#include "btGjkPairDetector.h"
#include "btPointCollector.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver)
:m_simplexSolver(simplexSolver),
m_penetrationDepthSolver(penetrationDepthSolver),
m_convexA(convexA),m_convexB(convexB)
m_convexA(convexA),m_convexB1(convexB),m_planeShape(0)
{
}
btContinuousConvexCollision::btContinuousConvexCollision( const btConvexShape* convexA,const btStaticPlaneShape* plane)
:m_simplexSolver(0),
m_penetrationDepthSolver(0),
m_convexA(convexA),m_convexB1(0),m_planeShape(plane)
{
}
/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
/// You don't want your game ever to lock-up.
#define MAX_ITERATIONS 64
void btContinuousConvexCollision::computeClosestPoints( const btTransform& transA, const btTransform& transB,btPointCollector& pointCollector)
{
if (m_convexB1)
{
m_simplexSolver->reset();
btGjkPairDetector gjk(m_convexA,m_convexB1,m_convexA->getShapeType(),m_convexB1->getShapeType(),m_convexA->getMargin(),m_convexB1->getMargin(),m_simplexSolver,m_penetrationDepthSolver);
btGjkPairDetector::ClosestPointInput input;
input.m_transformA = transA;
input.m_transformB = transB;
gjk.getClosestPoints(input,pointCollector,0);
} else
{
//convex versus plane
const btConvexShape* convexShape = m_convexA;
const btStaticPlaneShape* planeShape = m_planeShape;
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform convexWorldTransform = transA;
btTransform convexInPlaneTrans;
convexInPlaneTrans= transB.inverse() * convexWorldTransform;
btTransform planeInConvex;
planeInConvex= convexWorldTransform.inverse() * transB;
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
btVector3 vtxInPlaneWorld = transB * vtxInPlaneProjected;
btVector3 normalOnSurfaceB = transB.getBasis() * planeNormal;
pointCollector.addContactPoint(
normalOnSurfaceB,
vtxInPlaneWorld,
distance);
}
}
bool btContinuousConvexCollision::calcTimeOfImpact(
const btTransform& fromA,
const btTransform& toA,
@@ -44,7 +96,6 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
CastResult& result)
{
m_simplexSolver->reset();
/// compute linear and angular velocity for this interval, to interpolate
btVector3 linVelA,angVelA,linVelB,angVelB;
@@ -53,7 +104,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();
btScalar boundingRadiusB = m_convexB1?m_convexB1->getAngularMotionDisc():0.f;
btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
btVector3 relLinVel = (linVelB-linVelA);
@@ -64,7 +115,6 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
return false;
btScalar radius = btScalar(0.001);
btScalar lambda = btScalar(0.);
btVector3 v(1,0,0);
@@ -83,28 +133,14 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
//first solution, using GJK
btTransform identityTrans;
identityTrans.setIdentity();
btSphereShape raySphere(btScalar(0.0));
raySphere.setMargin(btScalar(0.));
btScalar radius = 0.001f;
// result.drawCoordSystem(sphereTr);
btPointCollector pointCollector1;
{
btGjkPairDetector gjk(m_convexA,m_convexB,m_convexA->getShapeType(),m_convexB->getShapeType(),m_convexA->getMargin(),m_convexB->getMargin(),m_simplexSolver,m_penetrationDepthSolver);
btGjkPairDetector::ClosestPointInput input;
//we don't use margins during CCD
// gjk.setIgnoreMargin(true);
input.m_transformA = fromA;
input.m_transformB = fromB;
gjk.getClosestPoints(input,pointCollector1,0);
computeClosestPoints(fromA,fromB,pointCollector1);
hasResult = pointCollector1.m_hasResult;
c = pointCollector1.m_pointInWorld;
@@ -113,11 +149,12 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
if (hasResult)
{
btScalar dist;
dist = pointCollector1.m_distance;
dist = pointCollector1.m_distance + result.m_allowedPenetration;
n = pointCollector1.m_normalOnBInWorld;
btScalar projectedLinearVelocity = relLinVel.dot(n);
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
return false;
//not close enough
while (dist > radius)
{
@@ -125,19 +162,10 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
{
result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1));
}
numIter++;
if (numIter > maxIter)
{
return false; //todo: report a failure
}
btScalar dLambda = btScalar(0.);
projectedLinearVelocity = relLinVel.dot(n);
//calculate safe moving fraction from distance / (linear+rotational velocity)
//btScalar clippedDist = GEN_min(angularConservativeRadius,dist);
//btScalar clippedDist = dist;
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
@@ -182,37 +210,27 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
result.DebugDraw( lambda );
btPointCollector pointCollector;
btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
btGjkPairDetector::ClosestPointInput input;
input.m_transformA = interpolatedTransA;
input.m_transformB = interpolatedTransB;
gjk.getClosestPoints(input,pointCollector,0);
computeClosestPoints(interpolatedTransA,interpolatedTransB,pointCollector);
if (pointCollector.m_hasResult)
{
if (pointCollector.m_distance < btScalar(0.))
{
//degenerate ?!
result.m_fraction = lastLambda;
n = pointCollector.m_normalOnBInWorld;
result.m_normal=n;//.setValue(1,1,1);// = n;
result.m_hitPoint = pointCollector.m_pointInWorld;
return true;
}
dist = pointCollector.m_distance+result.m_allowedPenetration;
c = pointCollector.m_pointInWorld;
n = pointCollector.m_normalOnBInWorld;
dist = pointCollector.m_distance;
} else
{
//??
result.reportFailure(-1, numIter);
return false;
}
numIter++;
if (numIter > maxIter)
{
result.reportFailure(-2, numIter);
return false;
}
}
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
return false;
result.m_fraction = lambda;
result.m_normal = n;
result.m_hitPoint = c;
@@ -221,16 +239,5 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
return false;
/*
//todo:
//if movement away from normal, discard result
btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
if (result.m_fraction < btScalar(1.))
{
if (move.dot(result.m_normal) <= btScalar(0.))
{
}
}
*/
}

View File

@@ -14,13 +14,14 @@ subject to the following restrictions:
*/
#ifndef CONTINUOUS_COLLISION_CONVEX_CAST_H
#define CONTINUOUS_COLLISION_CONVEX_CAST_H
#ifndef BT_CONTINUOUS_COLLISION_CONVEX_CAST_H
#define BT_CONTINUOUS_COLLISION_CONVEX_CAST_H
#include "btConvexCast.h"
#include "btSimplexSolverInterface.h"
class btConvexPenetrationDepthSolver;
class btConvexShape;
class btStaticPlaneShape;
/// btContinuousConvexCollision implements angular and linear time of impact for convex objects.
/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis).
@@ -31,13 +32,18 @@ class btContinuousConvexCollision : public btConvexCast
btSimplexSolverInterface* m_simplexSolver;
btConvexPenetrationDepthSolver* m_penetrationDepthSolver;
const btConvexShape* m_convexA;
const btConvexShape* m_convexB;
//second object is either a convex or a plane (code sharing)
const btConvexShape* m_convexB1;
const btStaticPlaneShape* m_planeShape;
void computeClosestPoints( const btTransform& transA, const btTransform& transB,struct btPointCollector& pointCollector);
public:
btContinuousConvexCollision (const btConvexShape* shapeA,const btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
btContinuousConvexCollision(const btConvexShape* shapeA,const btStaticPlaneShape* plane );
virtual bool calcTimeOfImpact(
const btTransform& fromA,
const btTransform& toA,
@@ -48,5 +54,6 @@ public:
};
#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H
#endif //BT_CONTINUOUS_COLLISION_CONVEX_CAST_H

View File

@@ -14,8 +14,8 @@ subject to the following restrictions:
*/
#ifndef CONVEX_CAST_H
#define CONVEX_CAST_H
#ifndef BT_CONVEX_CAST_H
#define BT_CONVEX_CAST_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
@@ -39,7 +39,7 @@ public:
virtual void DebugDraw(btScalar fraction) {(void)fraction;}
virtual void drawCoordSystem(const btTransform& trans) {(void)trans;}
virtual void reportFailure(int errNo, int numIterations) {(void)errNo;(void)numIterations;}
CastResult()
:m_fraction(btScalar(BT_LARGE_FLOAT)),
m_debugDrawer(0),
@@ -70,4 +70,4 @@ public:
CastResult& result) = 0;
};
#endif //CONVEX_CAST_H
#endif //BT_CONVEX_CAST_H

View File

@@ -14,8 +14,8 @@ subject to the following restrictions:
*/
#ifndef __CONVEX_PENETRATION_DEPTH_H
#define __CONVEX_PENETRATION_DEPTH_H
#ifndef BT_CONVEX_PENETRATION_DEPTH_H
#define BT_CONVEX_PENETRATION_DEPTH_H
class btStackAlloc;
class btVector3;
@@ -38,5 +38,5 @@ public:
};
#endif //CONVEX_PENETRATION_DEPTH_H
#endif //BT_CONVEX_PENETRATION_DEPTH_H

View File

@@ -14,8 +14,9 @@ subject to the following restrictions:
*/
#ifndef DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
#define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
#ifndef BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
#define BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
class btStackAlloc;
@@ -86,4 +87,5 @@ struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result
}
};
#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE1_H
#endif //BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H

View File

@@ -15,8 +15,8 @@ subject to the following restrictions:
#ifndef GJK_CONVEX_CAST_H
#define GJK_CONVEX_CAST_H
#ifndef BT_GJK_CONVEX_CAST_H
#define BT_GJK_CONVEX_CAST_H
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -47,4 +47,4 @@ public:
};
#endif //GJK_CONVEX_CAST_H
#endif //BT_GJK_CONVEX_CAST_H

View File

@@ -22,8 +22,9 @@ misrepresented as being the original software.
/*
GJK-EPA collision solver by Nathanael Presson, 2008
*/
#ifndef _68DA1F85_90B7_4bb0_A705_83B4040A75C6_
#define _68DA1F85_90B7_4bb0_A705_83B4040A75C6_
#ifndef BT_GJK_EPA2_H
#define BT_GJK_EPA2_H
#include "BulletCollision/CollisionShapes/btConvexShape.h"
///btGjkEpaSolver contributed under zlib by Nathanael Presson
@@ -70,4 +71,5 @@ static bool SignedDistance( const btConvexShape* shape0,const btTransform& wtrs
};
#endif
#endif //BT_GJK_EPA2_H

View File

@@ -254,20 +254,21 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
}
#endif //
m_cachedSeparatingAxis = newCachedSeparatingAxis;
//redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
//are we getting any closer ?
if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance)
{
m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
// m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
checkSimplex = true;
m_degenerateSimplex = 12;
break;
}
m_cachedSeparatingAxis = newCachedSeparatingAxis;
//degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject
if (m_curIter++ > gGjkMaxIter)
{
@@ -294,7 +295,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
if (!check)
{
//do we need this backup_closest here ?
m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
// m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
m_degenerateSimplex = 13;
break;
}
@@ -303,7 +304,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
if (checkSimplex)
{
m_simplexSolver->compute_points(pointOnA, pointOnB);
normalInB = pointOnA-pointOnB;
normalInB = m_cachedSeparatingAxis;
btScalar lenSqr =m_cachedSeparatingAxis.length2();
//valid normal

Some files were not shown because too many files have changed in this diff Show More