|
@@ -26,11 +26,18 @@ subject to the following restrictions:
|
|
|
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
|
|
#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
|
|
|
#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"
|
|
|
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.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
|
|
@@ -42,6 +49,24 @@ subject to the following restrictions:
|
|
|
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
|
|
|
|
|
|
|
|
|
+///for debug drawing
|
|
|
+
|
|
|
+//for debug rendering
|
|
|
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btConeShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btCylinderShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
|
|
|
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
|
|
|
:m_dispatcher1(dispatcher),
|
|
|
m_broadphasePairCache(pairCache),
|
|
@@ -92,27 +117,27 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
|
|
|
btAssert(collisionObject);
|
|
|
|
|
|
//check that the object isn't already added
|
|
|
- btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
|
|
|
+ btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
|
|
|
|
|
|
- m_collisionObjects.push_back(collisionObject);
|
|
|
+ m_collisionObjects.push_back(collisionObject);
|
|
|
|
|
|
- //calculate new AABB
|
|
|
- btTransform trans = collisionObject->getWorldTransform();
|
|
|
+ //calculate new AABB
|
|
|
+ btTransform trans = collisionObject->getWorldTransform();
|
|
|
|
|
|
- btVector3 minAabb;
|
|
|
- btVector3 maxAabb;
|
|
|
- collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
|
|
|
+ btVector3 minAabb;
|
|
|
+ btVector3 maxAabb;
|
|
|
+ collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
|
|
|
|
|
|
- int type = collisionObject->getCollisionShape()->getShapeType();
|
|
|
- collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
|
|
|
- minAabb,
|
|
|
- maxAabb,
|
|
|
- type,
|
|
|
- collisionObject,
|
|
|
- collisionFilterGroup,
|
|
|
- collisionFilterMask,
|
|
|
- m_dispatcher1,0
|
|
|
- )) ;
|
|
|
+ int type = collisionObject->getCollisionShape()->getShapeType();
|
|
|
+ collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
|
|
|
+ minAabb,
|
|
|
+ maxAabb,
|
|
|
+ type,
|
|
|
+ collisionObject,
|
|
|
+ collisionFilterGroup,
|
|
|
+ collisionFilterMask,
|
|
|
+ m_dispatcher1,0
|
|
|
+ )) ;
|
|
|
|
|
|
|
|
|
|
|
@@ -131,6 +156,16 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
|
|
|
minAabb -= contactThreshold;
|
|
|
maxAabb += contactThreshold;
|
|
|
|
|
|
+ if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
|
|
|
+ {
|
|
|
+ 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
|
|
@@ -173,6 +208,11 @@ void btCollisionWorld::updateAabbs()
|
|
|
}
|
|
|
|
|
|
|
|
|
+void btCollisionWorld::computeOverlappingPairs()
|
|
|
+{
|
|
|
+ BT_PROFILE("calculateOverlappingPairs");
|
|
|
+ m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
|
|
|
+}
|
|
|
|
|
|
void btCollisionWorld::performDiscreteCollisionDetection()
|
|
|
{
|
|
@@ -182,11 +222,7 @@ void btCollisionWorld::performDiscreteCollisionDetection()
|
|
|
|
|
|
updateAabbs();
|
|
|
|
|
|
- {
|
|
|
- BT_PROFILE("calculateOverlappingPairs");
|
|
|
- m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
|
|
|
- }
|
|
|
-
|
|
|
+ computeOverlappingPairs();
|
|
|
|
|
|
btDispatcher* dispatcher = getDispatcher();
|
|
|
{
|
|
@@ -226,20 +262,29 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
|
|
- btCollisionObject* collisionObject,
|
|
|
- const btCollisionShape* collisionShape,
|
|
|
- const btTransform& colObjWorldTransform,
|
|
|
- RayResultCallback& resultCallback)
|
|
|
+ btCollisionObject* collisionObject,
|
|
|
+ const btCollisionShape* collisionShape,
|
|
|
+ const btTransform& colObjWorldTransform,
|
|
|
+ RayResultCallback& resultCallback)
|
|
|
+{
|
|
|
+ btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform);
|
|
|
+ btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback);
|
|
|
+}
|
|
|
+
|
|
|
+void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
|
|
+ const btCollisionObjectWrapper* collisionObjectWrap,
|
|
|
+ RayResultCallback& resultCallback)
|
|
|
{
|
|
|
btSphereShape pointShape(btScalar(0.0));
|
|
|
pointShape.setMargin(0.f);
|
|
|
const btConvexShape* castShape = &pointShape;
|
|
|
+ const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
|
|
|
+ const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
|
|
|
|
|
|
if (collisionShape->isConvex())
|
|
|
{
|
|
|
-// BT_PROFILE("rayTestConvex");
|
|
|
+ // BT_PROFILE("rayTestConvex");
|
|
|
btConvexCast::CastResult castResult;
|
|
|
castResult.m_fraction = resultCallback.m_closestHitFraction;
|
|
|
|
|
@@ -268,10 +313,10 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
castResult.m_normal.normalize();
|
|
|
btCollisionWorld::LocalRayResult localRayResult
|
|
|
(
|
|
|
- collisionObject,
|
|
|
- 0,
|
|
|
- castResult.m_normal,
|
|
|
- castResult.m_fraction
|
|
|
+ collisionObjectWrap->getCollisionObject(),
|
|
|
+ 0,
|
|
|
+ castResult.m_normal,
|
|
|
+ castResult.m_fraction
|
|
|
);
|
|
|
|
|
|
bool normalInWorldSpace = true;
|
|
@@ -283,7 +328,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
} else {
|
|
|
if (collisionShape->isConcave())
|
|
|
{
|
|
|
-// BT_PROFILE("rayTestConcave");
|
|
|
+ // BT_PROFILE("rayTestConcave");
|
|
|
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
|
|
{
|
|
|
///optimized version for btBvhTriangleMeshShape
|
|
@@ -296,21 +341,21 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
|
|
|
{
|
|
|
btCollisionWorld::RayResultCallback* m_resultCallback;
|
|
|
- btCollisionObject* m_collisionObject;
|
|
|
+ const btCollisionObject* m_collisionObject;
|
|
|
btTriangleMeshShape* m_triangleMesh;
|
|
|
|
|
|
- btTransform m_colObjWorldTransform;
|
|
|
+ btTransform m_colObjWorldTransform;
|
|
|
|
|
|
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
|
|
|
- btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
|
|
|
- //@BP Mod
|
|
|
- btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
|
|
- m_resultCallback(resultCallback),
|
|
|
- m_collisionObject(collisionObject),
|
|
|
- m_triangleMesh(triangleMesh),
|
|
|
- m_colObjWorldTransform(colObjWorldTransform)
|
|
|
- {
|
|
|
- }
|
|
|
+ btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
|
|
|
+ //@BP Mod
|
|
|
+ btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
|
|
+ m_resultCallback(resultCallback),
|
|
|
+ m_collisionObject(collisionObject),
|
|
|
+ m_triangleMesh(triangleMesh),
|
|
|
+ m_colObjWorldTransform(colObjWorldTransform)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
|
|
|
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
|
|
@@ -319,10 +364,10 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
shapeInfo.m_shapePart = partId;
|
|
|
shapeInfo.m_triangleIndex = triangleIndex;
|
|
|
|
|
|
- btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
|
|
|
+ btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
|
|
|
|
|
|
btCollisionWorld::LocalRayResult rayResult
|
|
|
- (m_collisionObject,
|
|
|
+ (m_collisionObject,
|
|
|
&shapeInfo,
|
|
|
hitNormalWorld,
|
|
|
hitFraction);
|
|
@@ -333,7 +378,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
|
|
|
};
|
|
|
|
|
|
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
|
|
|
+ BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
|
|
|
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
|
|
|
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
|
|
|
} else
|
|
@@ -351,21 +396,21 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
|
|
|
{
|
|
|
btCollisionWorld::RayResultCallback* m_resultCallback;
|
|
|
- btCollisionObject* m_collisionObject;
|
|
|
+ const btCollisionObject* m_collisionObject;
|
|
|
btConcaveShape* m_triangleMesh;
|
|
|
|
|
|
- btTransform m_colObjWorldTransform;
|
|
|
+ btTransform m_colObjWorldTransform;
|
|
|
|
|
|
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
|
|
|
- btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
|
|
|
- //@BP Mod
|
|
|
- btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
|
|
- m_resultCallback(resultCallback),
|
|
|
- m_collisionObject(collisionObject),
|
|
|
- m_triangleMesh(triangleMesh),
|
|
|
- m_colObjWorldTransform(colObjWorldTransform)
|
|
|
- {
|
|
|
- }
|
|
|
+ btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
|
|
|
+ //@BP Mod
|
|
|
+ btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
|
|
+ m_resultCallback(resultCallback),
|
|
|
+ m_collisionObject(collisionObject),
|
|
|
+ m_triangleMesh(triangleMesh),
|
|
|
+ m_colObjWorldTransform(colObjWorldTransform)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
|
|
|
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
|
|
@@ -374,10 +419,10 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
shapeInfo.m_shapePart = partId;
|
|
|
shapeInfo.m_triangleIndex = triangleIndex;
|
|
|
|
|
|
- btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
|
|
|
+ btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
|
|
|
|
|
|
btCollisionWorld::LocalRayResult rayResult
|
|
|
- (m_collisionObject,
|
|
|
+ (m_collisionObject,
|
|
|
&shapeInfo,
|
|
|
hitNormalWorld,
|
|
|
hitFraction);
|
|
@@ -389,7 +434,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
};
|
|
|
|
|
|
|
|
|
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
|
|
|
+ BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
|
|
|
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
|
|
|
|
|
|
btVector3 rayAabbMinLocal = rayFromLocal;
|
|
@@ -400,27 +445,116 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
|
|
|
}
|
|
|
} else {
|
|
|
-// BT_PROFILE("rayTestCompound");
|
|
|
- ///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
|
|
|
+ // BT_PROFILE("rayTestCompound");
|
|
|
if (collisionShape->isCompound())
|
|
|
{
|
|
|
+ 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;
|
|
|
+ m_flags = m_userCallback->m_flags;
|
|
|
+ }
|
|
|
+ virtual bool needsCollision(btBroadphaseProxy* p) const
|
|
|
+ {
|
|
|
+ return m_userCallback->needsCollision(p);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ const btScalar result = m_userCallback->addSingleResult(r, b);
|
|
|
+ m_closestHitFraction = m_userCallback->m_closestHitFraction;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ struct RayTester : btDbvt::ICollide
|
|
|
+ {
|
|
|
+ const btCollisionObject* m_collisionObject;
|
|
|
+ const btCompoundShape* m_compoundShape;
|
|
|
+ const btTransform& m_colObjWorldTransform;
|
|
|
+ const btTransform& m_rayFromTrans;
|
|
|
+ const btTransform& m_rayToTrans;
|
|
|
+ RayResultCallback& m_resultCallback;
|
|
|
+
|
|
|
+ RayTester(const 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 ProcessLeaf(int i)
|
|
|
+ {
|
|
|
+ const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
|
|
|
+ const btTransform& childTrans = m_compoundShape->getChildTransform(i);
|
|
|
+ btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
|
|
|
+
|
|
|
+ btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans);
|
|
|
+ // replace collision shape so that callback can determine the triangle
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ LocalInfoAdder2 my_cb(i, &m_resultCallback);
|
|
|
+
|
|
|
+ rayTestSingleInternal(
|
|
|
+ m_rayFromTrans,
|
|
|
+ m_rayToTrans,
|
|
|
+ &tmpOb,
|
|
|
+ my_cb);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void Process(const btDbvtNode* leaf)
|
|
|
+ {
|
|
|
+ ProcessLeaf(leaf->dataAsInt);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
|
|
|
- int i=0;
|
|
|
- for (i=0;i<compoundShape->getNumChildShapes();i++)
|
|
|
+ const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
|
|
|
+
|
|
|
+
|
|
|
+ RayTester rayCB(
|
|
|
+ collisionObjectWrap->getCollisionObject(),
|
|
|
+ compoundShape,
|
|
|
+ colObjWorldTransform,
|
|
|
+ rayFromTrans,
|
|
|
+ rayToTrans,
|
|
|
+ resultCallback);
|
|
|
+#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
|
|
|
+ if (dbvt)
|
|
|
{
|
|
|
- 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);
|
|
|
- rayTestSingle(rayFromTrans,rayToTrans,
|
|
|
- collisionObject,
|
|
|
- childCollisionShape,
|
|
|
- childWorldTrans,
|
|
|
- resultCallback);
|
|
|
- // restore
|
|
|
- collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
|
|
|
+ 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.ProcessLeaf(i);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -428,11 +562,22 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
|
|
}
|
|
|
|
|
|
void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
|
|
|
- btCollisionObject* collisionObject,
|
|
|
- const btCollisionShape* collisionShape,
|
|
|
- const btTransform& colObjWorldTransform,
|
|
|
- ConvexResultCallback& resultCallback, btScalar allowedPenetration)
|
|
|
+ btCollisionObject* collisionObject,
|
|
|
+ const btCollisionShape* collisionShape,
|
|
|
+ const btTransform& colObjWorldTransform,
|
|
|
+ ConvexResultCallback& resultCallback, btScalar allowedPenetration)
|
|
|
{
|
|
|
+ btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform);
|
|
|
+ btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration);
|
|
|
+}
|
|
|
+
|
|
|
+void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
|
|
|
+ const btCollisionObjectWrapper* colObjWrap,
|
|
|
+ ConvexResultCallback& resultCallback, btScalar allowedPenetration)
|
|
|
+{
|
|
|
+ const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
|
|
|
+ const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
|
|
|
+
|
|
|
if (collisionShape->isConvex())
|
|
|
{
|
|
|
//BT_PROFILE("convexSweepConvex");
|
|
@@ -443,15 +588,15 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
btConvexShape* convexShape = (btConvexShape*) collisionShape;
|
|
|
btVoronoiSimplexSolver simplexSolver;
|
|
|
btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
|
|
|
-
|
|
|
+
|
|
|
btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
|
|
|
//btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
|
|
|
//btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
|
|
|
|
|
|
btConvexCast* castPtr = &convexCaster1;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
|
|
|
{
|
|
|
//add hit
|
|
@@ -461,13 +606,13 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
{
|
|
|
castResult.m_normal.normalize();
|
|
|
btCollisionWorld::LocalConvexResult localConvexResult
|
|
|
- (
|
|
|
- collisionObject,
|
|
|
- 0,
|
|
|
- castResult.m_normal,
|
|
|
- castResult.m_hitPoint,
|
|
|
- castResult.m_fraction
|
|
|
- );
|
|
|
+ (
|
|
|
+ colObjWrap->getCollisionObject(),
|
|
|
+ 0,
|
|
|
+ castResult.m_normal,
|
|
|
+ castResult.m_hitPoint,
|
|
|
+ castResult.m_fraction
|
|
|
+ );
|
|
|
|
|
|
bool normalInWorldSpace = true;
|
|
|
resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
|
|
@@ -492,17 +637,17 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
|
|
|
{
|
|
|
btCollisionWorld::ConvexResultCallback* m_resultCallback;
|
|
|
- btCollisionObject* m_collisionObject;
|
|
|
+ const btCollisionObject* m_collisionObject;
|
|
|
btTriangleMeshShape* m_triangleMesh;
|
|
|
|
|
|
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
|
|
|
- btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
|
|
|
- btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
|
|
|
- m_resultCallback(resultCallback),
|
|
|
- m_collisionObject(collisionObject),
|
|
|
- m_triangleMesh(triangleMesh)
|
|
|
- {
|
|
|
- }
|
|
|
+ btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* 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 )
|
|
@@ -514,7 +659,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
{
|
|
|
|
|
|
btCollisionWorld::LocalConvexResult convexResult
|
|
|
- (m_collisionObject,
|
|
|
+ (m_collisionObject,
|
|
|
&shapeInfo,
|
|
|
hitNormalLocal,
|
|
|
hitPointLocal,
|
|
@@ -530,30 +675,65 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
|
|
|
};
|
|
|
|
|
|
- BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
|
|
|
+ BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),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());
|
|
|
+ if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
|
|
|
+ {
|
|
|
+ btConvexCast::CastResult castResult;
|
|
|
+ castResult.m_allowedPenetration = allowedPenetration;
|
|
|
+ castResult.m_fraction = resultCallback.m_closestHitFraction;
|
|
|
+ btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
|
|
|
+ btContinuousConvexCollision convexCaster1(castShape,planeShape);
|
|
|
+ btConvexCast* castPtr = &convexCaster1;
|
|
|
+
|
|
|
+ if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
|
|
|
+ {
|
|
|
+ //add hit
|
|
|
+ if (castResult.m_normal.length2() > btScalar(0.0001))
|
|
|
+ {
|
|
|
+ if (castResult.m_fraction < resultCallback.m_closestHitFraction)
|
|
|
+ {
|
|
|
+ castResult.m_normal.normalize();
|
|
|
+ btCollisionWorld::LocalConvexResult localConvexResult
|
|
|
+ (
|
|
|
+ colObjWrap->getCollisionObject(),
|
|
|
+ 0,
|
|
|
+ castResult.m_normal,
|
|
|
+ castResult.m_hitPoint,
|
|
|
+ castResult.m_fraction
|
|
|
+ );
|
|
|
|
|
|
- //ConvexCast::CastResult
|
|
|
- struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
|
|
|
+ bool normalInWorldSpace = true;
|
|
|
+ resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else
|
|
|
{
|
|
|
- btCollisionWorld::ConvexResultCallback* m_resultCallback;
|
|
|
- btCollisionObject* m_collisionObject;
|
|
|
- btConcaveShape* m_triangleMesh;
|
|
|
+ //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
|
|
|
+ {
|
|
|
+ btCollisionWorld::ConvexResultCallback* m_resultCallback;
|
|
|
+ const btCollisionObject* m_collisionObject;
|
|
|
+ btConcaveShape* m_triangleMesh;
|
|
|
|
|
|
- BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
|
|
|
- btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
|
|
|
+ BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
|
|
|
+ btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
|
|
|
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
|
|
|
m_resultCallback(resultCallback),
|
|
|
m_collisionObject(collisionObject),
|
|
@@ -562,42 +742,44 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
}
|
|
|
|
|
|
|
|
|
- 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)
|
|
|
+ virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
|
|
|
{
|
|
|
-
|
|
|
- btCollisionWorld::LocalConvexResult convexResult
|
|
|
- (m_collisionObject,
|
|
|
- &shapeInfo,
|
|
|
- hitNormalLocal,
|
|
|
- hitPointLocal,
|
|
|
- hitFraction);
|
|
|
-
|
|
|
- bool normalInWorldSpace = false;
|
|
|
-
|
|
|
- return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
|
|
|
+ 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;
|
|
|
}
|
|
|
- return hitFraction;
|
|
|
- }
|
|
|
|
|
|
- };
|
|
|
-
|
|
|
- BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
|
|
|
- tccb.m_hitFraction = resultCallback.m_closestHitFraction;
|
|
|
- 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);
|
|
|
+ };
|
|
|
+
|
|
|
+ BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),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!
|
|
@@ -611,16 +793,41 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
|
|
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);
|
|
|
- objectQuerySingle(castShape, convexFromTrans,convexToTrans,
|
|
|
- collisionObject,
|
|
|
- childCollisionShape,
|
|
|
- childWorldTrans,
|
|
|
- resultCallback, allowedPenetration);
|
|
|
- // restore
|
|
|
- collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
|
|
|
+
|
|
|
+ struct LocalInfoAdder : public ConvexResultCallback {
|
|
|
+ ConvexResultCallback* m_userCallback;
|
|
|
+ int m_i;
|
|
|
+
|
|
|
+ LocalInfoAdder (int i, ConvexResultCallback *user)
|
|
|
+ : m_userCallback(user), m_i(i)
|
|
|
+ {
|
|
|
+ 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;
|
|
|
+ shapeInfo.m_shapePart = -1;
|
|
|
+ shapeInfo.m_triangleIndex = m_i;
|
|
|
+ if (r.m_localShapeInfo == NULL)
|
|
|
+ r.m_localShapeInfo = &shapeInfo;
|
|
|
+ const btScalar result = m_userCallback->addSingleResult(r, b);
|
|
|
+ m_closestHitFraction = m_userCallback->m_closestHitFraction;
|
|
|
+ return result;
|
|
|
+
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ LocalInfoAdder my_cb(i, &resultCallback);
|
|
|
+
|
|
|
+ btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans);
|
|
|
+
|
|
|
+ objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans,
|
|
|
+ &tmpObj,my_cb, allowedPenetration);
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -641,10 +848,10 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
|
|
btCollisionWorld::RayResultCallback& m_resultCallback;
|
|
|
|
|
|
btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
|
|
|
- :m_rayFromWorld(rayFromWorld),
|
|
|
- m_rayToWorld(rayToWorld),
|
|
|
- m_world(world),
|
|
|
- m_resultCallback(resultCallback)
|
|
|
+ :m_rayFromWorld(rayFromWorld),
|
|
|
+ m_rayToWorld(rayToWorld),
|
|
|
+ m_world(world),
|
|
|
+ m_resultCallback(resultCallback)
|
|
|
{
|
|
|
m_rayFromTrans.setIdentity();
|
|
|
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
|
@@ -666,7 +873,7 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
virtual bool process(const btBroadphaseProxy* proxy)
|
|
|
{
|
|
@@ -697,9 +904,9 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
|
|
{
|
|
|
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
|
|
collisionObject,
|
|
|
- collisionObject->getCollisionShape(),
|
|
|
- collisionObject->getWorldTransform(),
|
|
|
- m_resultCallback);
|
|
|
+ collisionObject->getCollisionShape(),
|
|
|
+ collisionObject->getWorldTransform(),
|
|
|
+ m_resultCallback);
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
@@ -771,13 +978,13 @@ struct btSingleSweepCallback : public btBroadphaseRayCallback
|
|
|
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
|
|
|
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
|
|
m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
|
|
|
- collisionObject,
|
|
|
- collisionObject->getCollisionShape(),
|
|
|
- collisionObject->getWorldTransform(),
|
|
|
- m_resultCallback,
|
|
|
- m_allowedCcdPenetration);
|
|
|
+ collisionObject,
|
|
|
+ collisionObject->getCollisionShape(),
|
|
|
+ collisionObject->getWorldTransform(),
|
|
|
+ m_resultCallback,
|
|
|
+ m_allowedCcdPenetration);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
};
|
|
@@ -792,7 +999,7 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
|
|
|
/// and for each object with ray-aabb overlap, perform an exact ray test
|
|
|
/// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
btTransform convexFromTrans,convexToTrans;
|
|
|
convexFromTrans = convexFromWorld;
|
|
@@ -801,13 +1008,13 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
|
|
|
/* Compute AABB that encompasses angular movement */
|
|
|
{
|
|
|
btVector3 linVel, angVel;
|
|
|
- btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
|
|
|
+ btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel);
|
|
|
btVector3 zeroLinVel;
|
|
|
zeroLinVel.setValue(0,0,0);
|
|
|
btTransform R;
|
|
|
R.setIdentity ();
|
|
|
R.setRotation (convexFromTrans.getRotation());
|
|
|
- castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
|
|
|
+ castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
|
|
|
}
|
|
|
|
|
|
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
|
@@ -835,12 +1042,498 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
|
|
|
{
|
|
|
objectQuerySingle(castShape, convexFromTrans,convexToTrans,
|
|
|
collisionObject,
|
|
|
- collisionObject->getCollisionShape(),
|
|
|
- collisionObject->getWorldTransform(),
|
|
|
- resultCallback,
|
|
|
- allowedCcdPenetration);
|
|
|
+ collisionObject->getCollisionShape(),
|
|
|
+ collisionObject->getWorldTransform(),
|
|
|
+ resultCallback,
|
|
|
+ allowedCcdPenetration);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+struct btBridgedManifoldResult : public btManifoldResult
|
|
|
+{
|
|
|
+
|
|
|
+ btCollisionWorld::ContactResultCallback& m_resultCallback;
|
|
|
+
|
|
|
+ btBridgedManifoldResult( const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap,btCollisionWorld::ContactResultCallback& resultCallback )
|
|
|
+ :btManifoldResult(obj0Wrap,obj1Wrap),
|
|
|
+ m_resultCallback(resultCallback)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
|
|
|
+ {
|
|
|
+ bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
|
|
|
+ btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
|
|
|
+ btVector3 localA;
|
|
|
+ btVector3 localB;
|
|
|
+ if (isSwapped)
|
|
|
+ {
|
|
|
+ localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
|
|
|
+ localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
|
|
|
+ localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
|
|
|
+ }
|
|
|
+
|
|
|
+ btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
|
|
|
+ newPt.m_positionWorldOnA = pointA;
|
|
|
+ newPt.m_positionWorldOnB = pointInWorld;
|
|
|
+
|
|
|
+ //BP mod, store contact triangles.
|
|
|
+ if (isSwapped)
|
|
|
+ {
|
|
|
+ newPt.m_partId0 = m_partId1;
|
|
|
+ newPt.m_partId1 = m_partId0;
|
|
|
+ newPt.m_index0 = m_index1;
|
|
|
+ newPt.m_index1 = m_index0;
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ newPt.m_partId0 = m_partId0;
|
|
|
+ newPt.m_partId1 = m_partId1;
|
|
|
+ newPt.m_index0 = m_index0;
|
|
|
+ newPt.m_index1 = m_index1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //experimental feature info, for per-triangle material etc.
|
|
|
+ const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
|
|
|
+ const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
|
|
|
+ m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+struct btSingleContactCallback : public btBroadphaseAabbCallback
|
|
|
+{
|
|
|
+
|
|
|
+ btCollisionObject* m_collisionObject;
|
|
|
+ btCollisionWorld* m_world;
|
|
|
+ btCollisionWorld::ContactResultCallback& m_resultCallback;
|
|
|
+
|
|
|
+
|
|
|
+ btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
|
|
|
+ :m_collisionObject(collisionObject),
|
|
|
+ m_world(world),
|
|
|
+ m_resultCallback(resultCallback)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual bool process(const btBroadphaseProxy* proxy)
|
|
|
+ {
|
|
|
+ btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
|
|
+ if (collisionObject == m_collisionObject)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ //only perform raycast if filterMask matches
|
|
|
+ if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
|
|
+ {
|
|
|
+ btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform());
|
|
|
+ btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform());
|
|
|
+
|
|
|
+ btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
|
|
|
+ if (algorithm)
|
|
|
+ {
|
|
|
+ btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
|
|
|
+ //discrete collision detection query
|
|
|
+
|
|
|
+ algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
|
|
|
+
|
|
|
+ algorithm->~btCollisionAlgorithm();
|
|
|
+ m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback.
|
|
|
+///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
|
|
|
+void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback)
|
|
|
+{
|
|
|
+ btVector3 aabbMin,aabbMax;
|
|
|
+ colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
|
|
|
+ btSingleContactCallback contactCB(colObj,this,resultCallback);
|
|
|
+
|
|
|
+ m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
|
|
|
+///it reports one or more contact points (including the one with deepest penetration)
|
|
|
+void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
|
|
|
+{
|
|
|
+ btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform());
|
|
|
+ btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform());
|
|
|
+
|
|
|
+ btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB);
|
|
|
+ if (algorithm)
|
|
|
+ {
|
|
|
+ btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
|
|
|
+ //discrete collision detection query
|
|
|
+ algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
|
|
|
+
|
|
|
+ algorithm->~btCollisionAlgorithm();
|
|
|
+ getDispatcher()->freeCollisionAlgorithm(algorithm);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
|
|
|
+{
|
|
|
+ btIDebugDraw* m_debugDrawer;
|
|
|
+ btVector3 m_color;
|
|
|
+ btTransform m_worldTrans;
|
|
|
+
|
|
|
+public:
|
|
|
+
|
|
|
+ DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
|
|
|
+ m_debugDrawer(debugDrawer),
|
|
|
+ m_color(color),
|
|
|
+ m_worldTrans(worldTrans)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
|
|
+ {
|
|
|
+ processTriangle(triangle,partId,triangleIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
|
|
+ {
|
|
|
+ (void)partId;
|
|
|
+ (void)triangleIndex;
|
|
|
+
|
|
|
+ btVector3 wv0,wv1,wv2;
|
|
|
+ wv0 = m_worldTrans*triangle[0];
|
|
|
+ wv1 = m_worldTrans*triangle[1];
|
|
|
+ wv2 = m_worldTrans*triangle[2];
|
|
|
+ btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
|
|
|
+
|
|
|
+ if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals )
|
|
|
+ {
|
|
|
+ btVector3 normal = (wv1-wv0).cross(wv2-wv0);
|
|
|
+ normal.normalize();
|
|
|
+ btVector3 normalColor(1,1,0);
|
|
|
+ m_debugDrawer->drawLine(center,center+normal,normalColor);
|
|
|
+ }
|
|
|
+ m_debugDrawer->drawLine(wv0,wv1,m_color);
|
|
|
+ m_debugDrawer->drawLine(wv1,wv2,m_color);
|
|
|
+ m_debugDrawer->drawLine(wv2,wv0,m_color);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
|
|
|
+{
|
|
|
+ // Draw a small simplex at the center of the object
|
|
|
+ getDebugDrawer()->drawTransform(worldTransform,1);
|
|
|
+
|
|
|
+ if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
|
|
|
+ {
|
|
|
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
|
|
+ for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
|
|
|
+ {
|
|
|
+ btTransform childTrans = compoundShape->getChildTransform(i);
|
|
|
+ const btCollisionShape* colShape = compoundShape->getChildShape(i);
|
|
|
+ debugDrawObject(worldTransform*childTrans,colShape,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:
|
|
|
+ {
|
|
|
+
|
|
|
+ /// for polyhedral shapes
|
|
|
+ if (shape->isPolyhedral())
|
|
|
+ {
|
|
|
+ btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
|
|
|
+
|
|
|
+ int i;
|
|
|
+ if (polyshape->getConvexPolyhedron())
|
|
|
+ {
|
|
|
+ const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
|
|
|
+ for (i=0;i<poly->m_faces.size();i++)
|
|
|
+ {
|
|
|
+ btVector3 centroid(0,0,0);
|
|
|
+ int numVerts = poly->m_faces[i].m_indices.size();
|
|
|
+ if (numVerts)
|
|
|
+ {
|
|
|
+ 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);
|
|
|
+ if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
|
|
|
+ {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void btCollisionWorld::debugDrawWorld()
|
|
|
+{
|
|
|
+ if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
|
|
|
+ {
|
|
|
+ int numManifolds = getDispatcher()->getNumManifolds();
|
|
|
+ btVector3 color(1,1,0);
|
|
|
+ for (int i=0;i<numManifolds;i++)
|
|
|
+ {
|
|
|
+ btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
|
|
|
+ //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
|
|
|
+ //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
|
|
|
+
|
|
|
+ int numContacts = contactManifold->getNumContacts();
|
|
|
+ for (int j=0;j<numContacts;j++)
|
|
|
+ {
|
|
|
+ btManifoldPoint& cp = contactManifold->getContactPoint(j);
|
|
|
+ getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for ( i=0;i<m_collisionObjects.size();i++)
|
|
|
+ {
|
|
|
+ btCollisionObject* colObj = m_collisionObjects[i];
|
|
|
+ if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
|
|
|
+ {
|
|
|
+ if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
|
|
|
+ {
|
|
|
+ btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
|
|
|
+ switch(colObj->getActivationState())
|
|
|
+ {
|
|
|
+ case ACTIVE_TAG:
|
|
|
+ color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
|
|
|
+ case ISLAND_SLEEPING:
|
|
|
+ color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
|
|
|
+ case WANTS_DEACTIVATION:
|
|
|
+ color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
|
|
|
+ case DISABLE_DEACTIVATION:
|
|
|
+ color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
|
|
|
+ case DISABLE_SIMULATION:
|
|
|
+ color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
|
|
|
+ }
|
|
|
+ if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
|
|
+ {
|
|
|
+ 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(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
|
|
|
+ {
|
|
|
+ colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
|
|
|
+ minAabb2 -= contactThreshold;
|
|
|
+ maxAabb2 += contactThreshold;
|
|
|
+ minAabb.setMin(minAabb2);
|
|
|
+ maxAabb.setMax(maxAabb2);
|
|
|
+ }
|
|
|
+
|
|
|
+ m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ //serialize all collision objects
|
|
|
+ for (i=0;i<m_collisionObjects.size();i++)
|
|
|
+ {
|
|
|
+ btCollisionObject* colObj = m_collisionObjects[i];
|
|
|
+ if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
|
|
|
+ {
|
|
|
+ colObj->serializeSingleObject(serializer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ///keep track of shapes already serialized
|
|
|
+ btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
|
|
|
+
|
|
|
+ for (i=0;i<m_collisionObjects.size();i++)
|
|
|
+ {
|
|
|
+ btCollisionObject* colObj = m_collisionObjects[i];
|
|
|
+ btCollisionShape* shape = colObj->getCollisionShape();
|
|
|
+
|
|
|
+ if (!serializedShapes.find(shape))
|
|
|
+ {
|
|
|
+ serializedShapes.insert(shape,shape);
|
|
|
+ shape->serializeSingleShape(serializer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void btCollisionWorld::serialize(btSerializer* serializer)
|
|
|
+{
|
|
|
+
|
|
|
+ serializer->startSerialization();
|
|
|
+
|
|
|
+ serializeCollisionObjects(serializer);
|
|
|
+
|
|
|
+ serializer->finishSerialization();
|
|
|
+}
|
|
|
+
|