update Bullet physics sdk to latest trunk/version 2.78
authorErwin Coumans <blender@erwincoumans.com>
Sat, 12 Mar 2011 20:34:17 +0000 (20:34 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Sat, 12 Mar 2011 20:34:17 +0000 (20:34 +0000)
add PhysicsConstraints.exportBulletFile(char* fileName) python command
I'll be checking the bf-committers mailing list, in case this commit broke stuff
scons needs to be updated, I'll do that in a second.

262 files changed:
extern/bullet2/CMakeLists.txt
extern/bullet2/src/Bullet-C-Api.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMaterial.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h
extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactMassUtil.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h
extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h
extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h
extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h
extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h
extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h
extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h
extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h
extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h
extern/bullet2/src/BulletCollision/Gimpact/gim_geometry.h
extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h
extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h
extern/bullet2/src/BulletCollision/Gimpact/gim_math.h
extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h
extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h
extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp
extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp [deleted file]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h [deleted file]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
extern/bullet2/src/BulletDynamics/Character/btCharacterControllerInterface.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btActionInterface.h
extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h
extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp [new file with mode: 0644]
extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h [new file with mode: 0644]
extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
extern/bullet2/src/BulletSoftBody/btSoftBody.h
extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyData.h [new file with mode: 0644]
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
extern/bullet2/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h [new file with mode: 0644]
extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h [new file with mode: 0644]
extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp
extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
extern/bullet2/src/LinearMath/btAlignedObjectArray.h
extern/bullet2/src/LinearMath/btConvexHull.cpp
extern/bullet2/src/LinearMath/btConvexHull.h
extern/bullet2/src/LinearMath/btDefaultMotionState.h
extern/bullet2/src/LinearMath/btHashMap.h
extern/bullet2/src/LinearMath/btIDebugDraw.h
extern/bullet2/src/LinearMath/btMatrix3x3.h
extern/bullet2/src/LinearMath/btMinMax.h
extern/bullet2/src/LinearMath/btPoolAllocator.h
extern/bullet2/src/LinearMath/btQuaternion.h
extern/bullet2/src/LinearMath/btQuickprof.cpp
extern/bullet2/src/LinearMath/btQuickprof.h
extern/bullet2/src/LinearMath/btScalar.h
extern/bullet2/src/LinearMath/btSerializer.cpp [new file with mode: 0644]
extern/bullet2/src/LinearMath/btSerializer.h [new file with mode: 0644]
extern/bullet2/src/LinearMath/btTransform.h
extern/bullet2/src/LinearMath/btTransformUtil.h
extern/bullet2/src/LinearMath/btVector3.h
extern/bullet2/src/btBulletCollisionCommon.h
extern/bullet2/src/btBulletDynamicsCommon.h
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h

index 74f0fc2ab56934701971f333aea0fec769d65ba2..4b85b0d72d112299d4b07d88ebe27fdacf612404 100644 (file)
@@ -107,7 +107,6 @@ set(SRC
        src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
        src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp
        src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
-       src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp
        src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
        src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
        src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
@@ -119,6 +118,7 @@ set(SRC
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
+       src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -132,6 +132,7 @@ set(SRC
        src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
        src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
        src/BulletDynamics/Vehicle/btWheelInfo.cpp
+       src/BulletSoftBody/btDefaultSoftBodySolver.cpp
        src/BulletSoftBody/btSoftBody.cpp
        src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
        src/BulletSoftBody/btSoftBodyHelpers.cpp
@@ -143,6 +144,8 @@ set(SRC
        src/LinearMath/btConvexHull.cpp
        src/LinearMath/btGeometryUtil.cpp
        src/LinearMath/btQuickprof.cpp
+       src/LinearMath/btSerializer.cpp
+       
 
        src/Bullet-C-Api.h
        src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
@@ -247,8 +250,7 @@ set(SRC
        src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
        src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
        src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
-       src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
-       src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
+?      src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
        src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
        src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
        src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
@@ -264,6 +266,7 @@ set(SRC
        src/BulletDynamics/ConstraintSolver/btContactConstraint.h
        src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
+       src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
        src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
        src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
        src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
@@ -282,6 +285,7 @@ set(SRC
        src/BulletDynamics/Vehicle/btRaycastVehicle.h
        src/BulletDynamics/Vehicle/btVehicleRaycaster.h
        src/BulletDynamics/Vehicle/btWheelInfo.h
+       src/BulletSoftBody/btDefaultSoftBodySolver.h
        src/BulletSoftBody/btSoftBody.h
        src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
        src/BulletSoftBody/btSoftBodyHelpers.h
@@ -310,11 +314,13 @@ set(SRC
        src/LinearMath/btQuickprof.h
        src/LinearMath/btRandom.h
        src/LinearMath/btScalar.h
+       src/LinearMath/btSerializer.h
        src/LinearMath/btSimdMinMax.h
        src/LinearMath/btStackAlloc.h
        src/LinearMath/btTransform.h
        src/LinearMath/btTransformUtil.h
        src/LinearMath/btVector3.h
+       
        src/btBulletCollisionCommon.h
        src/btBulletDynamicsCommon.h
 )
index d2123047c684bb699a5c4e745039de5da2c18189..f309aba2816886f164ee6f3e3d61260da6274f57 100644 (file)
@@ -65,7 +65,7 @@ extern "C" {
        Create and Delete a Physics SDK 
 */
 
-       extern  plPhysicsSdkHandle      plNewBulletSdk(void); //this could be also another sdk, like ODE, PhysX etc.
+       extern  plPhysicsSdkHandle      plNewBulletSdk(); //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(void);
+       extern  plCollisionShapeHandle plNewCompoundShape();
        extern  void    plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
 
        extern  void plDeleteShape(plCollisionShapeHandle shape);
 
        /* Convex Meshes */
-       extern  plCollisionShapeHandle plNewConvexHullShape(void);
+       extern  plCollisionShapeHandle plNewConvexHullShape();
        extern  void            plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
 /* Concave static triangle meshes */
-       extern  plMeshInterfaceHandle              plNewMeshInterface(void);
+       extern  plMeshInterfaceHandle              plNewMeshInterface();
        extern  void            plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
        extern  plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
 
@@ -147,6 +147,7 @@ extern "C" {
        extern  void plSetPosition(plRigidBodyHandle object, const plVector3 position);
        extern  void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
        extern  void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
+       extern  void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
 
        typedef struct plRayCastResult {
                plRigidBodyHandle               m_body;  
index cad21b4cad29a3db55773b7ec0236ebc31a7b9c2..07167af3baf540eef6a5f1cf5cd38c68cd03958e 100644 (file)
@@ -150,6 +150,8 @@ public:
        virtual void  getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
        
        virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+       virtual void    aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
+
        
        void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
        ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
@@ -285,6 +287,31 @@ void       btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,cons
        }
 }
 
+template <typename BP_FP_INT_TYPE>
+void   btAxisSweep3Internal<BP_FP_INT_TYPE>::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
+{
+       if (m_raycastAccelerator)
+       {
+               m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback);
+       } else
+       {
+               //choose axis?
+               BP_FP_INT_TYPE axis = 0;
+               //for each proxy
+               for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
+               {
+                       if (m_pEdges[axis][i].IsMax())
+                       {
+                               Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
+                               if (TestAabbAgainstAabb2(aabbMin,aabbMax,handle->m_aabbMin,handle->m_aabbMax))
+                               {
+                                       callback.process(handle);
+                               }
+                       }
+               }
+       }
+}
+
 
 
 template <typename BP_FP_INT_TYPE>
index b7bbaf512aed1dbf1e00fc09de8706d25e136921..fe414effbfc490fed4e1d79f28daff664ae8787c 100644 (file)
@@ -26,7 +26,14 @@ class btOverlappingPairCache;
 
 
 
-struct btBroadphaseRayCallback
+struct btBroadphaseAabbCallback
+{
+       virtual ~btBroadphaseAabbCallback() {}
+       virtual bool    process(const btBroadphaseProxy* proxy) = 0;
+};
+
+
+struct btBroadphaseRayCallback : public btBroadphaseAabbCallback
 {
        ///added some cached data to accelerate ray-AABB tests
        btVector3               m_rayDirectionInverse;
@@ -34,7 +41,6 @@ struct        btBroadphaseRayCallback
        btScalar                m_lambda_max;
 
        virtual ~btBroadphaseRayCallback() {}
-       virtual bool    process(const btBroadphaseProxy* proxy) = 0;
 };
 
 #include "LinearMath/btVector3.h"
@@ -54,6 +60,8 @@ public:
 
        virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
 
+       virtual void    aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0;
+
        ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
        virtual void    calculateOverlappingPairs(btDispatcher* dispatcher)=0;
 
@@ -65,7 +73,7 @@ public:
        virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
 
        ///reset broadphase internal structures, to ensure determinism/reproducability
-       virtual void resetPool(btDispatcher* dispatcher) {};
+       virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; };
 
        virtual void    printStats() = 0;
 
index a9f3223798b7c880ac63600b2a0be35545d93877..62d349739c3ce4568cc1693725c65fb9ceaedad4 100644 (file)
@@ -46,6 +46,8 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
        UNIFORM_SCALING_SHAPE_PROXYTYPE,
        MINKOWSKI_SUM_SHAPE_PROXYTYPE,
        MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+       BOX_2D_SHAPE_PROXYTYPE,
+       CONVEX_2D_SHAPE_PROXYTYPE,
        CUSTOM_CONVEX_SHAPE_TYPE,
 //concave shapes
 CONCAVE_SHAPES_START_HERE,
@@ -139,6 +141,11 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
                return (proxyType < CONCAVE_SHAPES_START_HERE);
        }
 
+       static SIMD_FORCE_INLINE bool   isNonMoving(int proxyType)
+       {
+               return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE));
+       }
+
        static SIMD_FORCE_INLINE bool   isConcave(int proxyType)
        {
                return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
@@ -148,14 +155,22 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
        {
                return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
        }
+
+       static SIMD_FORCE_INLINE bool   isSoftBody(int proxyType)
+       {
+               return (proxyType == SOFTBODY_SHAPE_PROXYTYPE);
+       }
+
        static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
        {
                return (proxyType == STATIC_PLANE_PROXYTYPE);
        }
-       static SIMD_FORCE_INLINE bool isSoftBody(int proxyType)
+
+       static SIMD_FORCE_INLINE bool isConvex2d(int proxyType)
        {
-               return (proxyType == SOFTBODY_SHAPE_PROXYTYPE);
+               return (proxyType == BOX_2D_SHAPE_PROXYTYPE) || (proxyType == CONVEX_2D_SHAPE_PROXYTYPE);
        }
+
        
 }
 ;
index 1618ad9fdd371f49304d267b1d596aaa0001e6c0..0d8bca41c8efc9cad696fec97b8d8e80b3936e37 100644 (file)
@@ -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:
 
index a6e36b47049253267116600cf45f706d701013d7..95443af507017cabbc1f67ed34635cb92bdacfa0 100644 (file)
@@ -61,7 +61,7 @@ static void                                           getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
        if(node->isinternal())
        {
                getmaxdepth(node->childs[0],depth+1,maxdepth);
-               getmaxdepth(node->childs[0],depth+1,maxdepth);
+               getmaxdepth(node->childs[1],depth+1,maxdepth);
        } else maxdepth=btMax(maxdepth,depth);
 }
 
@@ -238,7 +238,7 @@ static void                                         split(  const tNodeArray& leaves,
        right.resize(0);
        for(int i=0,ni=leaves.size();i<ni;++i)
        {
-               if(dot(axis,leaves[i]->volume.Center()-org)<0)
+               if(btDot(axis,leaves[i]->volume.Center()-org)<0)
                        left.push_back(leaves[i]);
                else
                        right.push_back(leaves[i]);
@@ -319,7 +319,7 @@ static btDbvtNode*                  topdown(btDbvt* pdbvt,
                                const btVector3 x=leaves[i]->volume.Center()-org;
                                for(int j=0;j<3;++j)
                                {
-                                       ++splitcount[j][dot(x,axis[j])>0?1:0];
+                                       ++splitcount[j][btDot(x,axis[j])>0?1:0];
                                }
                        }
                        for( i=0;i<3;++i)
index d3cf1e750397aea9403f731220ac8d8589333de3..2bb8ef5d2a7faf8d905b48c503e51f4c5783004c 100644 (file)
@@ -32,7 +32,7 @@ subject to the following restrictions:
 #define DBVT_IMPL_SSE                  1       // SSE
 
 // Template implementation of ICollide
-#ifdef WIN32
+#ifdef _WIN32
 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
 #define        DBVT_USE_TEMPLATE               1
 #else
@@ -57,7 +57,7 @@ subject to the following restrictions:
 // Specific methods implementation
 
 //SSE gives errors on a MSVC 7.1
-#ifdef BT_USE_SSE
+#if defined (BT_USE_SSE) && defined (_WIN32)
 #define DBVT_SELECT_IMPL               DBVT_IMPL_SSE
 #define DBVT_MERGE_IMPL                        DBVT_IMPL_SSE
 #define DBVT_INT0_IMPL                 DBVT_IMPL_SSE
@@ -92,7 +92,7 @@ subject to the following restrictions:
 #endif
 
 #if DBVT_USE_MEMMOVE
-#ifndef __CELLOS_LV2__
+#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
 #include <memory.h>
 #endif
 #include <string.h>
@@ -484,8 +484,8 @@ DBVT_INLINE int             btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) con
        case    (1+2+4):        px=btVector3(mx.x(),mx.y(),mx.z());
                pi=btVector3(mi.x(),mi.y(),mi.z());break;
        }
-       if((dot(n,px)+o)<0)             return(-1);
-       if((dot(n,pi)+o)>=0)    return(+1);
+       if((btDot(n,px)+o)<0)           return(-1);
+       if((btDot(n,pi)+o)>=0)  return(+1);
        return(0);
 }
 
@@ -496,7 +496,7 @@ DBVT_INLINE btScalar        btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned si
        const btVector3         p(      b[(signs>>0)&1]->x(),
                b[(signs>>1)&1]->y(),
                b[(signs>>2)&1]->z());
-       return(dot(p,v));
+       return(btDot(p,v));
 }
 
 //
@@ -947,6 +947,7 @@ inline void         btDbvt::rayTestInternal(        const btDbvtNode* root,
                                                                const btVector3& aabbMax,
                                                                DBVT_IPOLICY) const
 {
+        (void) rayTo;
        DBVT_CHECKTYPE
        if(root)
        {
@@ -961,8 +962,8 @@ inline void         btDbvt::rayTestInternal(        const btDbvtNode* root,
                do      
                {
                        const btDbvtNode*       node=stack[--depth];
-                       bounds[0] = node->volume.Mins()+aabbMin;
-                       bounds[1] = node->volume.Maxs()+aabbMax;
+                       bounds[0] = node->volume.Mins()-aabbMax;
+                       bounds[1] = node->volume.Maxs()-aabbMin;
                        btScalar tmin=1.f,lambda_min=0.f;
                        unsigned int result1=false;
                        result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
@@ -1000,11 +1001,11 @@ inline void             btDbvt::rayTest(        const btDbvtNode* root,
                        btVector3 rayDir = (rayTo-rayFrom);
                        rayDir.normalize ();
 
-                       ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+                       ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
                        btVector3 rayDirectionInverse;
-                       rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-                       rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-                       rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+                       rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+                       rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+                       rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
                        unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
 
                        btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
index f231717af172ece16b94c0085d01c9bf5107518a..75cfac64368d1e4321a83e5b76d236db26a6b864 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  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.
@@ -12,6 +12,7 @@ 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.
 */
+
 ///btDbvtBroadphase implementation by Nathanael Presson
 
 #include "btDbvtBroadphase.h"
@@ -123,7 +124,7 @@ btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
        m_deferedcollide        =       false;
        m_needcleanup           =       true;
        m_releasepaircache      =       (paircache!=0)?false:true;
-       m_prediction            =       1/(btScalar)2;
+       m_prediction            =       0;
        m_stageCurrent          =       0;
        m_fixedleft                     =       0;
        m_fupdates                      =       1;
@@ -249,6 +250,34 @@ void       btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
 
 }
 
+
+struct BroadphaseAabbTester : btDbvt::ICollide
+{
+       btBroadphaseAabbCallback& m_aabbCallback;
+       BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback)
+               :m_aabbCallback(orgCallback)
+       {
+       }
+       void                                    Process(const btDbvtNode* leaf)
+       {
+               btDbvtProxy*    proxy=(btDbvtProxy*)leaf->data;
+               m_aabbCallback.process(proxy);
+       }
+};     
+
+void   btDbvtBroadphase::aabbTest(const btVector3& aabbMin,const btVector3& aabbMax,btBroadphaseAabbCallback& aabbCallback)
+{
+       BroadphaseAabbTester callback(aabbCallback);
+
+       const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(aabbMin,aabbMax);
+               //process all children, that overlap with  the given AABB bounds
+       m_sets[0].collideTV(m_sets[0].m_root,bounds,callback);
+       m_sets[1].collideTV(m_sets[1].m_root,bounds,callback);
+
+}
+
+
+
 //
 void                                                   btDbvtBroadphase::setAabb(              btBroadphaseProxy* absproxy,
                                                                                                                  const btVector3& aabbMin,
@@ -316,6 +345,47 @@ void                                                       btDbvtBroadphase::setAabb(              btBroadphaseProxy* absproxy,
        }
 }
 
+
+//
+void                                                   btDbvtBroadphase::setAabbForceUpdate(           btBroadphaseProxy* absproxy,
+                                                                                                                 const btVector3& aabbMin,
+                                                                                                                 const btVector3& aabbMax,
+                                                                                                                 btDispatcher* /*dispatcher*/)
+{
+       btDbvtProxy*                                            proxy=(btDbvtProxy*)absproxy;
+       ATTRIBUTE_ALIGNED16(btDbvtVolume)       aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
+       bool    docollide=false;
+       if(proxy->stage==STAGECOUNT)
+       {/* fixed -> dynamic set        */ 
+               m_sets[1].remove(proxy->leaf);
+               proxy->leaf=m_sets[0].insert(aabb,proxy);
+               docollide=true;
+       }
+       else
+       {/* dynamic set                         */ 
+               ++m_updates_call;
+               /* Teleporting                  */ 
+               m_sets[0].update(proxy->leaf,aabb);
+               ++m_updates_done;
+               docollide=true;
+       }
+       listremove(proxy,m_stageRoots[proxy->stage]);
+       proxy->m_aabbMin = aabbMin;
+       proxy->m_aabbMax = aabbMax;
+       proxy->stage    =       m_stageCurrent;
+       listappend(proxy,m_stageRoots[m_stageCurrent]);
+       if(docollide)
+       {
+               m_needcleanup=true;
+               if(!m_deferedcollide)
+               {
+                       btDbvtTreeCollider      collider(this);
+                       m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
+                       m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
+               }
+       }       
+}
+
 //
 void                                                   btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
 {
@@ -571,7 +641,6 @@ void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
                
                m_deferedcollide        =       false;
                m_needcleanup           =       true;
-               m_prediction            =       1/(btScalar)2;
                m_stageCurrent          =       0;
                m_fixedleft                     =       0;
                m_fupdates                      =       1;
index fe70bc39c43d61657f19ca7f6a584b236d7dab6f..18b64ad0e57fa776a5eda4ceca99c93421a3c3b7 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  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.
@@ -12,6 +12,7 @@ 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.
 */
+
 ///btDbvtBroadphase implementation by Nathanael Presson
 #ifndef BT_DBVT_BROADPHASE_H
 #define BT_DBVT_BROADPHASE_H
@@ -101,26 +102,45 @@ struct    btDbvtBroadphase : btBroadphaseInterface
        ~btDbvtBroadphase();
        void                                                    collide(btDispatcher* dispatcher);
        void                                                    optimize();
-       /* btBroadphaseInterface Implementation */ 
+       
+       /* btBroadphaseInterface Implementation */
        btBroadphaseProxy*                              createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
-       void                                                    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
-       void                                                    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
-       virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
-
-       virtual void    getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
-       void                                                    calculateOverlappingPairs(btDispatcher* dispatcher);
-       btOverlappingPairCache*                 getOverlappingPairCache();
-       const btOverlappingPairCache*   getOverlappingPairCache() const;
-       void                                                    getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
-       void                                                    printStats();
-       static void                                             benchmark(btBroadphaseInterface*);
+       virtual void                                    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+       virtual void                                    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+       virtual void                                    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+       virtual void                                    aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
 
+       virtual void                                    getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+       virtual void                                    calculateOverlappingPairs(btDispatcher* dispatcher);
+       virtual btOverlappingPairCache* getOverlappingPairCache();
+       virtual const btOverlappingPairCache*   getOverlappingPairCache() const;
+       virtual void                                    getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
+       virtual void                                    printStats();
 
-       void    performDeferredRemoval(btDispatcher* dispatcher);
 
        ///reset broadphase internal structures, to ensure determinism/reproducability
        virtual void resetPool(btDispatcher* dispatcher);
 
+       void    performDeferredRemoval(btDispatcher* dispatcher);
+       
+       void    setVelocityPrediction(btScalar prediction)
+       {
+               m_prediction = prediction;
+       }
+       btScalar getVelocityPrediction() const
+       {
+               return m_prediction;
+       }
+
+       ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. 
+       ///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase.
+       ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see
+       ///http://code.google.com/p/bullet/issues/detail?id=223
+       void                                                    setAabbForceUpdate(             btBroadphaseProxy* absproxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* /*dispatcher*/);
+
+       static void                                             benchmark(btBroadphaseInterface*);
+
+
 };
 
 #endif
index ee57aa96151018a61ad8678b5be20e0630f755bc..8ded0006c3b3e54339f3be3e45eec740928566e9 100644 (file)
@@ -46,8 +46,9 @@ struct btDispatcherInfo
                m_enableSPU(true),
                m_useEpa(true),
                m_allowedCcdPenetration(btScalar(0.04)),
-               m_useConvexConservativeDistanceUtil(true),
+               m_useConvexConservativeDistanceUtil(false),
                m_convexConservativeDistanceThreshold(0.0f),
+               m_convexMaxDistanceUseCPT(false),
                m_stackAllocator(0)
        {
 
@@ -64,6 +65,7 @@ struct btDispatcherInfo
        btScalar        m_allowedCcdPenetration;
        bool            m_useConvexConservativeDistanceUtil;
        btScalar        m_convexConservativeDistanceThreshold;
+       bool            m_convexMaxDistanceUseCPT;
        btStackAlloc*   m_stackAllocator;
 };
 
index 91c504eee22825b481c418d3c8059dea948f313f..7bcfe6b132a8cfbb6551e2fc5bd354c9513564e2 100644 (file)
@@ -133,8 +133,8 @@ public:
        ///will add some transform later
        virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
        {
-               aabbMin.setValue(-1e30f,-1e30f,-1e30f);
-               aabbMax.setValue(1e30f,1e30f,1e30f);
+               aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);
+               aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
        }
 
        void    buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
index b209bcb9a200c3f2490beb17ba5b351e78fdf726..041bbe05ae202c34c8576aea9e00efbc00e12418 100644 (file)
@@ -240,7 +240,7 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
                }*/
        int count = m_overlappingPairArray.size();
        int oldCapacity = m_overlappingPairArray.capacity();
-       void* mem = &m_overlappingPairArray.expand();
+       void* mem = &m_overlappingPairArray.expandNonInitializing();
 
        //this is where we add an actual pair, so also call the 'ghost'
        if (m_ghostPairCallback)
@@ -467,7 +467,7 @@ btBroadphasePair*   btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseP
        if (!needsBroadphaseCollision(proxy0,proxy1))
                return 0;
        
-       void* mem = &m_overlappingPairArray.expand();
+       void* mem = &m_overlappingPairArray.expandNonInitializing();
        btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
        
        gOverlappingPairs++;
index eda45c47b5b2e8dcd5c42784a39db6b23376c6ca..3945afb8d706a58aac69890c3d8914f689ee3997 100644 (file)
@@ -457,6 +457,7 @@ public:
        
        virtual void    sortOverlappingPairs(btDispatcher* dispatcher)
        {
+        (void) dispatcher;
        }
 
 
index 8bef8f0d43ec2d97847840021ddfa479adb64447..c911435a946350a6e55c1acd906f08c22296fde1 100644 (file)
@@ -17,6 +17,7 @@ subject to the following restrictions:
 
 #include "LinearMath/btAabbUtil2.h"
 #include "LinearMath/btIDebugDraw.h"
+#include "LinearMath/btSerializer.h"
 
 #define RAYAABB2
 
@@ -78,10 +79,10 @@ void btQuantizedBvh::buildInternal()
 #ifdef DEBUG_PATCH_COLORS
 btVector3 color[4]=
 {
-       btVector3(255,0,0),
-       btVector3(0,255,0),
-       btVector3(0,0,255),
-       btVector3(0,255,255)
+       btVector3(1,0,0),
+       btVector3(0,1,0),
+       btVector3(0,0,1),
+       btVector3(0,1,1)
 };
 #endif //DEBUG_PATCH_COLORS
 
@@ -474,9 +475,9 @@ void        btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall
        lambda_max = rayDir.dot(rayTarget-raySource);
        ///what about division by zero? --> just set rayDirection[i] to 1.0
        btVector3 rayDirectionInverse;
-       rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-       rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-       rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+       rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+       rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+       rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
        unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
 #endif
 
@@ -493,8 +494,8 @@ void        btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall
                bounds[0] = rootNode->m_aabbMinOrg;
                bounds[1] = rootNode->m_aabbMaxOrg;
                /* Add box cast extents */
-               bounds[0] += aabbMin;
-               bounds[1] += aabbMax;
+               bounds[0] -= aabbMax;
+               bounds[1] -= aabbMin;
 
                aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
                //perhaps profile if it is worth doing the aabbOverlap test first
@@ -561,9 +562,9 @@ void        btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
        rayDirection.normalize ();
        lambda_max = rayDirection.dot(rayTarget-raySource);
        ///what about division by zero? --> just set rayDirection[i] to 1.0
-       rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[0];
-       rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[1];
-       rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[2];
+       rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
+       rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1];
+       rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2];
        unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
 #endif
 
@@ -617,8 +618,8 @@ void        btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
                        bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
                        bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
                        /* Add box cast extents */
-                       bounds[0] += aabbMin;
-                       bounds[1] += aabbMax;
+                       bounds[0] -= aabbMax;
+                       bounds[1] -= aabbMin;
                        btVector3 normal;
 #if 0
                        bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
@@ -830,7 +831,7 @@ unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
        return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
 }
 
-unsigned btQuantizedBvh::calculateSerializeBufferSize()
+unsigned btQuantizedBvh::calculateSerializeBufferSize() const
 {
        unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
        baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
@@ -841,7 +842,7 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize()
        return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
 }
 
-bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
+bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
 {
        btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
        m_subtreeHeaderCount = m_SubtreeHeaders.size();
@@ -1143,6 +1144,232 @@ m_bulletVersion(BT_BULLET_VERSION)
 
 }
 
+void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
+{
+       m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
+       m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
+       m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
+
+       m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
+       m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
+       
+       {
+               int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
+               m_contiguousNodes.resize(numElem);
+
+               if (numElem)
+               {
+                       btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
+
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
+                               m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
+                               m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
+                               m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
+                               m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
+                       }
+               }
+       }
+
+       {
+               int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
+               m_quantizedContiguousNodes.resize(numElem);
+               
+               if (numElem)
+               {
+                       btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+                       }
+               }
+       }
+
+       m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
+       
+       {
+               int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
+               m_SubtreeHeaders.resize(numElem);
+               if (numElem)
+               {
+                       btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+                               m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
+                               m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
+                       }
+               }
+       }
+}
+
+void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
+{
+       m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
+       m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
+       m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
+
+       m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
+       m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
+       
+       {
+               int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
+               m_contiguousNodes.resize(numElem);
+
+               if (numElem)
+               {
+                       btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
+
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
+                               m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
+                               m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
+                               m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
+                               m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
+                       }
+               }
+       }
+
+       {
+               int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
+               m_quantizedContiguousNodes.resize(numElem);
+               
+               if (numElem)
+               {
+                       btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+                               m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+                       }
+               }
+       }
+
+       m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
+       
+       {
+               int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
+               m_SubtreeHeaders.resize(numElem);
+               if (numElem)
+               {
+                       btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
+                       for (int i=0;i<numElem;i++,memPtr++)
+                       {
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+                               m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+                               m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+                               m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
+                               m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
+                       }
+               }
+       }
+
+}
+
+
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*    btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+       btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
+       
+       m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
+       m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
+       m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
+
+       quantizedData->m_curNodeIndex = m_curNodeIndex;
+       quantizedData->m_useQuantization = m_useQuantization;
+       
+       quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
+       quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
+       if (quantizedData->m_contiguousNodesPtr)
+       {
+               int sz = sizeof(btOptimizedBvhNodeData);
+               int numElem = m_contiguousNodes.size();
+               btChunk* chunk = serializer->allocate(sz,numElem);
+               btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
+               for (int i=0;i<numElem;i++,memPtr++)
+               {
+                       m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
+                       m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
+                       memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
+                       memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
+                       memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
+               }
+               serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
+       }
+
+       quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
+//     printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
+       quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
+       if (quantizedData->m_quantizedContiguousNodesPtr)
+       {
+               int sz = sizeof(btQuantizedBvhNodeData);
+               int numElem = m_quantizedContiguousNodes.size();
+               btChunk* chunk = serializer->allocate(sz,numElem);
+               btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
+               for (int i=0;i<numElem;i++,memPtr++)
+               {
+                       memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
+                       memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
+                       memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
+                       memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
+                       memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
+                       memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
+                       memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
+               }
+               serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
+       }
+
+       quantizedData->m_traversalMode = int(m_traversalMode);
+       quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
+
+       quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
+       if (quantizedData->m_subTreeInfoPtr)
+       {
+               int sz = sizeof(btBvhSubtreeInfoData);
+               int numElem = m_SubtreeHeaders.size();
+               btChunk* chunk = serializer->allocate(sz,numElem);
+               btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
+               for (int i=0;i<numElem;i++,memPtr++)
+               {
+                       memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
+                       memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
+                       memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
+                       memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
+                       memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
+                       memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
+
+                       memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
+                       memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
+               }
+               serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
+       }
+       return btQuantizedBvhDataName;
+}
+
+
 
 
 
index ced457b6036e3c31749b8009dfe209c81fcc0e3c..aa30d43a025381295446ca6d8e59b0bd3fa38ade 100644 (file)
@@ -16,6 +16,8 @@ subject to the following restrictions:
 #ifndef QUANTIZED_BVH_H
 #define QUANTIZED_BVH_H
 
+class btSerializer;
+
 //#define DEBUG_CHECK_DEQUANTIZATION 1
 #ifdef DEBUG_CHECK_DEQUANTIZATION
 #ifdef __SPU__
@@ -29,6 +31,17 @@ subject to the following restrictions:
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btAlignedAllocator.h"
 
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btQuantizedBvhData btQuantizedBvhDoubleData
+#define btOptimizedBvhNodeData btOptimizedBvhNodeDoubleData
+#define btQuantizedBvhDataName "btQuantizedBvhDoubleData"
+#else
+#define btQuantizedBvhData btQuantizedBvhFloatData
+#define btOptimizedBvhNodeData btOptimizedBvhNodeFloatData
+#define btQuantizedBvhDataName "btQuantizedBvhFloatData"
+#endif
+
+
 
 //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
 
@@ -190,7 +203,7 @@ protected:
        BvhSubtreeInfoArray             m_SubtreeHeaders;
 
        //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
-       int m_subtreeHeaderCount;
+       mutable int m_subtreeHeaderCount;
 
        
 
@@ -443,17 +456,32 @@ public:
                return m_SubtreeHeaders;
        }
 
+////////////////////////////////////////////////////////////////////
 
        /////Calculate space needed to store BVH for serialization
-       unsigned calculateSerializeBufferSize();
+       unsigned calculateSerializeBufferSize() const;
 
        /// Data buffer MUST be 16 byte aligned
-       virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
+       virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const;
 
        ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
        static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
 
        static unsigned int getAlignmentSerializationPadding();
+//////////////////////////////////////////////////////////////////////
+
+       
+       virtual int     calculateSerializeBufferSizeNew() const;
+
+       ///fills the dataBuffer and returns the struct name (and 0 on failure)
+       virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
+
+       virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData);
+
+       virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData);
+
+
+////////////////////////////////////////////////////////////////////
 
        SIMD_FORCE_INLINE bool isQuantized()
        {
@@ -470,4 +498,82 @@ private:
 ;
 
 
+struct btBvhSubtreeInfoData
+{
+       int                     m_rootNodeIndex;
+       int                     m_subtreeSize;
+       unsigned short m_quantizedAabbMin[3];
+       unsigned short m_quantizedAabbMax[3];
+};
+
+struct btOptimizedBvhNodeFloatData
+{
+       btVector3FloatData      m_aabbMinOrg;
+       btVector3FloatData      m_aabbMaxOrg;
+       int     m_escapeIndex;
+       int     m_subPart;
+       int     m_triangleIndex;
+       char m_pad[4];
+};
+
+struct btOptimizedBvhNodeDoubleData
+{
+       btVector3DoubleData     m_aabbMinOrg;
+       btVector3DoubleData     m_aabbMaxOrg;
+       int     m_escapeIndex;
+       int     m_subPart;
+       int     m_triangleIndex;
+       char    m_pad[4];
+};
+
+
+struct btQuantizedBvhNodeData
+{
+       unsigned short m_quantizedAabbMin[3];
+       unsigned short m_quantizedAabbMax[3];
+       int     m_escapeIndexOrTriangleIndex;
+};
+
+struct btQuantizedBvhFloatData
+{
+       btVector3FloatData                      m_bvhAabbMin;
+       btVector3FloatData                      m_bvhAabbMax;
+       btVector3FloatData                      m_bvhQuantization;
+       int                                     m_curNodeIndex;
+       int                                     m_useQuantization;
+       int                                     m_numContiguousLeafNodes;
+       int                                     m_numQuantizedContiguousNodes;
+       btOptimizedBvhNodeFloatData     *m_contiguousNodesPtr;
+       btQuantizedBvhNodeData          *m_quantizedContiguousNodesPtr;
+       btBvhSubtreeInfoData    *m_subTreeInfoPtr;
+       int                                     m_traversalMode;
+       int                                     m_numSubtreeHeaders;
+       
+};
+
+struct btQuantizedBvhDoubleData
+{
+       btVector3DoubleData                     m_bvhAabbMin;
+       btVector3DoubleData                     m_bvhAabbMax;
+       btVector3DoubleData                     m_bvhQuantization;
+       int                                                     m_curNodeIndex;
+       int                                                     m_useQuantization;
+       int                                                     m_numContiguousLeafNodes;
+       int                                                     m_numQuantizedContiguousNodes;
+       btOptimizedBvhNodeDoubleData    *m_contiguousNodesPtr;
+       btQuantizedBvhNodeData                  *m_quantizedContiguousNodesPtr;
+
+       int                                                     m_traversalMode;
+       int                                                     m_numSubtreeHeaders;
+       btBvhSubtreeInfoData            *m_subTreeInfoPtr;
+};
+
+
+SIMD_FORCE_INLINE      int     btQuantizedBvh::calculateSerializeBufferSizeNew() const
+{
+       return sizeof(btQuantizedBvhData);
+}
+
+
+
 #endif //QUANTIZED_BVH_H
index caed63db0056eeff1b752613401ca2f638896216..752fcd0fef27306d4da10ec63bbf83826db5de4e 100644 (file)
@@ -20,6 +20,8 @@ subject to the following restrictions:
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btTransform.h"
 #include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btAabbUtil2.h"
+
 #include <new>
 
 extern int gOverlappingPairs;
@@ -166,6 +168,23 @@ void       btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo
 }
 
 
+void   btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
+{
+       for (int i=0; i <= m_LastHandleIndex; i++)
+       {
+               btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
+               if(!proxy->m_clientObject)
+               {
+                       continue;
+               }
+               if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax))
+               {
+                       callback.process(proxy);
+               }
+       }
+}
+
+
 
        
 
index cc7613bf6a0e089a5c37f8c2a213c83bf7bdab4b..3e7c7ee3b62151ea018d34e4b1f78e7790b246c4 100644 (file)
@@ -136,6 +136,7 @@ public:
        virtual void    getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
 
        virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
+       virtual void    aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
                
        btOverlappingPairCache* getOverlappingPairCache()
        {
@@ -153,8 +154,8 @@ public:
        ///will add some transform later
        virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
        {
-               aabbMin.setValue(-1e30f,-1e30f,-1e30f);
-               aabbMax.setValue(1e30f,1e30f,1e30f);
+               aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);
+               aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
        }
 
        virtual void    printStats()
index 9a749a03793bc20dababdf1e652ce7a38593ad45..23a5c7526b4dea3239c0a969b9a86ba962f22382 100644 (file)
@@ -37,7 +37,7 @@ void  SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
        btVector3 point,normal;
        btScalar timeOfImpact = btScalar(1.);
        btScalar depth = btScalar(0.);
-//     output.m_distance = btScalar(1e30);
+//     output.m_distance = btScalar(BT_LARGE_FLOAT);
        //move sphere into triangle space
        btTransform     sphereInTr = transformB.inverseTimes(transformA);
 
@@ -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;
index 981bd54e76c5629f138f8372961a7a8ec8e959fa..f656e5c323acb4ba0cfa74e1433bbd10cc9575f1 100644 (file)
@@ -34,9 +34,11 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
 
        virtual ~SphereTriangleDetector() {};
 
+       bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
+
 private:
 
-       bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
+       
        bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
        bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
 
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
new file mode 100644 (file)
index 0000000..2182d0d
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+* The b2CollidePolygons routines are Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+
+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.
+*/
+
+///btBox2dBox2dCollisionAlgorithm, with modified b2CollidePolygons routines from the Box2D library.
+///The modifications include: switching from b2Vec to btVector3, redefinition of b2Dot, b2Cross
+
+#include "btBox2dBox2dCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h"
+#include "BulletCollision/CollisionShapes/btBox2dShape.h"
+
+#define USE_PERSISTENT_CONTACTS 1
+
+btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
+: btActivatingCollisionAlgorithm(ci,obj0,obj1),
+m_ownManifold(false),
+m_manifoldPtr(mf)
+{
+       if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
+       {
+               m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
+               m_ownManifold = true;
+       }
+}
+
+btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm()
+{
+       
+       if (m_ownManifold)
+       {
+               if (m_manifoldPtr)
+                       m_dispatcher->releaseManifold(m_manifoldPtr);
+       }
+       
+}
+
+
+void b2CollidePolygons(btManifoldResult* manifold,  const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB);
+
+//#include <stdio.h>
+void btBox2dBox2dCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+       if (!m_manifoldPtr)
+               return;
+
+       btCollisionObject*      col0 = body0;
+       btCollisionObject*      col1 = body1;
+       btBox2dShape* box0 = (btBox2dShape*)col0->getCollisionShape();
+       btBox2dShape* box1 = (btBox2dShape*)col1->getCollisionShape();
+
+       resultOut->setPersistentManifold(m_manifoldPtr);
+
+       b2CollidePolygons(resultOut,box0,col0->getWorldTransform(),box1,col1->getWorldTransform());
+
+       //  refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
+       if (m_ownManifold)
+       {
+               resultOut->refreshContactPoints();
+       }
+
+}
+
+btScalar btBox2dBox2dCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
+{
+       //not yet
+       return 1.f;
+}
+
+
+struct ClipVertex
+{
+       btVector3 v;
+       int id;
+       //b2ContactID id;
+       //b2ContactID id;
+};
+
+#define b2Dot(a,b) (a).dot(b)
+#define b2Mul(a,b) (a)*(b)
+#define b2MulT(a,b) (a).transpose()*(b)
+#define b2Cross(a,b) (a).cross(b)
+#define btCrossS(a,s) btVector3(s * a.getY(), -s * a.getX(),0.f)
+
+int b2_maxManifoldPoints =2;
+
+static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2],
+                                         const btVector3& normal, btScalar offset)
+{
+       // Start with no output points
+       int numOut = 0;
+
+       // Calculate the distance of end points to the line
+       btScalar distance0 = b2Dot(normal, vIn[0].v) - offset;
+       btScalar distance1 = b2Dot(normal, vIn[1].v) - offset;
+
+       // If the points are behind the plane
+       if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
+       if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
+
+       // If the points are on different sides of the plane
+       if (distance0 * distance1 < 0.0f)
+       {
+               // Find intersection point of edge and plane
+               btScalar interp = distance0 / (distance0 - distance1);
+               vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
+               if (distance0 > 0.0f)
+               {
+                       vOut[numOut].id = vIn[0].id;
+               }
+               else
+               {
+                       vOut[numOut].id = vIn[1].id;
+               }
+               ++numOut;
+       }
+
+       return numOut;
+}
+
+// Find the separation between poly1 and poly2 for a give edge normal on poly1.
+static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1, int edge1,
+                                                         const btBox2dShape* poly2, const btTransform& xf2)
+{
+       const btVector3* vertices1 = poly1->getVertices();
+       const btVector3* normals1 = poly1->getNormals();
+
+       int count2 = poly2->getVertexCount();
+       const btVector3* vertices2 = poly2->getVertices();
+
+       btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
+
+       // Convert normal from poly1's frame into poly2's frame.
+       btVector3 normal1World = b2Mul(xf1.getBasis(), normals1[edge1]);
+       btVector3 normal1 = b2MulT(xf2.getBasis(), normal1World);
+
+       // Find support vertex on poly2 for -normal.
+       int index = 0;
+       btScalar minDot = BT_LARGE_FLOAT;
+
+       for (int i = 0; i < count2; ++i)
+       {
+               btScalar dot = b2Dot(vertices2[i], normal1);
+               if (dot < minDot)
+               {
+                       minDot = dot;
+                       index = i;
+               }
+       }
+
+       btVector3 v1 = b2Mul(xf1, vertices1[edge1]);
+       btVector3 v2 = b2Mul(xf2, vertices2[index]);
+       btScalar separation = b2Dot(v2 - v1, normal1World);
+       return separation;
+}
+
+// Find the max separation between poly1 and poly2 using edge normals from poly1.
+static btScalar FindMaxSeparation(int* edgeIndex,
+                                                                const btBox2dShape* poly1, const btTransform& xf1,
+                                                                const btBox2dShape* poly2, const btTransform& xf2)
+{
+       int count1 = poly1->getVertexCount();
+       const btVector3* normals1 = poly1->getNormals();
+
+       // Vector pointing from the centroid of poly1 to the centroid of poly2.
+       btVector3 d = b2Mul(xf2, poly2->getCentroid()) - b2Mul(xf1, poly1->getCentroid());
+       btVector3 dLocal1 = b2MulT(xf1.getBasis(), d);
+
+       // Find edge normal on poly1 that has the largest projection onto d.
+       int edge = 0;
+       btScalar maxDot = -BT_LARGE_FLOAT;
+       for (int i = 0; i < count1; ++i)
+       {
+               btScalar dot = b2Dot(normals1[i], dLocal1);
+               if (dot > maxDot)
+               {
+                       maxDot = dot;
+                       edge = i;
+               }
+       }
+
+       // Get the separation for the edge normal.
+       btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+       if (s > 0.0f)
+       {
+               return s;
+       }
+
+       // Check the separation for the previous edge normal.
+       int prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
+       btScalar sPrev = EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
+       if (sPrev > 0.0f)
+       {
+               return sPrev;
+       }
+
+       // Check the separation for the next edge normal.
+       int nextEdge = edge + 1 < count1 ? edge + 1 : 0;
+       btScalar sNext = EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
+       if (sNext > 0.0f)
+       {
+               return sNext;
+       }
+
+       // Find the best edge and the search direction.
+       int bestEdge;
+       btScalar bestSeparation;
+       int increment;
+       if (sPrev > s && sPrev > sNext)
+       {
+               increment = -1;
+               bestEdge = prevEdge;
+               bestSeparation = sPrev;
+       }
+       else if (sNext > s)
+       {
+               increment = 1;
+               bestEdge = nextEdge;
+               bestSeparation = sNext;
+       }
+       else
+       {
+               *edgeIndex = edge;
+               return s;
+       }
+
+       // Perform a local search for the best edge normal.
+       for ( ; ; )
+       {
+               if (increment == -1)
+                       edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
+               else
+                       edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
+
+               s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+               if (s > 0.0f)
+               {
+                       return s;
+               }
+
+               if (s > bestSeparation)
+               {
+                       bestEdge = edge;
+                       bestSeparation = s;
+               }
+               else
+               {
+                       break;
+               }
+       }
+
+       *edgeIndex = bestEdge;
+       return bestSeparation;
+}
+
+static void FindIncidentEdge(ClipVertex c[2],
+                                                        const btBox2dShape* poly1, const btTransform& xf1, int edge1,
+                                                        const btBox2dShape* poly2, const btTransform& xf2)
+{
+       const btVector3* normals1 = poly1->getNormals();
+
+       int count2 = poly2->getVertexCount();
+       const btVector3* vertices2 = poly2->getVertices();
+       const btVector3* normals2 = poly2->getNormals();
+
+       btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
+
+       // Get the normal of the reference edge in poly2's frame.
+       btVector3 normal1 = b2MulT(xf2.getBasis(), b2Mul(xf1.getBasis(), normals1[edge1]));
+
+       // Find the incident edge on poly2.
+       int index = 0;
+       btScalar minDot = BT_LARGE_FLOAT;
+       for (int i = 0; i < count2; ++i)
+       {
+               btScalar dot = b2Dot(normal1, normals2[i]);
+               if (dot < minDot)
+               {
+                       minDot = dot;
+                       index = i;
+               }
+       }
+
+       // Build the clip vertices for the incident edge.
+       int i1 = index;
+       int i2 = i1 + 1 < count2 ? i1 + 1 : 0;
+
+       c[0].v = b2Mul(xf2, vertices2[i1]);
+//     c[0].id.features.referenceEdge = (unsigned char)edge1;
+//     c[0].id.features.incidentEdge = (unsigned char)i1;
+//     c[0].id.features.incidentVertex = 0;
+
+       c[1].v = b2Mul(xf2, vertices2[i2]);
+//     c[1].id.features.referenceEdge = (unsigned char)edge1;
+//     c[1].id.features.incidentEdge = (unsigned char)i2;
+//     c[1].id.features.incidentVertex = 1;
+}
+
+// Find edge normal of max separation on A - return if separating axis is found
+// Find edge normal of max separation on B - return if separation axis is found
+// Choose reference edge as min(minA, minB)
+// Find incident edge
+// Clip
+
+// The normal points from 1 to 2
+void b2CollidePolygons(btManifoldResult* manifold,
+                                         const btBox2dShape* polyA, const btTransform& xfA,
+                                         const btBox2dShape* polyB, const btTransform& xfB)
+{
+
+       int edgeA = 0;
+       btScalar separationA = FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);
+       if (separationA > 0.0f)
+               return;
+
+       int edgeB = 0;
+       btScalar separationB = FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);
+       if (separationB > 0.0f)
+               return;
+
+       const btBox2dShape* poly1;      // reference poly
+       const btBox2dShape* poly2;      // incident poly
+       btTransform xf1, xf2;
+       int edge1;              // reference edge
+       unsigned char flip;
+       const btScalar k_relativeTol = 0.98f;
+       const btScalar k_absoluteTol = 0.001f;
+
+       // TODO_ERIN use "radius" of poly for absolute tolerance.
+       if (separationB > k_relativeTol * separationA + k_absoluteTol)
+       {
+               poly1 = polyB;
+               poly2 = polyA;
+               xf1 = xfB;
+               xf2 = xfA;
+               edge1 = edgeB;
+               flip = 1;
+       }
+       else
+       {
+               poly1 = polyA;
+               poly2 = polyB;
+               xf1 = xfA;
+               xf2 = xfB;
+               edge1 = edgeA;
+               flip = 0;
+       }
+
+       ClipVertex incidentEdge[2];
+       FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+
+       int count1 = poly1->getVertexCount();
+       const btVector3* vertices1 = poly1->getVertices();
+
+       btVector3 v11 = vertices1[edge1];
+       btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];
+
+       btVector3 dv = v12 - v11;
+       btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11);
+       sideNormal.normalize();
+       btVector3 frontNormal = btCrossS(sideNormal, 1.0f);
+       
+       
+       v11 = b2Mul(xf1, v11);
+       v12 = b2Mul(xf1, v12);
+
+       btScalar frontOffset = b2Dot(frontNormal, v11);
+       btScalar sideOffset1 = -b2Dot(sideNormal, v11);
+       btScalar sideOffset2 = b2Dot(sideNormal, v12);
+
+       // Clip incident edge against extruded edge1 side edges.
+       ClipVertex clipPoints1[2];
+       clipPoints1[0].v.setValue(0,0,0);
+       clipPoints1[1].v.setValue(0,0,0);
+
+       ClipVertex clipPoints2[2];
+       clipPoints2[0].v.setValue(0,0,0);
+       clipPoints2[1].v.setValue(0,0,0);
+
+
+       int np;
+
+       // Clip to box side 1
+       np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, sideOffset1);
+
+       if (np < 2)
+               return;
+
+       // Clip to negative box side 1
+       np = ClipSegmentToLine(clipPoints2, clipPoints1,  sideNormal, sideOffset2);
+
+       if (np < 2)
+       {
+               return;
+       }
+
+       // Now clipPoints2 contains the clipped points.
+       btVector3 manifoldNormal = flip ? -frontNormal : frontNormal;
+
+       int pointCount = 0;
+       for (int i = 0; i < b2_maxManifoldPoints; ++i)
+       {
+               btScalar separation = b2Dot(frontNormal, clipPoints2[i].v) - frontOffset;
+
+               if (separation <= 0.0f)
+               {
+                       
+                       //b2ManifoldPoint* cp = manifold->points + pointCount;
+                       //btScalar separation = separation;
+                       //cp->localPoint1 = b2MulT(xfA, clipPoints2[i].v);
+                       //cp->localPoint2 = b2MulT(xfB, clipPoints2[i].v);
+
+                       manifold->addContactPoint(-manifoldNormal,clipPoints2[i].v,separation);
+
+//                     cp->id = clipPoints2[i].id;
+//                     cp->id.features.flip = flip;
+                       ++pointCount;
+               }
+       }
+
+//     manifold->pointCount = pointCount;}
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
new file mode 100644 (file)
index 0000000..2134217
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+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.
+*/
+
+#ifndef BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+#define BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+
+class btPersistentManifold;
+
+///box-box collision detection
+class btBox2dBox2dCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+       bool    m_ownManifold;
+       btPersistentManifold*   m_manifoldPtr;
+       
+public:
+       btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
+               : btActivatingCollisionAlgorithm(ci) {}
+
+       virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+       virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+       btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+
+       virtual ~btBox2dBox2dCollisionAlgorithm();
+
+       virtual void    getAllContactManifolds(btManifoldArray& manifoldArray)
+       {
+               if (m_manifoldPtr && m_ownManifold)
+               {
+                       manifoldArray.push_back(m_manifoldPtr);
+               }
+       }
+
+
+       struct CreateFunc :public       btCollisionAlgorithmCreateFunc
+       {
+               virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+               {
+                       int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm);
+                       void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
+                       return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0,body1);
+               }
+       };
+
+};
+
+#endif //BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+
index d3342c547b560acd8e36931f816dc7ec2f6a15eb..49628853493793a5998bc56e53e460f477d9b08f 100644 (file)
@@ -61,7 +61,7 @@ void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCo
 #endif //USE_PERSISTENT_CONTACTS
 
        btDiscreteCollisionDetectorInterface::ClosestPointInput input;
-       input.m_maximumDistanceSquared = 1e30f;
+       input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
        input.m_transformA = body0->getWorldTransform();
        input.m_transformB = body1->getWorldTransform();
 
index 31353f1b2c4b4225b0ac4741a258309c7415493c..a7c8cf140ce4e97e3b614484c68f59bb62557d96 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
  * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
@@ -212,7 +211,7 @@ void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
                a = 1.f/(btScalar(3.0)*(a+q));
        } else
        {
-               a=1e30f;
+               a=BT_LARGE_FLOAT;
        }
     cx = a*(cx + q*(p[n*2-2]+p[0]));
     cy = a*(cy + q*(p[n*2-1]+p[1]));
@@ -267,7 +266,7 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
                 int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output)
 {
   const btScalar fudge_factor = btScalar(1.05);
-  btVector3 p,pp,normalC;
+  btVector3 p,pp,normalC(0.f,0.f,0.f);
   const btScalar *normalR = 0;
   btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33,
     Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l;
@@ -333,9 +332,9 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
 #undef TST
 #define TST(expr1,expr2,n1,n2,n3,cc) \
   s2 = btFabs(expr1) - (expr2); \
-  if (s2 > 0) return 0; \
+  if (s2 > SIMD_EPSILON) return 0; \
   l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
-  if (l > 0) { \
+  if (l > SIMD_EPSILON) { \
     s2 /= l; \
     if (s2*fudge_factor > s) { \
       s = s2; \
@@ -346,6 +345,20 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
     } \
   }
 
+  btScalar fudge2 (1.0e-5f);
+
+  Q11 += fudge2;
+  Q12 += fudge2;
+  Q13 += fudge2;
+
+  Q21 += fudge2;
+  Q22 += fudge2;
+  Q23 += fudge2;
+
+  Q31 += fudge2;
+  Q32 += fudge2;
+  Q33 += fudge2;
+
   // separating axis = u1 x (v1,v2,v3)
   TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7);
   TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8);
@@ -424,6 +437,7 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
                output.addContactPoint(-normal,pointInWorld,-*depth);
 #else
                output.addContactPoint(-normal,pb,-*depth);
+
 #endif //
                *return_code = code;
        }
@@ -593,21 +607,30 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
   if (maxc < 1) maxc = 1;
 
   if (cnum <= maxc) {
-    // we have less contacts than we need, so we use them all
-    for (j=0; j < cnum; j++) {
-
-               //AddContactPoint...
-
-               //dContactGeom *con = CONTACT(contact,skip*j);
-      //for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i];
-      //con->depth = dep[j];
 
+         if (code<4) 
+         {
+    // we have less contacts than we need, so we use them all
+    for (j=0; j < cnum; j++) 
+       {
                btVector3 pointInWorld;
                for (i=0; i<3; i++) 
                        pointInWorld[i] = point[j*3+i] + pa[i];
                output.addContactPoint(-normal,pointInWorld,-dep[j]);
 
     }
+         } else
+         {
+                 // we have less contacts than we need, so we use them all
+               for (j=0; j < cnum; j++) 
+               {
+                       btVector3 pointInWorld;
+                       for (i=0; i<3; i++) 
+                               pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j];
+                               //pointInWorld[i] = point[j*3+i] + pa[i];
+                       output.addContactPoint(-normal,pointInWorld,-dep[j]);
+               }
+         }
   }
   else {
     // we have more contacts than are wanted, some of them must be culled.
@@ -632,7 +655,13 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
                btVector3 posInWorld;
                for (i=0; i<3; i++) 
                        posInWorld[i] = point[iret[j]*3+i] + pa[i];
-               output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
+               if (code<4) 
+          {
+                       output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
+               } else
+               {
+                       output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]);
+               }
     }
     cnum = maxc;
   }
index e6ff2130aaddb0742154d34dc6e16153bd6d002e..9fed44a19f73ee19e3833e1424c6b01ccf68f433 100644 (file)
@@ -34,9 +34,7 @@ int gNumManifold = 0;
 
 
 btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): 
-       m_count(0),
-       m_useIslands(true),
-       m_staticWarningReported(false),
+m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
        m_collisionConfiguration(collisionConfiguration)
 {
        int i;
@@ -79,9 +77,11 @@ btPersistentManifold*        btCollisionDispatcher::getNewManifold(void* b0,void* b1)
        btCollisionObject* body0 = (btCollisionObject*)b0;
        btCollisionObject* body1 = (btCollisionObject*)b1;
 
-       //test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
-       //btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
-       btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
+       //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
+       
+       btScalar contactBreakingThreshold =  (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? 
+               btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold))
+               : gContactBreakingThreshold ;
 
        btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
                
@@ -169,13 +169,13 @@ bool      btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
        bool needsCollision = true;
 
 #ifdef BT_DEBUG
-       if (!m_staticWarningReported)
+       if (!(m_dispatcherFlags & btCollisionDispatcher::CD_STATIC_STATIC_REPORTED))
        {
                //broadphase filtering already deals with this
                if ((body0->isStaticObject() || body0->isKinematicObject()) &&
                        (body1->isStaticObject() || body1->isKinematicObject()))
                {
-                       m_staticWarningReported = true;
+                       m_dispatcherFlags |= btCollisionDispatcher::CD_STATIC_STATIC_REPORTED;
                        printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
                }
        }
index a9c9cd414c1e753d5a705df21e44e88e791dcae3..3c4f039504a36f4c87c04c9b36860991ba8eefad 100644 (file)
@@ -42,14 +42,13 @@ typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispa
 ///Time of Impact, Closest Points and Penetration Depth.
 class btCollisionDispatcher : public btDispatcher
 {
-       int m_count;
-       
-       btAlignedObjectArray<btPersistentManifold*>     m_manifoldsPtr;
 
-       bool m_useIslands;
+protected:
+
+       int             m_dispatcherFlags;
+
+       btAlignedObjectArray<btPersistentManifold*>     m_manifoldsPtr;
 
-       bool    m_staticWarningReported;
-       
        btManifoldResult        m_defaultManifoldResult;
 
        btNearCallback          m_nearCallback;
@@ -59,13 +58,28 @@ class btCollisionDispatcher : public btDispatcher
        btPoolAllocator*        m_persistentManifoldPoolAllocator;
 
        btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
-       
 
        btCollisionConfiguration*       m_collisionConfiguration;
 
 
 public:
 
+       enum DispatcherFlags
+       {
+               CD_STATIC_STATIC_REPORTED = 1,
+               CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2
+       };
+
+       int     getDispatcherFlags() const
+       {
+               return m_dispatcherFlags;
+       }
+
+       void    setDispatcherFlags(int flags)
+       {
+               m_dispatcherFlags = flags;
+       }
+
        ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
        void    registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
 
index 285b8f174e4487c09877b8f44774b70cca28aeab..580ea3458607192ccdadd5e7771811e85d9527d5 100644 (file)
@@ -15,13 +15,15 @@ subject to the following restrictions:
 
 
 #include "btCollisionObject.h"
+#include "LinearMath/btSerializer.h"
 
 btCollisionObject::btCollisionObject()
        :       m_anisotropicFriction(1.f,1.f,1.f),
        m_hasAnisotropicFriction(false),
-       m_contactProcessingThreshold(0.f),
+       m_contactProcessingThreshold(BT_LARGE_FLOAT),
                m_broadphaseHandle(0),
                m_collisionShape(0),
+               m_extensionPointer(0),
                m_rootCollisionShape(0),
                m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
                m_islandTag1(-1),
@@ -30,14 +32,14 @@ btCollisionObject::btCollisionObject()
                m_deactivationTime(btScalar(0.)),
                m_friction(btScalar(0.5)),
                m_restitution(btScalar(0.)),
-               m_userObjectPointer(0),
                m_internalType(CO_COLLISION_OBJECT),
+               m_userObjectPointer(0),
                m_hitFraction(btScalar(1.)),
                m_ccdSweptSphereRadius(btScalar(0.)),
                m_ccdMotionThreshold(btScalar(0.)),
                m_checkCollideWith(false)
 {
-       
+       m_worldTransform.setIdentity();
 }
 
 btCollisionObject::~btCollisionObject()
@@ -64,5 +66,51 @@ void btCollisionObject::activate(bool forceActivation)
        }
 }
 
+const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* serializer) const
+{
 
+       btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer;
 
+       m_worldTransform.serialize(dataOut->m_worldTransform);
+       m_interpolationWorldTransform.serialize(dataOut->m_interpolationWorldTransform);
+       m_interpolationLinearVelocity.serialize(dataOut->m_interpolationLinearVelocity);
+       m_interpolationAngularVelocity.serialize(dataOut->m_interpolationAngularVelocity);
+       m_anisotropicFriction.serialize(dataOut->m_anisotropicFriction);
+       dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction;
+       dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold;
+       dataOut->m_broadphaseHandle = 0;
+       dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape);
+       dataOut->m_rootCollisionShape = 0;//@todo
+       dataOut->m_collisionFlags = m_collisionFlags;
+       dataOut->m_islandTag1 = m_islandTag1;
+       dataOut->m_companionId = m_companionId;
+       dataOut->m_activationState1 = m_activationState1;
+       dataOut->m_activationState1 = m_activationState1;
+       dataOut->m_deactivationTime = m_deactivationTime;
+       dataOut->m_friction = m_friction;
+       dataOut->m_restitution = m_restitution;
+       dataOut->m_internalType = m_internalType;
+       
+       char* name = (char*) serializer->findNameForPointer(this);
+       dataOut->m_name = (char*)serializer->getUniquePointer(name);
+       if (dataOut->m_name)
+       {
+               serializer->serializeName(name);
+       }
+       dataOut->m_hitFraction = m_hitFraction;
+       dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius;
+       dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
+       dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
+       dataOut->m_checkCollideWith = m_checkCollideWith;
+
+       return btCollisionObjectDataName;
+}
+
+
+void btCollisionObject::serializeSingleObject(class btSerializer* serializer) const
+{
+       int len = calculateSerializeBufferSize();
+       btChunk* chunk = serializer->allocate(len,1);
+       const char* structType = serialize(chunk->m_oldPtr, serializer);
+       serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,(void*)this);
+}
index 0d5b7886443da13a94afee57ef39c7ce7c783741..5de829824ff0b908d9ecd61da05e020b2e824c83 100644 (file)
@@ -27,13 +27,21 @@ subject to the following restrictions:
 
 struct btBroadphaseProxy;
 class  btCollisionShape;
+struct btCollisionShapeData;
 #include "LinearMath/btMotionState.h"
 #include "LinearMath/btAlignedAllocator.h"
 #include "LinearMath/btAlignedObjectArray.h"
 
-
 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
 
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btCollisionObjectData btCollisionObjectDoubleData
+#define btCollisionObjectDataName "btCollisionObjectDoubleData"
+#else
+#define btCollisionObjectData btCollisionObjectFloatData
+#define btCollisionObjectDataName "btCollisionObjectFloatData"
+#endif
+
 
 /// btCollisionObject can be used to manage collision detection objects. 
 /// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
@@ -53,12 +61,14 @@ protected:
        btVector3       m_interpolationLinearVelocity;
        btVector3       m_interpolationAngularVelocity;
        
-       btVector3               m_anisotropicFriction;
-       bool                            m_hasAnisotropicFriction;
-       btScalar                m_contactProcessingThreshold;   
+       btVector3       m_anisotropicFriction;
+       int                     m_hasAnisotropicFriction;
+       btScalar        m_contactProcessingThreshold;   
 
        btBroadphaseProxy*              m_broadphaseHandle;
        btCollisionShape*               m_collisionShape;
+       ///m_extensionPointer is used by some internal low-level Bullet extensions.
+       void*                                   m_extensionPointer;
        
        ///m_rootCollisionShape is temporarily used to store the original collision shape
        ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
@@ -76,13 +86,13 @@ protected:
        btScalar                m_friction;
        btScalar                m_restitution;
 
-       ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
-       void*                   m_userObjectPointer;
-
        ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
        ///do not assign your own m_internalType unless you write a new dynamics object class.
        int                             m_internalType;
 
+       ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
+       void*                   m_userObjectPointer;
+
        ///time of impact calculation
        btScalar                m_hitFraction; 
        
@@ -93,9 +103,7 @@ protected:
        btScalar                m_ccdMotionThreshold;
        
        /// If some object should have elaborate collision filtering by sub-classes
-       bool                    m_checkCollideWith;
-
-       char    m_pad[7];
+       int                     m_checkCollideWith;
 
        virtual bool    checkCollideWithOverride(btCollisionObject* /* co */)
        {
@@ -112,18 +120,21 @@ public:
                CF_KINEMATIC_OBJECT= 2,
                CF_NO_CONTACT_RESPONSE = 4,
                CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
-               CF_CHARACTER_OBJECT = 16
+               CF_CHARACTER_OBJECT = 16,
+               CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
+               CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
        };
 
        enum    CollisionObjectTypes
        {
                CO_COLLISION_OBJECT =1,
-               CO_RIGID_BODY,
+               CO_RIGID_BODY=2,
                ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
                ///It is useful for collision sensors, explosion objects, character controller etc.
-               CO_GHOST_OBJECT,
-               CO_SOFT_BODY,
-               CO_HF_FLUID
+               CO_GHOST_OBJECT=4,
+               CO_SOFT_BODY=8,
+               CO_HF_FLUID=16,
+               CO_USER_TYPE=32
        };
 
        SIMD_FORCE_INLINE bool mergesSimulationIslands() const
@@ -143,7 +154,7 @@ public:
        }
        bool    hasAnisotropicFriction() const
        {
-               return m_hasAnisotropicFriction;
+               return m_hasAnisotropicFriction!=0;
        }
 
        ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
@@ -213,6 +224,19 @@ public:
                m_collisionShape = collisionShape;
        }
 
+       ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. 
+       ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
+       void*           internalGetExtensionPointer() const
+       {
+               return m_extensionPointer;
+       }
+       ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
+       ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
+       void    internalSetExtensionPointer(void* pointer)
+       {
+               m_extensionPointer = pointer;
+       }
+
        SIMD_FORCE_INLINE       int     getActivationState() const { return m_activationState1;}
        
        void setActivationState(int newState);
@@ -393,7 +417,7 @@ public:
        /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
        void    setCcdMotionThreshold(btScalar ccdMotionThreshold)
        {
-               m_ccdMotionThreshold = ccdMotionThreshold*ccdMotionThreshold;
+               m_ccdMotionThreshold = ccdMotionThreshold;
        }
 
        ///users can point to their objects, userPointer is not used by Bullet
@@ -416,6 +440,85 @@ public:
 
                return true;
        }
+
+       virtual int     calculateSerializeBufferSize()  const;
+
+       ///fills the dataBuffer and returns the struct name (and 0 on failure)
+       virtual const char*     serialize(void* dataBuffer, class btSerializer* serializer) const;
+
+       virtual void serializeSingleObject(class btSerializer* serializer) const;
+
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btCollisionObjectDoubleData
+{
+       void                                    *m_broadphaseHandle;
+       void                                    *m_collisionShape;
+       btCollisionShapeData    *m_rootCollisionShape;
+       char                                    *m_name;
+
+       btTransformDoubleData   m_worldTransform;
+       btTransformDoubleData   m_interpolationWorldTransform;
+       btVector3DoubleData             m_interpolationLinearVelocity;
+       btVector3DoubleData             m_interpolationAngularVelocity;
+       btVector3DoubleData             m_anisotropicFriction;
+       double                                  m_contactProcessingThreshold;   
+       double                                  m_deactivationTime;
+       double                                  m_friction;
+       double                                  m_restitution;
+       double                                  m_hitFraction; 
+       double                                  m_ccdSweptSphereRadius;
+       double                                  m_ccdMotionThreshold;
+
+       int                                             m_hasAnisotropicFriction;
+       int                                             m_collisionFlags;
+       int                                             m_islandTag1;
+       int                                             m_companionId;
+       int                                             m_activationState1;
+       int                                             m_internalType;
+       int                                             m_checkCollideWith;
+
+       char    m_padding[4];
 };
 
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btCollisionObjectFloatData
+{
+       void                                    *m_broadphaseHandle;
+       void                                    *m_collisionShape;
+       btCollisionShapeData    *m_rootCollisionShape;
+       char                                    *m_name;
+
+       btTransformFloatData    m_worldTransform;
+       btTransformFloatData    m_interpolationWorldTransform;
+       btVector3FloatData              m_interpolationLinearVelocity;
+       btVector3FloatData              m_interpolationAngularVelocity;
+       btVector3FloatData              m_anisotropicFriction;
+       float                                   m_contactProcessingThreshold;   
+       float                                   m_deactivationTime;
+       float                                   m_friction;
+       float                                   m_restitution;
+       float                                   m_hitFraction; 
+       float                                   m_ccdSweptSphereRadius;
+       float                                   m_ccdMotionThreshold;
+
+       int                                             m_hasAnisotropicFriction;
+       int                                             m_collisionFlags;
+       int                                             m_islandTag1;
+       int                                             m_companionId;
+       int                                             m_activationState1;
+       int                                             m_internalType;
+       int                                             m_checkCollideWith;
+};
+
+
+
+SIMD_FORCE_INLINE      int     btCollisionObject::calculateSerializeBufferSize() const
+{
+       return sizeof(btCollisionObjectData);
+}
+
+
+
 #endif //COLLISION_OBJECT_H
index 5c645f82a45b13d56bab2102b401414de1e6a491..bfe8d4f52fb172702fae8629906814d93d576e59 100644 (file)
@@ -26,12 +26,16 @@ 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 "BulletSoftBody/btSoftBody.h"
+#include "LinearMath/btSerializer.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
@@ -43,10 +47,29 @@ 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),
-m_debugDrawer(0)
+m_debugDrawer(0),
+m_forceUpdateAllAabbs(true)
 {
        m_stackAlloc = collisionConfiguration->getStackAllocator();
        m_dispatchInfo.m_stackAllocator = m_stackAlloc;
@@ -89,28 +112,30 @@ btCollisionWorld::~btCollisionWorld()
 void   btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
 {
 
+       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
+               ))      ;
 
 
 
@@ -129,6 +154,16 @@ void       btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
        minAabb -= contactThreshold;
        maxAabb += contactThreshold;
 
+       if(getDispatchInfo().m_convexMaxDistanceUseCPT)
+       {
+               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
@@ -163,7 +198,7 @@ void        btCollisionWorld::updateAabbs()
                btCollisionObject* colObj = m_collisionObjects[i];
 
                //only update aabb of active objects
-               if (colObj->isActive())
+               if (m_forceUpdateAllAabbs || colObj->isActive())
                {
                        updateSingleAabb(colObj);
                }
@@ -226,10 +261,10 @@ 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)
 {
        btSphereShape pointShape(btScalar(0.0));
        pointShape.setMargin(0.f);
@@ -237,7 +272,7 @@ void        btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
 
        if (collisionShape->isConvex())
        {
-//             BT_PROFILE("rayTestConvex");
+               //              BT_PROFILE("rayTestConvex");
                btConvexCast::CastResult castResult;
                castResult.m_fraction = resultCallback.m_closestHitFraction;
 
@@ -266,10 +301,10 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                        castResult.m_normal.normalize();
                                        btCollisionWorld::LocalRayResult localRayResult
                                                (
-                                                       collisionObject,
-                                                       0,
-                                                       castResult.m_normal,
-                                                       castResult.m_fraction
+                                               collisionObject,
+                                               0,
+                                               castResult.m_normal,
+                                               castResult.m_fraction
                                                );
 
                                        bool normalInWorldSpace = true;
@@ -281,7 +316,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
@@ -297,15 +332,18 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                        btCollisionObject*      m_collisionObject;
                                        btTriangleMeshShape*    m_triangleMesh;
 
+                                       btTransform m_colObjWorldTransform;
+
                                        BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-                                               btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*    triangleMesh):
-                  //@BP Mod
-                                               btTriangleRaycastCallback(from,to, resultCallback->m_flags),
-                                                       m_resultCallback(resultCallback),
-                                                       m_collisionObject(collisionObject),
-                                                       m_triangleMesh(triangleMesh)
-                                               {
-                                               }
+                                               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)
+                                       {
+                                       }
 
 
                                        virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
@@ -314,19 +352,21 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                                shapeInfo.m_shapePart = partId;
                                                shapeInfo.m_triangleIndex = triangleIndex;
 
+                                               btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
+
                                                btCollisionWorld::LocalRayResult rayResult
-                                               (m_collisionObject,
+                                                       (m_collisionObject,
                                                        &shapeInfo,
-                                                       hitNormalLocal,
+                                                       hitNormalWorld,
                                                        hitFraction);
 
-                                               bool    normalInWorldSpace = false;
+                                               bool    normalInWorldSpace = true;
                                                return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
                                        }
 
                                };
 
-                               BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+                               BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
                                triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
                        } else
@@ -347,15 +387,18 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                        btCollisionObject*      m_collisionObject;
                                        btConcaveShape* m_triangleMesh;
 
+                                       btTransform m_colObjWorldTransform;
+
                                        BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-                                               btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh):
-                  //@BP Mod
-                  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
-                                                       m_resultCallback(resultCallback),
-                                                       m_collisionObject(collisionObject),
-                                                       m_triangleMesh(triangleMesh)
-                                               {
-                                               }
+                                               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)
+                                       {
+                                       }
 
 
                                        virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
@@ -364,22 +407,22 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                                shapeInfo.m_shapePart = partId;
                                                shapeInfo.m_triangleIndex = triangleIndex;
 
+                                               btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
+
                                                btCollisionWorld::LocalRayResult rayResult
-                                               (m_collisionObject,
+                                                       (m_collisionObject,
                                                        &shapeInfo,
-                                                       hitNormalLocal,
+                                                       hitNormalWorld,
                                                        hitFraction);
 
-                                               bool    normalInWorldSpace = false;
+                                               bool    normalInWorldSpace = true;
                                                return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
-
-
                                        }
 
                                };
 
 
-                               BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
+                               BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
                                btVector3 rayAabbMinLocal = rayFromLocal;
@@ -390,27 +433,118 @@ 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;
+                                       }
+                                       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
+                               {
+                                       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);
+
+                                               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);
-                               int i=0;
-                               for (i=0;i<compoundShape->getNumChildShapes();i++)
+                               const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
+
+
+                               RayTester rayCB(
+                                       collisionObject,
+                                       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.Process(i);
+                                       }       
                                }
                        }
                }
@@ -418,10 +552,10 @@ 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)
 {
        if (collisionShape->isConvex())
        {
@@ -433,15 +567,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
@@ -451,13 +585,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
-                                                               );
+                                               (
+                                               collisionObject,
+                                               0,
+                                               castResult.m_normal,
+                                               castResult.m_hitPoint,
+                                               castResult.m_fraction
+                                               );
 
                                        bool normalInWorldSpace = true;
                                        resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
@@ -487,12 +621,12 @@ void      btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
 
                                        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)
-                                               {
-                                               }
+                                       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 )
@@ -504,7 +638,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                {
 
                                                        btCollisionWorld::LocalConvexResult convexResult
-                                                       (m_collisionObject,
+                                                               (m_collisionObject,
                                                                &shapeInfo,
                                                                hitNormalLocal,
                                                                hitPointLocal,
@@ -522,6 +656,7 @@ 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);
@@ -544,12 +679,12 @@ void      btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
 
                                        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)
-                                               {
-                                               }
+                                       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 )
@@ -561,7 +696,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                {
 
                                                        btCollisionWorld::LocalConvexResult convexResult
-                                                       (m_collisionObject,
+                                                               (m_collisionObject,
                                                                &shapeInfo,
                                                                hitNormalLocal,
                                                                hitPointLocal,
@@ -578,6 +713,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
 
                                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);
 
@@ -604,11 +740,41 @@ void      btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                        // replace collision shape so that callback can determine the triangle
                                        btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
                                        collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+                    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);
+                                       
+
                                        objectQuerySingle(castShape, convexFromTrans,convexToTrans,
                                                collisionObject,
                                                childCollisionShape,
                                                childWorldTrans,
-                                               resultCallback, allowedPenetration);
+                                               my_cb, allowedPenetration);
                                        // restore
                                        collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
                                }
@@ -631,10 +797,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);
@@ -644,10 +810,10 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
                btVector3 rayDir = (rayToWorld-rayFromWorld);
 
                rayDir.normalize ();
-               ///what about division by zero? --> just set rayDirection[i] to INF/1e30
-               m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-               m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-               m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+               ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
+               m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+               m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+               m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
                m_signs[0] = m_rayDirectionInverse[0] < 0.0;
                m_signs[1] = m_rayDirectionInverse[1] < 0.0;
                m_signs[2] = m_rayDirectionInverse[2] < 0.0;
@@ -656,7 +822,7 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
 
        }
 
-       
+
 
        virtual bool    process(const btBroadphaseProxy* proxy)
        {
@@ -687,9 +853,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;
@@ -698,7 +864,7 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
 
 void   btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
 {
-       BT_PROFILE("rayTest");
+       //BT_PROFILE("rayTest");
        /// use the broadphase to accelerate the search for objects, based on their aabb
        /// and for each object with ray-aabb overlap, perform an exact ray test
        btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
@@ -737,10 +903,10 @@ struct btSingleSweepCallback : public btBroadphaseRayCallback
        {
                btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
                btVector3 rayDir = unnormalizedRayDir.normalized();
-               ///what about division by zero? --> just set rayDirection[i] to INF/1e30
-               m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-               m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-               m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+               ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
+               m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+               m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+               m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
                m_signs[0] = m_rayDirectionInverse[0] < 0.0;
                m_signs[1] = m_rayDirectionInverse[1] < 0.0;
                m_signs[2] = m_rayDirectionInverse[2] < 0.0;
@@ -761,13 +927,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;
        }
 };
@@ -782,7 +948,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;
@@ -825,12 +991,455 @@ 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( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
+               :btManifoldResult(obj0,obj1),
+               m_resultCallback(resultCallback)
+       {
+       }
+
+       virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+       {
+               bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+               btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
+               btVector3 localA;
+               btVector3 localB;
+               if (isSwapped)
+               {
+                       localA = m_rootTransB.invXform(pointA );
+                       localB = m_rootTransA.invXform(pointInWorld);
+               } else
+               {
+                       localA = m_rootTransA.invXform(pointA );
+                       localB = m_rootTransB.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.
+               btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
+               btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
+               m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,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())) 
+               {
+                       btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
+                       if (algorithm)
+                       {
+                               btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
+                               //discrete collision detection query
+                               algorithm->processCollision(m_collisionObject,collisionObject, 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)
+{
+       btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
+       if (algorithm)
+       {
+               btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
+               //discrete collision detection query
+               algorithm->processCollision(colObjA,colObjB, 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.);
+
+                 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:
+                       {
+
+                               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 a,b;
+                                               polyshape->getEdge(i,a,b);
+                                               btVector3 wa = worldTransform * a;
+                                               btVector3 wb = worldTransform * b;
+                                               getDebugDrawer()->drawLine(wa,wb,color);
+
+                                       }
+
+
+                               }
+                       }
+               }
+       }
+}
+
+
+void   btCollisionWorld::debugDrawWorld()
+{
+       if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
+       {
+               int numManifolds = getDispatcher()->getNumManifolds();
+               btVector3 color(0,0,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;
+
+                                       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();
+}
+
index 1f785cf69e4aa6762aec942e07c1e2b8ad9287fc..b42e2c40b2114b94bc41918615729d784151bfe9 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Bullet Continuous Collision Detection and Physics %Library
+Bullet Continuous Collision Detection and Physics Library
 Copyright (c) 2003-2006 Erwin Coumans  http://bulletphysics.com/Bullet/
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -15,50 +15,48 @@ subject to the following restrictions:
 
 
 /**
- * \file btCollisionWorld.h
- * \ingroup bullet
- *
- * @page bulletdoc Bullet Documentation
+ * @mainpage Bullet Documentation
  *
  * @section intro_sec Introduction
  * Bullet Collision Detection & Physics SDK
  *
- * Bullet is a Collision Detection and Rigid Body Dynamics %Library. The %Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
+ * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
  *
+ * The main documentation is Bullet_User_Manual.pdf, included in the source code distribution.
  * There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
  * Please visit http://www.bulletphysics.com
  *
  * @section install_sec Installation
  *
  * @subsection step1 Step 1: Download
- * You can download the Bullet Physics %Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
+ * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
+ *
  * @subsection step2 Step 2: Building
- * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
- * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
- * 
- * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
- * So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
- * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
- * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
+ * Bullet main build system for all platforms is cmake, you can download http://www.cmake.org
+ * cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles.
+ * The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles.
+ * You can also use cmake in the command-line. Here are some examples for various platforms:
+ * cmake . -G "Visual Studio 9 2008"
+ * cmake . -G Xcode
+ * cmake . -G "Unix Makefiles"
+ * Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make.
  * 
  * @subsection step3 Step 3: Testing demos
  * Try to run and experiment with BasicDemo executable as a starting point.
- * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector %Library or Low Level / Snippets like the GJK Closest Point calculation.
+ * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation.
  * The Dependencies can be seen in this documentation under Directories
  * 
  * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation
  * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
  * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld.
- * @subsection step5 Step 5 : Integrate the Collision Detection %Library (without Dynamics and other Extras)
+ * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras)
  * Bullet Collision Detection can also be used without the Dynamics/Extras.
  * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo.
  * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation.
  * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
  *
  * @section copyright Copyright
- * Copyright (C) 2005-2008 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
- * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
- * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
+ * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf
  * 
  */
  
@@ -71,6 +69,8 @@ class btStackAlloc;
 class btCollisionShape;
 class btConvexShape;
 class btBroadphaseInterface;
+class btSerializer;
+
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btTransform.h"
 #include "btCollisionObject.h"
@@ -97,7 +97,12 @@ protected:
 
        btIDebugDraw*   m_debugDrawer;
 
-       
+       ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs
+       ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB)
+       bool m_forceUpdateAllAabbs;
+
+       void    serializeCollisionObjects(btSerializer* serializer);
+
 public:
 
        //this constructor doesn't own the dispatcher and paircache/broadphase
@@ -150,6 +155,10 @@ public:
                return m_debugDrawer;
        }
 
+       virtual void    debugDrawWorld();
+
+       virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
+
 
        ///LocalShapeInfo gives extra information for complex shapes
        ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart
@@ -255,6 +264,45 @@ public:
                }
        };
 
+       struct  AllHitsRayResultCallback : public RayResultCallback
+       {
+               AllHitsRayResultCallback(const btVector3&       rayFromWorld,const btVector3&   rayToWorld)
+               :m_rayFromWorld(rayFromWorld),
+               m_rayToWorld(rayToWorld)
+               {
+               }
+
+               btAlignedObjectArray<btCollisionObject*>                m_collisionObjects;
+
+               btVector3       m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
+               btVector3       m_rayToWorld;
+
+               btAlignedObjectArray<btVector3> m_hitNormalWorld;
+               btAlignedObjectArray<btVector3> m_hitPointWorld;
+               btAlignedObjectArray<btScalar> m_hitFractions;
+                       
+               virtual btScalar        addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
+               {
+                       m_collisionObject = rayResult.m_collisionObject;
+                       m_collisionObjects.push_back(rayResult.m_collisionObject);
+                       btVector3 hitNormalWorld;
+                       if (normalInWorldSpace)
+                       {
+                               hitNormalWorld = rayResult.m_hitNormalLocal;
+                       } else
+                       {
+                               ///need to transform normal into worldspace
+                               hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
+                       }
+                       m_hitNormalWorld.push_back(hitNormalWorld);
+                       btVector3 hitPointWorld;
+                       hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
+                       m_hitPointWorld.push_back(hitPointWorld);
+                       m_hitFractions.push_back(rayResult.m_hitFraction);
+                       return m_closestHitFraction;
+               }
+       };
+
 
        struct LocalConvexResult
        {
@@ -350,6 +398,34 @@ public:
                }
        };
 
+       ///ContactResultCallback is used to report contact points
+       struct  ContactResultCallback
+       {
+               short int       m_collisionFilterGroup;
+               short int       m_collisionFilterMask;
+               
+               ContactResultCallback()
+                       :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
+                       m_collisionFilterMask(btBroadphaseProxy::AllFilter)
+               {
+               }
+
+               virtual ~ContactResultCallback()
+               {
+               }
+               
+               virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+               {
+                       bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
+                       collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+                       return collides;
+               }
+
+               virtual btScalar        addSingleResult(btManifoldPoint& cp,    const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0;
+       };
+
+
+
        int     getNumCollisionObjects() const
        {
                return int(m_collisionObjects.size());
@@ -359,10 +435,18 @@ public:
        /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
        virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 
 
-       // convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
-       // This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
+       /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
+       /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
        void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback,  btScalar allowedCcdPenetration = btScalar(0.)) const;
 
+       ///contactTest performs a discrete collision test between colObj 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    contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
+
+       ///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    contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
+
 
        /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
        /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
@@ -380,7 +464,7 @@ public:
                                          const btTransform& colObjWorldTransform,
                                          ConvexResultCallback& resultCallback, btScalar        allowedPenetration);
 
-       void    addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
+       virtual void    addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
 
        btCollisionObjectArray& getCollisionObjectArray()
        {
@@ -393,7 +477,7 @@ public:
        }
 
 
-       void    removeCollisionObject(btCollisionObject* collisionObject);
+       virtual void    removeCollisionObject(btCollisionObject* collisionObject);
 
        virtual void    performDiscreteCollisionDetection();
 
@@ -406,6 +490,18 @@ public:
        {
                return m_dispatchInfo;
        }
+       
+       bool    getForceUpdateAllAabbs() const
+       {
+               return m_forceUpdateAllAabbs;
+       }
+       void setForceUpdateAllAabbs( bool forceUpdateAllAabbs)
+       {
+               m_forceUpdateAllAabbs = forceUpdateAllAabbs;
+       }
+
+       ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo)
+       virtual void    serialize(btSerializer* serializer);
 
 };
 
index 1dea91a0b0b4ea68b5b03e7dbfcd6524aec45c0b..54889a6375d1540aea34d56425ebd2b168e3ccd2 100644 (file)
@@ -114,8 +114,9 @@ public:
 
        void    ProcessChildShape(btCollisionShape* childShape,int index)
        {
-               
+               btAssert(index>=0);
                btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
+               btAssert(index<compoundShape->getNumChildShapes());
 
 
                //backup
@@ -142,6 +143,15 @@ public:
                        if (!m_childCollisionAlgorithms[index])
                                m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
 
+                       ///detect swapping case
+                       if (m_resultOut->getBody0Internal() == m_compoundColObj)
+                       {
+                               m_resultOut->setShapeIdentifiersA(-1,index);
+                       } else
+                       {
+                               m_resultOut->setShapeIdentifiersB(-1,index);
+                       }
+
                        m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
                        if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
                        {
@@ -224,7 +234,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
                                                resultOut->setPersistentManifold(0);//??necessary?
                                        }
                                }
-                               manifoldArray.clear();
+                               manifoldArray.resize(0);
                        }
                }
        }
@@ -257,20 +267,24 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
                int numChildren = m_childCollisionAlgorithms.size();
                int i;
                btManifoldArray manifoldArray;
-
+        btCollisionShape* childShape = 0;
+        btTransform    orgTrans;
+        btTransform    orgInterpolationTrans;
+        btTransform    newChildWorldTrans;
+        btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;        
+        
                for (i=0;i<numChildren;i++)
                {
                        if (m_childCollisionAlgorithms[i])
                        {
-                               btCollisionShape* childShape = compoundShape->getChildShape(i);
+                               childShape = compoundShape->getChildShape(i);
                        //if not longer overlapping, remove the algorithm
-                               btTransform     orgTrans = colObj->getWorldTransform();
-                               btTransform     orgInterpolationTrans = colObj->getInterpolationWorldTransform();
+                orgTrans = colObj->getWorldTransform();
+                orgInterpolationTrans = colObj->getInterpolationWorldTransform();
                                const btTransform& childTrans = compoundShape->getChildTransform(i);
-                               btTransform     newChildWorldTrans = orgTrans*childTrans ;
+                newChildWorldTrans = orgTrans*childTrans ;
 
                                //perform an AABB check first
-                               btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
                                childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
                                otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
 
@@ -280,13 +294,8 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
                                        m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
                                        m_childCollisionAlgorithms[i] = 0;
                                }
-
                        }
-                       
                }
-
-               
-
        }
 }
 
@@ -311,13 +320,15 @@ btScalar  btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
 
        int numChildren = m_childCollisionAlgorithms.size();
        int i;
+    btTransform        orgTrans;
+    btScalar frac;
        for (i=0;i<numChildren;i++)
        {
                //temporarily exchange parent btCollisionShape with childShape, and recurse
                btCollisionShape* childShape = compoundShape->getChildShape(i);
 
                //backup
-               btTransform     orgTrans = colObj->getWorldTransform();
+        orgTrans = colObj->getWorldTransform();
        
                const btTransform& childTrans = compoundShape->getChildTransform(i);
                //btTransform   newChildWorldTrans = orgTrans*childTrans ;
@@ -325,7 +336,7 @@ btScalar    btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
 
                btCollisionShape* tmpShape = colObj->getCollisionShape();
                colObj->internalSetTemporaryCollisionShape( childShape );
-               btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
+        frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
                if (frac<hitFraction)
                {
                        hitFraction = frac;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
new file mode 100644 (file)
index 0000000..db7f884
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+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.
+*/
+
+#include "btConvex2dConvex2dAlgorithm.h"
+
+//#include <stdio.h>
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
+
+
+
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+
+
+btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*                  simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
+{
+       m_numPerturbationIterations = 0;
+       m_minimumPointsPerturbationThreshold = 3;
+       m_simplexSolver = simplexSolver;
+       m_pdSolver = pdSolver;
+}
+
+btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() 
+{ 
+}
+
+btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_simplexSolver(simplexSolver),
+m_pdSolver(pdSolver),
+m_ownManifold (false),
+m_manifoldPtr(mf),
+m_lowLevelOfDetail(false),
+ m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
+{
+       (void)body0;
+       (void)body1;
+}
+
+
+
+
+btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm()
+{
+       if (m_ownManifold)
+       {
+               if (m_manifoldPtr)
+                       m_dispatcher->releaseManifold(m_manifoldPtr);
+       }
+}
+
+void   btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
+{
+       m_lowLevelOfDetail = useLowLevel;
+}
+
+
+
+extern btScalar gContactBreakingThreshold;
+
+
+//
+// Convex-Convex collision algorithm
+//
+void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+
+       if (!m_manifoldPtr)
+       {
+               //swapped?
+               m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+               m_ownManifold = true;
+       }
+       resultOut->setPersistentManifold(m_manifoldPtr);
+
+       //comment-out next line to test multi-contact generation
+       //resultOut->getPersistentManifold()->clearManifold();
+
+
+       btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
+       btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+
+       btVector3  normalOnB;
+       btVector3  pointOnBWorld;
+
+       {
+
+
+               btGjkPairDetector::ClosestPointInput input;
+
+               btGjkPairDetector       gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
+               //TODO: if (dispatchInfo.m_useContinuous)
+               gjkPairDetector.setMinkowskiA(min0);
+               gjkPairDetector.setMinkowskiB(min1);
+
+               {
+                       input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+                       input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+               }
+
+               input.m_stackAlloc = dispatchInfo.m_stackAllocator;
+               input.m_transformA = body0->getWorldTransform();
+               input.m_transformB = body1->getWorldTransform();
+
+               gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
+               btVector3 v0,v1;
+               btVector3 sepNormalWorldSpace;
+
+       }
+
+       if (m_ownManifold)
+       {
+               resultOut->refreshContactPoints();
+       }
+
+}
+
+
+
+
+btScalar       btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+       (void)resultOut;
+       (void)dispatchInfo;
+       ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
+
+       ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
+       ///col0->m_worldTransform,
+       btScalar resultFraction = btScalar(1.);
+
+
+       btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
+       btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
+
+       if (squareMot0 < col0->getCcdSquareMotionThreshold() &&
+               squareMot1 < col1->getCcdSquareMotionThreshold())
+               return resultFraction;
+
+
+       //An adhoc way of testing the Continuous Collision Detection algorithms
+       //One object is approximated as a sphere, to simplify things
+       //Starting in penetration should report no time of impact
+       //For proper CCD, better accuracy and handling of 'allowed' penetration should be added
+       //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
+
+
+       /// Convex0 against sphere for Convex1
+       {
+               btConvexShape* convex0 = static_cast<btConvexShape*>(col0->getCollisionShape());
+
+               btSphereShape   sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
+               btConvexCast::CastResult result;
+               btVoronoiSimplexSolver voronoiSimplex;
+               //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
+               ///Simplification, one object is simplified as a sphere
+               btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex);
+               //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
+               if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
+                       col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
+               {
+
+                       //store result.m_fraction in both bodies
+
+                       if (col0->getHitFraction()> result.m_fraction)
+                               col0->setHitFraction( result.m_fraction );
+
+                       if (col1->getHitFraction() > result.m_fraction)
+                               col1->setHitFraction( result.m_fraction);
+
+                       if (resultFraction > result.m_fraction)
+                               resultFraction = result.m_fraction;
+
+               }
+
+
+
+
+       }
+
+       /// Sphere (for convex0) against Convex1
+       {
+               btConvexShape* convex1 = static_cast<btConvexShape*>(col1->getCollisionShape());
+
+               btSphereShape   sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
+               btConvexCast::CastResult result;
+               btVoronoiSimplexSolver voronoiSimplex;
+               //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
+               ///Simplification, one object is simplified as a sphere
+               btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex);
+               //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
+               if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
+                       col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
+               {
+
+                       //store result.m_fraction in both bodies
+
+                       if (col0->getHitFraction()      > result.m_fraction)
+                               col0->setHitFraction( result.m_fraction);
+
+                       if (col1->getHitFraction() > result.m_fraction)
+                               col1->setHitFraction( result.m_fraction);
+
+                       if (resultFraction > result.m_fraction)
+                               resultFraction = result.m_fraction;
+
+               }
+       }
+
+       return resultFraction;
+
+}
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
new file mode 100644 (file)
index 0000000..5738401
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+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.
+*/
+
+#ifndef CONVEX_2D_CONVEX_2D_ALGORITHM_H
+#define CONVEX_2D_CONVEX_2D_ALGORITHM_H
+
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
+
+class btConvexPenetrationDepthSolver;
+
+
+///The convex2dConvex2dAlgorithm collision algorithm support 2d collision detection for btConvex2dShape
+///Currently it requires the btMinkowskiPenetrationDepthSolver, it has support for 2d penetration depth computation
+class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
+{
+       btSimplexSolverInterface*               m_simplexSolver;
+       btConvexPenetrationDepthSolver* m_pdSolver;
+
+       
+       bool    m_ownManifold;
+       btPersistentManifold*   m_manifoldPtr;
+       bool                    m_lowLevelOfDetail;
+       
+       int m_numPerturbationIterations;
+       int m_minimumPointsPerturbationThreshold;
+
+public:
+
+       btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
+
+
+       virtual ~btConvex2dConvex2dAlgorithm();
+
+       virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+       virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+       virtual void    getAllContactManifolds(btManifoldArray& manifoldArray)
+       {
+               ///should we use m_ownManifold to avoid adding duplicates?
+               if (m_manifoldPtr && m_ownManifold)
+                       manifoldArray.push_back(m_manifoldPtr);
+       }
+
+
+       void    setLowLevelOfDetail(bool useLowLevel);
+
+
+       const btPersistentManifold*     getManifold()
+       {
+               return m_manifoldPtr;
+       }
+
+       struct CreateFunc :public       btCollisionAlgorithmCreateFunc
+       {
+
+               btConvexPenetrationDepthSolver*         m_pdSolver;
+               btSimplexSolverInterface*                       m_simplexSolver;
+               int m_numPerturbationIterations;
+               int m_minimumPointsPerturbationThreshold;
+
+               CreateFunc(btSimplexSolverInterface*                    simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
+               
+               virtual ~CreateFunc();
+
+               virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+               {
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm));
+                       return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+               }
+       };
+
+
+};
+
+#endif //CONVEX_2D_CONVEX_2D_ALGORITHM_H
index cbc5530732b6fe138f8a03fda60ce2210cb1e5e7..268ec4b6c7e9a0e195119e427c6d89881d47b687 100644 (file)
@@ -95,7 +95,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
        ///debug drawing of the overlapping triangles
        if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
        {
-               btVector3 color(255,255,0);
+               btVector3 color(1,1,0);
                btTransform& tr = ob->getWorldTransform();
                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
@@ -121,12 +121,16 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
                ob->internalSetTemporaryCollisionShape( &tm );
                
                btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
-               ///this should use the btDispatcher, so the actual registered algorithm is used
-               //              btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
 
-               m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex);
-       //      cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
-//             cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+               if (m_resultOut->getBody0Internal() == m_triBody)
+               {
+                       m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
+               }
+               else
+               {
+                       m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
+               }
+       
                colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
                colAlgo->~btCollisionAlgorithm();
                ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
index 496fd996f8c78e381e80c17811ba4d33db5171e0..ede1afb2a036202e477839a51adca65b7140c627 100644 (file)
@@ -13,6 +13,11 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
+///Specialized capsule-capsule collision algorithm has been added for Bullet 2.75 release to increase ragdoll performance
+///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
+
 #include "btConvexConvexAlgorithm.h"
 
 //#include <stdio.h>
@@ -20,6 +25,9 @@ subject to the following restrictions:
 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
 #include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+
+
 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
@@ -43,8 +51,127 @@ subject to the following restrictions:
 
 
 
+///////////
+
+
+
+static SIMD_FORCE_INLINE void segmentsClosestPoints(
+       btVector3& ptsVector,
+       btVector3& offsetA,
+       btVector3& offsetB,
+       btScalar& tA, btScalar& tB,
+       const btVector3& translation,
+       const btVector3& dirA, btScalar hlenA,
+       const btVector3& dirB, btScalar hlenB )
+{
+       // compute the parameters of the closest points on each line segment
+
+       btScalar dirA_dot_dirB = btDot(dirA,dirB);
+       btScalar dirA_dot_trans = btDot(dirA,translation);
+       btScalar dirB_dot_trans = btDot(dirB,translation);
+
+       btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB;
+
+       if ( denom == 0.0f ) {
+               tA = 0.0f;
+       } else {
+               tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom;
+               if ( tA < -hlenA )
+                       tA = -hlenA;
+               else if ( tA > hlenA )
+                       tA = hlenA;
+       }
+
+       tB = tA * dirA_dot_dirB - dirB_dot_trans;
+
+       if ( tB < -hlenB ) {
+               tB = -hlenB;
+               tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+               if ( tA < -hlenA )
+                       tA = -hlenA;
+               else if ( tA > hlenA )
+                       tA = hlenA;
+       } else if ( tB > hlenB ) {
+               tB = hlenB;
+               tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+               if ( tA < -hlenA )
+                       tA = -hlenA;
+               else if ( tA > hlenA )
+                       tA = hlenA;
+       }
+
+       // compute the closest points relative to segment centers.
+
+       offsetA = dirA * tA;
+       offsetB = dirB * tB;
+
+       ptsVector = translation - offsetA + offsetB;
+}
+
+
+static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance(
+       btVector3& normalOnB,
+       btVector3& pointOnB,
+       btScalar capsuleLengthA,
+       btScalar        capsuleRadiusA,
+       btScalar capsuleLengthB,
+       btScalar        capsuleRadiusB,
+       int capsuleAxisA,
+       int capsuleAxisB,
+       const btTransform& transformA,
+       const btTransform& transformB,
+       btScalar distanceThreshold )
+{
+       btVector3 directionA = transformA.getBasis().getColumn(capsuleAxisA);
+       btVector3 translationA = transformA.getOrigin();
+       btVector3 directionB = transformB.getBasis().getColumn(capsuleAxisB);
+       btVector3 translationB = transformB.getOrigin();
+
+       // translation between centers
+
+       btVector3 translation = translationB - translationA;
+
+       // compute the closest points of the capsule line segments
+
+       btVector3 ptsVector;           // the vector between the closest points
+       
+       btVector3 offsetA, offsetB;    // offsets from segment centers to their closest points
+       btScalar tA, tB;              // parameters on line segment
+
+       segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation,
+                                                  directionA, capsuleLengthA, directionB, capsuleLengthB );
+
+       btScalar distance = ptsVector.length() - capsuleRadiusA - capsuleRadiusB;
+
+       if ( distance > distanceThreshold )
+               return distance;
+
+       btScalar lenSqr = ptsVector.length2();
+       if (lenSqr<= (SIMD_EPSILON*SIMD_EPSILON))
+       {
+               //degenerate case where 2 capsules are likely at the same location: take a vector tangential to 'directionA'
+               btVector3 q;
+               btPlaneSpace1(directionA,normalOnB,q);
+       } else
+       {
+               // compute the contact normal
+               normalOnB = ptsVector*-btRecipSqrt(lenSqr);
+       }
+       pointOnB = transformB.getOrigin()+offsetB + normalOnB * capsuleRadiusB;
+
+       return distance;
+}
+
+
+
+
+
 
 
+//////////
+
 
 
 
@@ -69,7 +196,7 @@ m_ownManifold (false),
 m_manifoldPtr(mf),
 m_lowLevelOfDetail(false),
 #ifdef USE_SEPDISTANCE_UTIL2
-,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
+m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
                          (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
 #endif
 m_numPerturbationIterations(numPerturbationIterations),
@@ -111,8 +238,8 @@ struct btPerturbedContactResult : public btManifoldResult
                :m_originalManifoldResult(originalResult),
                m_transformA(transformA),
                m_transformB(transformB),
-               m_perturbA(perturbA),
                m_unPerturbedTransform(unPerturbedTransform),
+               m_perturbA(perturbA),
                m_debugDrawer(debugDrawer)
        {
        }
@@ -155,6 +282,7 @@ struct btPerturbedContactResult : public btManifoldResult
 
 extern btScalar gContactBreakingThreshold;
 
+
 //
 // Convex-Convex collision algorithm
 //
@@ -176,8 +304,39 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
        btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
        btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
 
+       btVector3  normalOnB;
+               btVector3  pointOnBWorld;
+#ifndef BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
+       if ((min0->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) && (min1->getShapeType() == CAPSULE_SHAPE_PROXYTYPE))
+       {
+               btCapsuleShape* capsuleA = (btCapsuleShape*) min0;
+               btCapsuleShape* capsuleB = (btCapsuleShape*) min1;
+               btVector3 localScalingA = capsuleA->getLocalScaling();
+               btVector3 localScalingB = capsuleB->getLocalScaling();
+               
+               btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
+
+               btScalar dist = capsuleCapsuleDistance(normalOnB,       pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(),
+                       capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(),
+                       body0->getWorldTransform(),body1->getWorldTransform(),threshold);
+
+               if (dist<threshold)
+               {
+                       btAssert(normalOnB.length2()>=(SIMD_EPSILON*SIMD_EPSILON));
+                       resultOut->addContactPoint(normalOnB,pointOnBWorld,dist);       
+               }
+               resultOut->refreshContactPoints();
+               return;
+       }
+#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
+
+
 #ifdef USE_SEPDISTANCE_UTIL2
-       m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+       if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+       {
+               m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+       }
+
        if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
 #endif //USE_SEPDISTANCE_UTIL2
 
@@ -194,31 +353,55 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
 #ifdef USE_SEPDISTANCE_UTIL2
        if (dispatchInfo.m_useConvexConservativeDistanceUtil)
        {
-               input.m_maximumDistanceSquared = 1e30f;
+               input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
        } else
 #endif //USE_SEPDISTANCE_UTIL2
        {
-               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;
        }
 
+       input.m_stackAlloc = dispatchInfo.m_stackAllocator;
        input.m_transformA = body0->getWorldTransform();
        input.m_transformB = body1->getWorldTransform();
 
        gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
-       btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold;
 
-       //now perturbe directions to get multiple contact points
-       btVector3 v0,v1;
-       btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
-       btPlaneSpace1(sepNormalWorldSpace,v0,v1);
+       
+
+#ifdef USE_SEPDISTANCE_UTIL2
+       btScalar sepDist = 0.f;
+       if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+       {
+               sepDist = gjkPairDetector.getCachedSeparatingDistance();
+               if (sepDist>SIMD_EPSILON)
+               {
+                       sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
+                       //now perturbe directions to get multiple contact points
+                       
+               }
+       }
+#endif //USE_SEPDISTANCE_UTIL2
+
        //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
        
        //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
-       if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
+       if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
        {
                
                int i;
+               btVector3 v0,v1;
+               btVector3 sepNormalWorldSpace;
+       
+               sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
+               btPlaneSpace1(sepNormalWorldSpace,v0,v1);
+
 
                bool perturbeA = true;
                const btScalar angleLimit = 0.125f * SIMD_PI;
@@ -248,6 +431,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
                
                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);
@@ -271,7 +456,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
                        
                        btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
                        gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
-                       
+                       }
                        
                }
        }
@@ -279,7 +464,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
        
 
 #ifdef USE_SEPDISTANCE_UTIL2
-       if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+       if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON))
        {
                m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,bo