Upgrade Bullet to version 2.83.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Sun, 17 Jan 2016 20:35:32 +0000 (21:35 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 25 Jan 2016 21:14:46 +0000 (22:14 +0100)
I tried to carefully preserve all patches since the last upgrade.

Improves T47195, cloth collision detection bug.

Differential Revision: https://developer.blender.org/D1739

133 files changed:
extern/bullet2/CMakeLists.txt
extern/bullet2/patches/blender.patch [new file with mode: 0644]
extern/bullet2/patches/convex_hull.patch [deleted file]
extern/bullet2/readme.txt
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
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/btCollisionWorldImporter.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
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/btConvexHullShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
extern/bullet2/src/BulletCollision/Doxyfile [deleted file]
extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.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/BulletDynamics/Character/btKinematicCharacterController.cpp
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/btContactSolverInfo.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h [new file with mode: 0644]
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/btTypedConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyLink.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h
extern/bullet2/src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp
extern/bullet2/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/MLCPSolvers/btLemkeSolver.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp
extern/bullet2/src/BulletDynamics/MLCPSolvers/btMLCPSolver.h
extern/bullet2/src/BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
extern/bullet2/src/BulletSoftBody/btSoftBody.h
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
extern/bullet2/src/BulletSoftBody/btSparseSDF.h
extern/bullet2/src/LinearMath/btAlignedObjectArray.h
extern/bullet2/src/LinearMath/btCpuFeatureUtility.h [new file with mode: 0644]
extern/bullet2/src/LinearMath/btDefaultMotionState.h
extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h
extern/bullet2/src/LinearMath/btHashMap.h
extern/bullet2/src/LinearMath/btIDebugDraw.h
extern/bullet2/src/LinearMath/btMatrix3x3.h
extern/bullet2/src/LinearMath/btMatrixX.h
extern/bullet2/src/LinearMath/btQuadWord.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
extern/bullet2/src/LinearMath/btSerializer.h
extern/bullet2/src/LinearMath/btSpatialAlgebra.h [new file with mode: 0644]
extern/bullet2/src/LinearMath/btTransform.h
extern/bullet2/src/LinearMath/btVector3.cpp
extern/bullet2/src/LinearMath/btVector3.h

index 2b2c18c06853756b3c68ff17bb20a3885c9ef99e..949a8b01bd2ace05a5b22f813e9eeee8c7dfc59c 100644 (file)
@@ -43,53 +43,53 @@ set(SRC
        src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
        src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
        src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
+       src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
        src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
-       src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
+       src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
        src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
        src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
        src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+       src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp
        src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+       src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
+       src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
-       src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
        src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btGhostObject.cpp
+       src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
        src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
-       src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
        src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
        src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
        src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
        src/BulletCollision/CollisionDispatch/btUnionFind.cpp
-       src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
-       src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
-       src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
-       src/BulletCollision/CollisionShapes/btBoxShape.cpp
        src/BulletCollision/CollisionShapes/btBox2dShape.cpp
+       src/BulletCollision/CollisionShapes/btBoxShape.cpp
        src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
        src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
        src/BulletCollision/CollisionShapes/btCollisionShape.cpp
        src/BulletCollision/CollisionShapes/btCompoundShape.cpp
        src/BulletCollision/CollisionShapes/btConcaveShape.cpp
        src/BulletCollision/CollisionShapes/btConeShape.cpp
+       src/BulletCollision/CollisionShapes/btConvex2dShape.cpp
        src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
        src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
        src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
        src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
        src/BulletCollision/CollisionShapes/btConvexShape.cpp
-       src/BulletCollision/CollisionShapes/btConvex2dShape.cpp
        src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
        src/BulletCollision/CollisionShapes/btCylinderShape.cpp
        src/BulletCollision/CollisionShapes/btEmptyShape.cpp
        src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
        src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
-       src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp
        src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
+       src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp
        src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
        src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
        src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
@@ -106,11 +106,11 @@ set(SRC
        src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
        src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
        src/BulletCollision/Gimpact/btContactProcessing.cpp
-       src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
        src/BulletCollision/Gimpact/btGImpactBvh.cpp
        src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
        src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
        src/BulletCollision/Gimpact/btGImpactShape.cpp
+       src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
        src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
        src/BulletCollision/Gimpact/gim_box_set.cpp
        src/BulletCollision/Gimpact/gim_contact.cpp
@@ -124,32 +124,32 @@ set(SRC
        src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
        src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
        src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
+       src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
        src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
-       src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
-       
+
+       src/BulletDynamics/Character/btKinematicCharacterController.cpp
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
+       src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
+       src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
+       src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
        src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp
        src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
+       src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp
        src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
        src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
-       src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
-       src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
+       src/BulletDynamics/Dynamics/Bullet-C-API.cpp
        src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
        src/BulletDynamics/Dynamics/btRigidBody.cpp
        src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
-       src/BulletDynamics/Dynamics/Bullet-C-API.cpp
-       src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
-       src/BulletDynamics/Vehicle/btWheelInfo.cpp
-       src/BulletDynamics/Character/btKinematicCharacterController.cpp
        src/BulletDynamics/Featherstone/btMultiBody.cpp
        src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp
        src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
@@ -158,8 +158,12 @@ set(SRC
        src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp
        src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp
        src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp
+       src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp
        src/BulletDynamics/MLCPSolvers/btMLCPSolver.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
@@ -167,18 +171,16 @@ set(SRC
        src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
        src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
        src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp
-       src/BulletSoftBody/btDefaultSoftBodySolver.cpp
-       
+
        src/LinearMath/btAlignedAllocator.cpp
        src/LinearMath/btConvexHull.cpp
        src/LinearMath/btConvexHullComputer.cpp
        src/LinearMath/btGeometryUtil.cpp
+       src/LinearMath/btPolarDecomposition.cpp
        src/LinearMath/btQuickprof.cpp
        src/LinearMath/btSerializer.cpp
        src/LinearMath/btVector3.cpp
-       src/LinearMath/btPolarDecomposition.cpp
-       
-       
+
        src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
        src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
        src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
@@ -191,35 +193,37 @@ set(SRC
        src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h
        src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
        src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
+       src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
        src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
-       src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
+       src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h
        src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
        src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
        src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
-       src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h
        src/BulletCollision/CollisionDispatch/btCollisionObject.h
+       src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h
        src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+       src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h
        src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
+       src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
+       src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
        src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
-       src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
        src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
        src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btGhostObject.h
+       src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
+       src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
        src/BulletCollision/CollisionDispatch/btManifoldResult.h
        src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
        src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
        src/BulletCollision/CollisionDispatch/btUnionFind.h
-       src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
-       src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
-       src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
-       src/BulletCollision/CollisionShapes/btBoxShape.h
        src/BulletCollision/CollisionShapes/btBox2dShape.h
+       src/BulletCollision/CollisionShapes/btBoxShape.h
        src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
        src/BulletCollision/CollisionShapes/btCapsuleShape.h
        src/BulletCollision/CollisionShapes/btCollisionMargin.h
@@ -227,20 +231,20 @@ set(SRC
        src/BulletCollision/CollisionShapes/btCompoundShape.h
        src/BulletCollision/CollisionShapes/btConcaveShape.h
        src/BulletCollision/CollisionShapes/btConeShape.h
+       src/BulletCollision/CollisionShapes/btConvex2dShape.h
        src/BulletCollision/CollisionShapes/btConvexHullShape.h
        src/BulletCollision/CollisionShapes/btConvexInternalShape.h
        src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
        src/BulletCollision/CollisionShapes/btConvexPolyhedron.h
        src/BulletCollision/CollisionShapes/btConvexShape.h
-       src/BulletCollision/CollisionShapes/btConvex2dShape.h
        src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
        src/BulletCollision/CollisionShapes/btCylinderShape.h
        src/BulletCollision/CollisionShapes/btEmptyShape.h
        src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
        src/BulletCollision/CollisionShapes/btMaterial.h
        src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
-       src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
        src/BulletCollision/CollisionShapes/btMultiSphereShape.h
+       src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
        src/BulletCollision/CollisionShapes/btOptimizedBvh.h
        src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
        src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
@@ -286,33 +290,43 @@ set(SRC
        src/BulletCollision/Gimpact/gim_memory.h
        src/BulletCollision/Gimpact/gim_radixsort.h
        src/BulletCollision/Gimpact/gim_tri_collision.h
+       src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h
        src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h
        src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
        src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
        src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
+       src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h
        src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
        src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
+       src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h
        src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
        src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
        src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
        src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
+       src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h
        src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
        src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
+       src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
        src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
        src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
-       src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
-       
+
+       src/BulletDynamics/Character/btCharacterControllerInterface.h
+       src/BulletDynamics/Character/btKinematicCharacterController.h
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
        src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
        src/BulletDynamics/ConstraintSolver/btContactConstraint.h
        src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+       src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
+       src/BulletDynamics/ConstraintSolver/btGearConstraint.h
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
+       src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
        src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
        src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
        src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
        src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
+       src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h
        src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
        src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
        src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
@@ -321,22 +335,16 @@ set(SRC
        src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
        src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
        src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
-       src/BulletDynamics/ConstraintSolver/btGearConstraint.h
-       src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
        src/BulletDynamics/Dynamics/btActionInterface.h
        src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
        src/BulletDynamics/Dynamics/btDynamicsWorld.h
-       src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
        src/BulletDynamics/Dynamics/btRigidBody.h
-       src/BulletDynamics/Vehicle/btRaycastVehicle.h
-       src/BulletDynamics/Vehicle/btVehicleRaycaster.h
-       src/BulletDynamics/Vehicle/btWheelInfo.h
-       src/BulletDynamics/Character/btCharacterControllerInterface.h
-       src/BulletDynamics/Character/btKinematicCharacterController.h
+       src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
        src/BulletDynamics/Featherstone/btMultiBody.h
        src/BulletDynamics/Featherstone/btMultiBodyConstraint.h
        src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
        src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
+       src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h
        src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h
        src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h
        src/BulletDynamics/Featherstone/btMultiBodyLink.h
@@ -345,30 +353,36 @@ set(SRC
        src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h
        src/BulletDynamics/MLCPSolvers/btDantzigLCP.h
        src/BulletDynamics/MLCPSolvers/btDantzigSolver.h
+       src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h
+       src/BulletDynamics/MLCPSolvers/btLemkeSolver.h
        src/BulletDynamics/MLCPSolvers/btMLCPSolver.h
        src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h
        src/BulletDynamics/MLCPSolvers/btPATHSolver.h
        src/BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h
-       
+       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/btSoftBodyInternals.h
-       src/BulletSoftBody/btSoftBodyData.h
        src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
+       src/BulletSoftBody/btSoftBodyData.h
        src/BulletSoftBody/btSoftBodyHelpers.h
+       src/BulletSoftBody/btSoftBodyInternals.h
        src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
+       src/BulletSoftBody/btSoftBodySolverVertexBuffer.h
+       src/BulletSoftBody/btSoftBodySolvers.h
        src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
        src/BulletSoftBody/btSoftRigidDynamicsWorld.h
        src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
        src/BulletSoftBody/btSparseSDF.h
-       src/BulletSoftBody/btSoftBodySolvers.h
-       src/BulletSoftBody/btDefaultSoftBodySolver.h
-       src/BulletSoftBody/btSoftBodySolverVertexBuffer.h
-       
+
        src/LinearMath/btAabbUtil2.h
        src/LinearMath/btAlignedAllocator.h
        src/LinearMath/btAlignedObjectArray.h
        src/LinearMath/btConvexHull.h
        src/LinearMath/btConvexHullComputer.h
+       src/LinearMath/btCpuFeatureUtility.h
        src/LinearMath/btDefaultMotionState.h
        src/LinearMath/btGeometryUtil.h
        src/LinearMath/btGrahamScan2dConvexHull.h
@@ -376,8 +390,10 @@ set(SRC
        src/LinearMath/btIDebugDraw.h
        src/LinearMath/btList.h
        src/LinearMath/btMatrix3x3.h
+       src/LinearMath/btMatrixX.h
        src/LinearMath/btMinMax.h
        src/LinearMath/btMotionState.h
+       src/LinearMath/btPolarDecomposition.h
        src/LinearMath/btPoolAllocator.h
        src/LinearMath/btQuadWord.h
        src/LinearMath/btQuaternion.h
@@ -385,14 +401,12 @@ set(SRC
        src/LinearMath/btRandom.h
        src/LinearMath/btScalar.h
        src/LinearMath/btSerializer.h
+       src/LinearMath/btSpatialAlgebra.h
        src/LinearMath/btStackAlloc.h
        src/LinearMath/btTransform.h
        src/LinearMath/btTransformUtil.h
        src/LinearMath/btVector3.h
-       src/LinearMath/btPolarDecomposition.h
-       src/LinearMath/btMatrixX.h
-       
-       
+
        src/btBulletCollisionCommon.h
        src/btBulletDynamicsCommon.h
        src/Bullet-C-Api.h
diff --git a/extern/bullet2/patches/blender.patch b/extern/bullet2/patches/blender.patch
new file mode 100644 (file)
index 0000000..d8e52ec
--- /dev/null
@@ -0,0 +1,150 @@
+diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+index be9eca6..ec40c96 100644
+--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
++++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+@@ -15,7 +15,7 @@ subject to the following restrictions:
+ /**
+- * @mainpage Bullet Documentation
++ * @page Bullet Documentation
+  *
+  * @section intro_sec Introduction
+  * 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 ).
+diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp
+index 36dd043..57eb817 100644
+--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp
++++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp
+@@ -579,14 +579,10 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape(  btCollisionS
+                               btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;
+                               btCompoundShape* compoundShape = createCompoundShape();
+-                              btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0];
+-
+                               btAlignedObjectArray<btCollisionShape*> childShapes;
+                               for (int i=0;i<compoundData->m_numChildShapes;i++)
+                               {
+-                                      btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i];
+-
+                                       btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;
+                                       btCollisionShape* childShape = convertCollisionShape(cd);
+diff --git a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
+index 57fc119..31faf1d 100644
+--- a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
++++ b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
+@@ -29,14 +29,11 @@ subject to the following restrictions:
+ static btVector3
+ getNormalizedVector(const btVector3& v)
+ {
+-      btScalar l = v.length();
+-      btVector3 n = v;
+-      if (l < SIMD_EPSILON) {
+-              n.setValue(0,0,0);
+-      } else {
+-              n /= l;
+-      }
++      btVector3 n(0, 0, 0);
++      if (v.length() > SIMD_EPSILON) {
++              n = v.normalized();
++      }
+       return n;
+ }
+diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
+index 27ccefe..8e4456e 100644
+--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
++++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
+@@ -37,8 +37,13 @@ struct      btSimdScalar
+       {
+       }
+-
++/* workaround for clang 3.4 ( == apple clang 5.1 ) issue, friction would fail with forced inlining */
++#if (defined(__clang__) && defined(__apple_build_version__) &&  (__clang_major__ == 5) && (__clang_minor__ == 1)) \
++|| (defined(__clang__) && !defined(__apple_build_version__) && (__clang_major__ == 3) && (__clang_minor__ == 4))
++      inline __attribute__ ((noinline)) btSimdScalar(float    fl)
++#else
+       SIMD_FORCE_INLINE       btSimdScalar(float      fl)
++#endif
+       :m_vec128 (_mm_set1_ps(fl))
+       {
+       }
+diff --git a/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp b/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
+index 5d62da7..fcd312e 100644
+--- a/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
++++ b/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
+@@ -28,7 +28,6 @@
+ #include "btMultiBodyJointFeedback.h"
+ #include "LinearMath/btTransformUtil.h"
+ #include "LinearMath/btSerializer.h"
+-#include "Bullet3Common/b3Logging.h"
+ // #define INCLUDE_GYRO_TERM 
+ ///todo: determine if we need these options. If so, make a proper API, otherwise delete those globals
+@@ -1732,7 +1731,6 @@ void btMultiBody::goToSleep()
+ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
+ {
+-      int num_links = getNumLinks();
+       extern bool gDisableDeactivation;
+     if (!m_canSleep || gDisableDeactivation) 
+       {
+diff --git a/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
+index 8a034b3..4f66b20 100644
+--- a/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
++++ b/extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
+@@ -809,7 +809,6 @@ static void applyJointFeedback(btMultiBodyJacobianData& data, const btMultiBodyS
+ }
+ #endif
+-#include "Bullet3Common/b3Logging.h"
+ void btMultiBodyConstraintSolver::writeBackSolverBodyToMultiBody(btMultiBodySolverConstraint& c, btScalar deltaTime)
+ {
+ #if 1 
+diff --git a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
+index bcf0c79..8992ddb 100644
+--- a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
++++ b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
+@@ -185,7 +185,6 @@ struct     btSparseSdf
+               {
+                       ++nprobes;              
+                       ++ncells;
+-                      int sz = sizeof(Cell);
+                       if (ncells>m_clampCells)
+                       {
+                               static int numResets=0;
+diff --git a/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp b/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
+index d58ac95..3fd77df 100644
+--- a/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
++++ b/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
+@@ -2665,6 +2665,7 @@ btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, in
+       }
+       vertices.resize(0);
++      original_vertex_index.resize(0);
+       edges.resize(0);
+       faces.resize(0);
+@@ -2675,6 +2676,7 @@ btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, in
+       {
+               btConvexHullInternal::Vertex* v = oldVertices[copied];
+               vertices.push_back(hull.getCoordinates(v));
++              original_vertex_index.push_back(v->point.index);
+               btConvexHullInternal::Edge* firstEdge = v->edges;
+               if (firstEdge)
+               {
+diff --git a/extern/bullet2/src/LinearMath/btConvexHullComputer.h b/extern/bullet2/src/LinearMath/btConvexHullComputer.h
+index 7240ac4..6871ce8 100644
+--- a/extern/bullet2/src/LinearMath/btConvexHullComputer.h
++++ b/extern/bullet2/src/LinearMath/btConvexHullComputer.h
+@@ -67,6 +67,7 @@ class btConvexHullComputer
+               // Vertices of the output hull
+               btAlignedObjectArray<btVector3> vertices;
++              btAlignedObjectArray<int> original_vertex_index;
+               // Edges of the output hull
+               btAlignedObjectArray<Edge> edges;
diff --git a/extern/bullet2/patches/convex_hull.patch b/extern/bullet2/patches/convex_hull.patch
deleted file mode 100644 (file)
index 1b29782..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-Index: extern/bullet2/src/Bullet-C-Api.h
-===================================================================
---- extern/bullet2/src/Bullet-C-Api.h  (revision 51556)
-+++ extern/bullet2/src/Bullet-C-Api.h  (working copy)
-@@ -167,6 +167,16 @@ extern "C" {
-       // needed for source/blender/blenkernel/intern/collision.c
-       double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
-+
-+      /* Convex Hull */
-+      PL_DECLARE_HANDLE(plConvexHull);
-+      plConvexHull plConvexHullCompute(float (*coords)[3], int count);
-+      int plConvexHullNumVertices(plConvexHull hull);
-+      int plConvexHullNumFaces(plConvexHull hull);
-+      void plConvexHullGetVertex(plConvexHull hull, int n, float coords[3], int *original_index);
-+      int plConvexHullGetFaceSize(plConvexHull hull, int n);
-+      void plConvexHullGetFaceVertices(plConvexHull hull, int n, int *vertices);
-+
- #ifdef __cplusplus
- }
- #endif
-Index: extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
-===================================================================
---- extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp        (revision 51556)
-+++ extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp        (working copy)
-@@ -23,7 +23,7 @@ subject to the following restrictions:
- #include "Bullet-C-Api.h"
- #include "btBulletDynamicsCommon.h"
- #include "LinearMath/btAlignedAllocator.h"
--
-+#include "LinearMath/btConvexHullComputer.h"
- #include "LinearMath/btVector3.h"
-@@ -403,3 +403,60 @@ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float
-       return -1.0f;   
- }
-+// Convex hull
-+plConvexHull plConvexHullCompute(float (*coords)[3], int count)
-+{
-+      btConvexHullComputer *computer = new btConvexHullComputer;
-+      computer->compute(reinterpret_cast< float* >(coords),
-+                                        sizeof(*coords), count, 0, 0);
-+      return reinterpret_cast<plConvexHull>(computer);
-+}
-+
-+int plConvexHullNumVertices(plConvexHull hull)
-+{
-+      btConvexHullComputer *computer(reinterpret_cast< btConvexHullComputer* >(hull));
-+      return computer->vertices.size();
-+}
-+
-+int plConvexHullNumFaces(plConvexHull hull)
-+{
-+      btConvexHullComputer *computer(reinterpret_cast< btConvexHullComputer* >(hull));
-+      return computer->faces.size();
-+}
-+
-+void plConvexHullGetVertex(plConvexHull hull, int n, float coords[3],
-+                                                 int *original_index)
-+{
-+      btConvexHullComputer *computer(reinterpret_cast< btConvexHullComputer* >(hull));
-+      const btVector3 &v(computer->vertices[n]);
-+      coords[0] = v[0];
-+      coords[1] = v[1];
-+      coords[2] = v[2];
-+      (*original_index) = computer->original_vertex_index[n];
-+}
-+
-+int plConvexHullGetFaceSize(plConvexHull hull, int n)
-+{
-+      btConvexHullComputer *computer(reinterpret_cast< btConvexHullComputer* >(hull));
-+      const btConvexHullComputer::Edge *e_orig, *e;
-+      int count;
-+
-+      for (e_orig = &computer->edges[computer->faces[n]], e = e_orig, count = 0;
-+               count == 0 || e != e_orig;
-+               e = e->getNextEdgeOfFace(), count++);
-+      return count;
-+}
-+
-+void plConvexHullGetFaceVertices(plConvexHull hull, int n, int *vertices)
-+{
-+      btConvexHullComputer *computer(reinterpret_cast< btConvexHullComputer* >(hull));
-+      const btConvexHullComputer::Edge *e_orig, *e;
-+      int count;
-+
-+      for (e_orig = &computer->edges[computer->faces[n]], e = e_orig, count = 0;
-+               count == 0 || e != e_orig;
-+               e = e->getNextEdgeOfFace(), count++)
-+      {
-+              vertices[count] = e->getTargetVertex();
-+      }
-+}
-Index: extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
-===================================================================
---- extern/bullet2/src/LinearMath/btConvexHullComputer.cpp     (revision 51556)
-+++ extern/bullet2/src/LinearMath/btConvexHullComputer.cpp     (working copy)
-@@ -2661,6 +2661,7 @@ btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, in
-       }
-       vertices.resize(0);
-+      original_vertex_index.resize(0);
-       edges.resize(0);
-       faces.resize(0);
-@@ -2671,6 +2672,7 @@ btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, in
-       {
-               btConvexHullInternal::Vertex* v = oldVertices[copied];
-               vertices.push_back(hull.getCoordinates(v));
-+              original_vertex_index.push_back(v->point.index);
-               btConvexHullInternal::Edge* firstEdge = v->edges;
-               if (firstEdge)
-               {
-Index: extern/bullet2/src/LinearMath/btConvexHullComputer.h
-===================================================================
---- extern/bullet2/src/LinearMath/btConvexHullComputer.h       (revision 51556)
-+++ extern/bullet2/src/LinearMath/btConvexHullComputer.h       (working copy)
-@@ -67,6 +67,7 @@ class btConvexHullComputer
-               // Vertices of the output hull
-               btAlignedObjectArray<btVector3> vertices;
-+              btAlignedObjectArray<int> original_vertex_index;
-               // Edges of the output hull
-               btAlignedObjectArray<Edge> edges;
index 3b286afa579afe92f6a2ede1ca9f33c31c00feac..ec99abf71cfd3de49a09161065dcf9573be8caac 100644 (file)
@@ -4,8 +4,8 @@ Questions? mail blender at erwincoumans.com, or check the bf-blender mailing lis
 Thanks,
 Erwin
 
-Apply patches/convex_hull.patch to add access to the convex hull
-operation, used in the BMesh convex hull operator.
+Apply patches/blender.patch to fix a few build errors and warnings and dd original
+vertex access for BMesh convex hull operator.
 
 Documentation is available at:
 http://code.google.com/p/bullet/source/browse/trunk/Bullet_User_Manual.pdf
index 95443af507017cabbc1f67ed34635cb92bdacfa0..2ca20cdd8b8b9837fdd2e71dca88c28097020e5e 100644 (file)
@@ -38,8 +38,9 @@ static DBVT_INLINE btDbvtVolume       merge(  const btDbvtVolume& a,
                                                                          const btDbvtVolume& b)
 {
 #if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
-       ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
-       btDbvtVolume&   res=*(btDbvtVolume*)locals;
+       ATTRIBUTE_ALIGNED16( char locals[sizeof(btDbvtAabbMm)]);
+       btDbvtVolume* ptr = (btDbvtVolume*) locals;
+       btDbvtVolume&   res=*ptr;
 #else
                btDbvtVolume    res;
 #endif
@@ -250,7 +251,8 @@ static btDbvtVolume                         bounds( const tNodeArray& leaves)
 {
 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
        ATTRIBUTE_ALIGNED16(char        locals[sizeof(btDbvtVolume)]);
-       btDbvtVolume&   volume=*(btDbvtVolume*)locals;
+       btDbvtVolume* ptr = (btDbvtVolume*) locals;
+       btDbvtVolume&   volume=*ptr;
        volume=leaves[0]->volume;
 #else
        btDbvtVolume volume=leaves[0]->volume;
index b64936844d52b01936814e09e1a0a9cf9f3c888a..db4e482f2926f9c29345dc55311086ff89bdf308 100644 (file)
@@ -1193,19 +1193,34 @@ inline void             btDbvt::collideOCL(     const btDbvtNode* root,
                                                        /* Insert 0     */ 
                                                        j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
                                                        stack.push_back(0);
+                                                       
+                                                       //void * memmove ( void * destination, const void * source, size_t num );
+                                                       
 #if DBVT_USE_MEMMOVE
-                                                       memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+                     {
+                     int num_items_to_move = stack.size()-1-j;
+                     if(num_items_to_move > 0)
+                        memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
+                     }
 #else
-                                                       for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+                     for(int k=stack.size()-1;k>j;--k) {
+                                                               stack[k]=stack[k-1];
+                     }
 #endif
                                                        stack[j]=allocate(ifree,stock,nes[q]);
                                                        /* Insert 1     */ 
                                                        j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
                                                        stack.push_back(0);
 #if DBVT_USE_MEMMOVE
-                                                       memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+                     {
+                     int num_items_to_move = stack.size()-1-j;
+                     if(num_items_to_move > 0)
+                        memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
+                     }
 #else
-                                                       for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+                     for(int k=stack.size()-1;k>j;--k) {
+                        stack[k]=stack[k-1];
+                     }
 #endif
                                                        stack[j]=allocate(ifree,stock,nes[1-q]);
                                                }
index ae22dadc73ac9ec445ce35569df7abdd01dc1f90..ad69fcbd712b74065b80d11ad279806842f4dba9 100644 (file)
@@ -34,7 +34,6 @@ int gFindPairs =0;
 
 btHashedOverlappingPairCache::btHashedOverlappingPairCache():
        m_overlapFilterCallback(0),
-       m_blockedForChanges(false),
        m_ghostPairCallback(0)
 {
        int initialAllocatedSize= 2;
index eee90e473a9488aded22873e56c15a00b1ec67da..146142704761a4d93a24bdb3ef4f17014fff574d 100644 (file)
@@ -94,7 +94,6 @@ class btHashedOverlappingPairCache : public btOverlappingPairCache
 {
        btBroadphasePairArray   m_overlappingPairArray;
        btOverlapFilterCallback* m_overlapFilterCallback;
-       bool            m_blockedForChanges;
 
 protected:
        
index 669d0b6b55e4c65316593c1bfaef01376937e1af..3b6913c0e1ecab8bcf07b6e4eefe1c81ff86a56a 100644 (file)
@@ -189,7 +189,7 @@ bool        btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const
 
        if ((!body0->isActive()) && (!body1->isActive()))
                needsCollision = false;
-       else if (!body0->checkCollideWith(body1))
+       else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
                needsCollision = false;
        
        return needsCollision ;
index d0924100058c3de611773e907ecb7d2b8cf88c83..395df3a550f19e3bd0676e198b3394a66883ce38 100644 (file)
@@ -4,8 +4,8 @@ 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, 
+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.
@@ -31,10 +31,11 @@ btCollisionObject::btCollisionObject()
                m_activationState1(1),
                m_deactivationTime(btScalar(0.)),
                m_friction(btScalar(0.5)),
-               m_rollingFriction(0.0f),
                m_restitution(btScalar(0.)),
+               m_rollingFriction(0.0f),
                m_internalType(CO_COLLISION_OBJECT),
                m_userObjectPointer(0),
+               m_userIndex(-1),
                m_hitFraction(btScalar(1.)),
                m_ccdSweptSphereRadius(btScalar(0.)),
                m_ccdMotionThreshold(btScalar(0.)),
index 89cad16821093c14d1c56aa9464502220deee09e..c68402418f72061f548b0fd3db67a34fa8d927e9 100644 (file)
@@ -92,11 +92,10 @@ protected:
        int                             m_internalType;
 
        ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
-       union
-       {
-               void*                   m_userObjectPointer;
-               int     m_userIndex;
-       };
+
+    void*                      m_userObjectPointer;
+    
+    int        m_userIndex;
 
        ///time of impact calculation
        btScalar                m_hitFraction; 
@@ -110,13 +109,11 @@ protected:
        /// If some object should have elaborate collision filtering by sub-classes
        int                     m_checkCollideWith;
 
+       btAlignedObjectArray<const btCollisionObject*> m_objectsWithoutCollisionCheck;
+
        ///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation.
        int                     m_updateRevision;
 
-       virtual bool    checkCollideWithOverride(const btCollisionObject* /* co */) const
-       {
-               return true;
-       }
 
 public:
 
@@ -225,7 +222,34 @@ public:
                return m_collisionShape;
        }
 
-       
+       void    setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
+       {
+               if (ignoreCollisionCheck)
+               {
+                       //We don't check for duplicates. Is it ok to leave that up to the user of this API?
+                       //int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
+                       //if (index == m_objectsWithoutCollisionCheck.size())
+                       //{
+                       m_objectsWithoutCollisionCheck.push_back(co);
+                       //}
+               }
+               else
+               {
+                       m_objectsWithoutCollisionCheck.remove(co);
+               }
+               m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
+       }
+
+       virtual bool    checkCollideWithOverride(const btCollisionObject*  co) const
+       {
+               int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
+               if (index < m_objectsWithoutCollisionCheck.size())
+               {
+                       return false;
+               }
+               return true;
+       }
+
 
        
 
index d739a2a08d7419181bdd56f6b51db1b221f722f0..c505ed5d5080d8e99e392381d0da34950cb170d8 100644 (file)
@@ -34,7 +34,7 @@ subject to the following restrictions:
 #include "LinearMath/btSerializer.h"
 #include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
 #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
-#include "BulletCollision/Gimpact/btGImpactShape.h"
+
 //#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
 
 
@@ -292,12 +292,13 @@ void      btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
                btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver);
                
                //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
-               bool condition = true;
+
                btConvexCast* convexCasterPtr = 0;
-               if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest)
-                       convexCasterPtr = &subSimplexConvexCaster;
-               else
+               //use kF_UseSubSimplexConvexCastRaytest by default
+               if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest)
                        convexCasterPtr = &gjkConvexCaster;
+               else
+                       convexCasterPtr = &subSimplexConvexCaster;
                
                btConvexCast& convexCaster = *convexCasterPtr;
 
@@ -308,6 +309,7 @@ void        btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
                        {
                                if (castResult.m_fraction < resultCallback.m_closestHitFraction)
                                {
+                                       //todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
 #ifdef USE_SUBSIMPLEX_CONVEX_CAST
                                        //rotate normal into worldspace
                                        castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
@@ -387,14 +389,7 @@ void       btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
                                triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
                        }
-                       else if(collisionShape->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
-                       {
-                               btGImpactMeshShape* concaveShape = (btGImpactMeshShape*)collisionShape;
-
-                               BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
-                               rcb.m_hitFraction = resultCallback.m_closestHitFraction;
-                               concaveShape->processAllTrianglesRay(&rcb,rayFromLocal,rayToLocal);
-                       }else
+                       else
                        {
                                //generic (slower) case
                                btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
@@ -1251,7 +1246,10 @@ public:
 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 (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
+       {
+               getDebugDrawer()->drawTransform(worldTransform,1);
+       }
 
        if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
        {
@@ -1429,81 +1427,91 @@ void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const
 
 void   btCollisionWorld::debugDrawWorld()
 {
-       if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
+       if (getDebugDrawer())
        {
-               int numManifolds = getDispatcher()->getNumManifolds();
-               btVector3 color(1,1,0);
-               for (int i=0;i<numManifolds;i++)
+               btIDebugDraw::DefaultColors defaultColors = getDebugDrawer()->getDefaultColors();
+
+               if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
                {
-                       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++)
+                       if (getDispatcher())
                        {
-                               btManifoldPoint& cp = contactManifold->getContactPoint(j);
-                               getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
+                               int numManifolds = getDispatcher()->getNumManifolds();
+                       
+                               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(),defaultColors.m_contactPoint);
+                                       }
+                               }
                        }
                }
-       }
 
-       if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
-       {
-               int i;
-
-               for (  i=0;i<m_collisionObjects.size();i++)
+               if ((getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
                {
-                       btCollisionObject* colObj = m_collisionObjects[i];
-                       if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
+                       int i;
+
+                       for (  i=0;i<m_collisionObjects.size();i++)
                        {
-                               if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
+                               btCollisionObject* colObj = m_collisionObjects[i];
+                               if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
                                {
-                                       btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
-                                       switch(colObj->getActivationState())
+                                       if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
                                        {
-                                       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:
+                                               btVector3 color(btScalar(0.4),btScalar(0.4),btScalar(0.4));
+
+                                               switch(colObj->getActivationState())
                                                {
-                                                       color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
-                                               }
-                                       };
+                                               case  ACTIVE_TAG:
+                                                       color = defaultColors.m_activeObject; break;
+                                               case ISLAND_SLEEPING:
+                                                       color =  defaultColors.m_deactivatedObject;break;
+                                               case WANTS_DEACTIVATION:
+                                                       color = defaultColors.m_wantsDeactivationObject;break;
+                                               case DISABLE_DEACTIVATION:
+                                                       color = defaultColors.m_disabledDeactivationObject;break;
+                                               case DISABLE_SIMULATION:
+                                                       color = defaultColors.m_disabledSimulationObject;break;
+                                               default:
+                                                       {
+                                                               color = btVector3(btScalar(.3),btScalar(0.3),btScalar(0.3));
+                                                       }
+                                               };
 
-                                       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;
+                                               debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
+                                       }
+                                       if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
+                                       {
+                                               btVector3 minAabb,maxAabb;
+                                               btVector3 colorvec = defaultColors.m_aabb;
+                                               colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
+                                               btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
+                                               minAabb -= contactThreshold;
+                                               maxAabb += contactThreshold;
 
-                                       btVector3 minAabb2,maxAabb2;
+                                               btVector3 minAabb2,maxAabb2;
 
-                                       if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
-                                       {
-                                               colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
-                                               minAabb2 -= contactThreshold;
-                                               maxAabb2 += contactThreshold;
-                                               minAabb.setMin(minAabb2);
-                                               maxAabb.setMax(maxAabb2);
-                                       }
+                                               if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
+                                               {
+                                                       colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
+                                                       minAabb2 -= contactThreshold;
+                                                       maxAabb2 += contactThreshold;
+                                                       minAabb.setMin(minAabb2);
+                                                       maxAabb.setMax(maxAabb2);
+                                               }
 
-                                       m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
+                                               m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
+                                       }
                                }
                        }
-
                }
        }
 }
@@ -1512,15 +1520,6 @@ void     btCollisionWorld::debugDrawWorld()
 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;
@@ -1537,6 +1536,15 @@ void     btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
                }
        }
 
+       //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->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK))
+               {
+                       colObj->serializeSingleObject(serializer);
+               }
+       }
 }
 
 
index 0ac5563d06e571ec385a2ab5f8ff0e06c16a97c2..ec40c969f51c0ac22e627310e5a2a6cfbf86d957 100644 (file)
@@ -27,7 +27,7 @@ subject to the following restrictions:
  * @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 github repository: https://github.com/bulletphysics/bullet3/releases 
  *
  * @subsection step2 Step 2: Building
  * Bullet has multiple build systems, including premake, cmake and autotools. Premake and cmake support all platforms.
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp
new file mode 100644 (file)
index 0000000..57eb817
--- /dev/null
@@ -0,0 +1,1143 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2014 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.
+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 "btCollisionWorldImporter.h"
+#include "btBulletCollisionCommon.h"
+#include "LinearMath/btSerializer.h" //for btBulletSerializedArrays definition
+
+#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
+#include "BulletCollision/Gimpact/btGImpactShape.h"
+#endif //SUPPORT_GIMPACT_SHAPE_IMPORT
+
+btCollisionWorldImporter::btCollisionWorldImporter(btCollisionWorld* world)
+:m_collisionWorld(world),
+m_verboseMode(0)
+{
+
+}
+
+btCollisionWorldImporter::~btCollisionWorldImporter()
+{
+}
+
+
+
+
+
+bool   btCollisionWorldImporter::convertAllObjects( btBulletSerializedArrays* arrays)
+{
+
+       m_shapeMap.clear();
+       m_bodyMap.clear();
+
+       int i;
+
+       for (i=0;i<arrays->m_bvhsDouble.size();i++)
+       {
+               btOptimizedBvh* bvh = createOptimizedBvh();
+               btQuantizedBvhDoubleData* bvhData = arrays->m_bvhsDouble[i];
+               bvh->deSerializeDouble(*bvhData);
+               m_bvhMap.insert(arrays->m_bvhsDouble[i],bvh);
+       }
+       for (i=0;i<arrays->m_bvhsFloat.size();i++)
+    {
+        btOptimizedBvh* bvh = createOptimizedBvh();
+               btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i];
+               bvh->deSerializeFloat(*bvhData);
+               m_bvhMap.insert(arrays->m_bvhsFloat[i],bvh);
+       }
+
+
+
+
+
+       for (i=0;i<arrays->m_colShapeData.size();i++)
+       {
+               btCollisionShapeData* shapeData = arrays->m_colShapeData[i];
+               btCollisionShape* shape = convertCollisionShape(shapeData);
+               if (shape)
+               {
+       //              printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
+                       m_shapeMap.insert(shapeData,shape);
+               }
+
+               if (shape&& shapeData->m_name)
+               {
+                       char* newname = duplicateName(shapeData->m_name);
+                       m_objectNameMap.insert(shape,newname);
+                       m_nameShapeMap.insert(newname,shape);
+               }
+       }
+
+
+       for (i=0;i<arrays->m_collisionObjectDataDouble.size();i++)
+       {
+        btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i];
+        btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
+        if (shapePtr && *shapePtr)
+        {
+            btTransform startTransform;
+            colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
+            startTransform.deSerializeDouble(colObjData->m_worldTransform);
+
+            btCollisionShape* shape = (btCollisionShape*)*shapePtr;
+            btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
+            body->setFriction(btScalar(colObjData->m_friction));
+            body->setRestitution(btScalar(colObjData->m_restitution));
+
+#ifdef USE_INTERNAL_EDGE_UTILITY
+            if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+            {
+                btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
+                if (trimesh->getTriangleInfoMap())
+                {
+                    body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+                }
+            }
+#endif //USE_INTERNAL_EDGE_UTILITY
+            m_bodyMap.insert(colObjData,body);
+        } else
+        {
+            printf("error: no shape found\n");
+        }
+       }
+       for (i=0;i<arrays->m_collisionObjectDataFloat.size();i++)
+       {
+        btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i];
+        btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
+        if (shapePtr && *shapePtr)
+        {
+            btTransform startTransform;
+            colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
+            startTransform.deSerializeFloat(colObjData->m_worldTransform);
+
+            btCollisionShape* shape = (btCollisionShape*)*shapePtr;
+            btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
+
+#ifdef USE_INTERNAL_EDGE_UTILITY
+            if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+            {
+                btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
+                if (trimesh->getTriangleInfoMap())
+                {
+                    body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+                }
+            }
+#endif //USE_INTERNAL_EDGE_UTILITY
+            m_bodyMap.insert(colObjData,body);
+        } else
+        {
+            printf("error: no shape found\n");
+        }
+    }
+
+       return true;
+}
+
+
+
+void btCollisionWorldImporter::deleteAllData()
+{
+       int i;
+
+       for (i=0;i<m_allocatedCollisionObjects.size();i++)
+       {
+               if(m_collisionWorld)
+                       m_collisionWorld->removeCollisionObject(m_allocatedCollisionObjects[i]);
+               delete m_allocatedCollisionObjects[i];
+       }
+
+       m_allocatedCollisionObjects.clear();
+
+
+       for (i=0;i<m_allocatedCollisionShapes.size();i++)
+       {
+               delete m_allocatedCollisionShapes[i];
+       }
+       m_allocatedCollisionShapes.clear();
+
+
+       for (i=0;i<m_allocatedBvhs.size();i++)
+       {
+               delete m_allocatedBvhs[i];
+       }
+       m_allocatedBvhs.clear();
+
+       for (i=0;i<m_allocatedTriangleInfoMaps.size();i++)
+       {
+               delete m_allocatedTriangleInfoMaps[i];
+       }
+       m_allocatedTriangleInfoMaps.clear();
+       for (i=0;i<m_allocatedTriangleIndexArrays.size();i++)
+       {
+               delete m_allocatedTriangleIndexArrays[i];
+       }
+       m_allocatedTriangleIndexArrays.clear();
+       for (i=0;i<m_allocatedNames.size();i++)
+       {
+               delete[] m_allocatedNames[i];
+       }
+       m_allocatedNames.clear();
+
+       for (i=0;i<m_allocatedbtStridingMeshInterfaceDatas.size();i++)
+       {
+               btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i];
+
+               for(int a = 0;a < curData->m_numMeshParts;a++)
+               {
+                       btMeshPartData* curPart = &curData->m_meshPartsPtr[a];
+                       if(curPart->m_vertices3f)
+                               delete [] curPart->m_vertices3f;
+
+                       if(curPart->m_vertices3d)
+                               delete [] curPart->m_vertices3d;
+
+                       if(curPart->m_indices32)
+                               delete [] curPart->m_indices32;
+
+                       if(curPart->m_3indices16)
+                               delete [] curPart->m_3indices16;
+
+                       if(curPart->m_indices16)
+                               delete [] curPart->m_indices16;
+
+                       if (curPart->m_3indices8)
+                               delete [] curPart->m_3indices8;
+
+               }
+               delete [] curData->m_meshPartsPtr;
+               delete curData;
+       }
+       m_allocatedbtStridingMeshInterfaceDatas.clear();
+
+       for (i=0;i<m_indexArrays.size();i++)
+       {
+               btAlignedFree(m_indexArrays[i]);
+       }
+  m_indexArrays.clear();
+
+       for (i=0;i<m_shortIndexArrays.size();i++)
+       {
+               btAlignedFree(m_shortIndexArrays[i]);
+       }
+  m_shortIndexArrays.clear();
+
+       for (i=0;i<m_charIndexArrays.size();i++)
+       {
+               btAlignedFree(m_charIndexArrays[i]);
+       }
+  m_charIndexArrays.clear();
+
+       for (i=0;i<m_floatVertexArrays.size();i++)
+       {
+               btAlignedFree(m_floatVertexArrays[i]);
+       }
+  m_floatVertexArrays.clear();
+
+       for (i=0;i<m_doubleVertexArrays.size();i++)
+       {
+               btAlignedFree(m_doubleVertexArrays[i]);
+       }
+   m_doubleVertexArrays.clear();
+
+
+}
+
+
+
+btCollisionShape* btCollisionWorldImporter::convertCollisionShape(  btCollisionShapeData* shapeData  )
+{
+       btCollisionShape* shape = 0;
+
+       switch (shapeData->m_shapeType)
+               {
+       case STATIC_PLANE_PROXYTYPE:
+               {
+                       btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
+                       btVector3 planeNormal,localScaling;
+                       planeNormal.deSerializeFloat(planeData->m_planeNormal);
+                       localScaling.deSerializeFloat(planeData->m_localScaling);
+                       shape = createPlaneShape(planeNormal,planeData->m_planeConstant);
+                       shape->setLocalScaling(localScaling);
+
+                       break;
+               }
+       case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:
+               {
+                       btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData;
+                       btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData;
+                       colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
+                       btCollisionShape* childShape = convertCollisionShape(colShapeData);
+                       btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape;
+                       btVector3 localScaling;
+                       localScaling.deSerializeFloat(scaledMesh->m_localScaling);
+
+                       shape = createScaledTrangleMeshShape(meshShape, localScaling);
+                       break;
+               }
+#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
+       case GIMPACT_SHAPE_PROXYTYPE:
+               {
+                       btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData;
+                       if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
+                       {
+                               btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);
+                               btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
+
+
+                               btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
+                               btVector3 localScaling;
+                               localScaling.deSerializeFloat(gimpactData->m_localScaling);
+                               gimpactShape->setLocalScaling(localScaling);
+                               gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin));
+                               gimpactShape->updateBound();
+                               shape = gimpactShape;
+                       } else
+                       {
+                               printf("unsupported gimpact sub type\n");
+                       }
+                       break;
+               }
+#endif //SUPPORT_GIMPACT_SHAPE_IMPORT
+       //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API
+       //so deal with this
+               case CAPSULE_SHAPE_PROXYTYPE:
+               {
+                       btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData;
+
+
+                       switch (capData->m_upAxis)
+                       {
+                       case 0:
+                               {
+                                       shape = createCapsuleShapeX(1,1);
+                                       break;
+                               }
+                       case 1:
+                               {
+                                       shape = createCapsuleShapeY(1,1);
+                                       break;
+                               }
+                       case 2:
+                               {
+                                       shape = createCapsuleShapeZ(1,1);
+                                       break;
+                               }
+                       default:
+                               {
+                                       printf("error: wrong up axis for btCapsuleShape\n");
+                               }
+
+
+                       };
+                       if (shape)
+                       {
+                               btCapsuleShape* cap = (btCapsuleShape*) shape;
+                               cap->deSerializeFloat(capData);
+                       }
+                       break;
+               }
+               case CYLINDER_SHAPE_PROXYTYPE:
+               case CONE_SHAPE_PROXYTYPE:
+               case BOX_SHAPE_PROXYTYPE:
+               case SPHERE_SHAPE_PROXYTYPE:
+               case MULTI_SPHERE_SHAPE_PROXYTYPE:
+               case CONVEX_HULL_SHAPE_PROXYTYPE:
+                       {
+                               btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData;
+                               btVector3 implicitShapeDimensions;
+                               implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions);
+                               btVector3 localScaling;
+                               localScaling.deSerializeFloat(bsd->m_localScaling);
+                               btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin);
+                               switch (shapeData->m_shapeType)
+                               {
+                                       case BOX_SHAPE_PROXYTYPE:
+                                               {
+                                                       btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin);
+                                                       //box->initializePolyhedralFeatures();
+                                                       shape = box;
+
+                                                       break;
+                                               }
+                                       case SPHERE_SHAPE_PROXYTYPE:
+                                               {
+                                                       shape = createSphereShape(implicitShapeDimensions.getX());
+                                                       break;
+                                               }
+
+                                       case CYLINDER_SHAPE_PROXYTYPE:
+                                               {
+                                                       btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData;
+                                                       btVector3 halfExtents = implicitShapeDimensions+margin;
+                                                       switch (cylData->m_upAxis)
+                                                       {
+                                                       case 0:
+                                                               {
+                                                                       shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX());
+                                                                       break;
+                                                               }
+                                                       case 1:
+                                                               {
+                                                                       shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY());
+                                                                       break;
+                                                               }
+                                                       case 2:
+                                                               {
+                                                                       shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ());
+                                                                       break;
+                                                               }
+                                                       default:
+                                                               {
+                                                                       printf("unknown Cylinder up axis\n");
+                                                               }
+
+                                                       };
+
+
+
+                                                       break;
+                                               }
+                                       case CONE_SHAPE_PROXYTYPE:
+                                               {
+                                                       btConeShapeData* conData = (btConeShapeData*) shapeData;
+                                                       btVector3 halfExtents = implicitShapeDimensions;//+margin;
+                                                       switch (conData->m_upIndex)
+                                                       {
+                                                       case 0:
+                                                               {
+                                                                       shape = createConeShapeX(halfExtents.getY(),halfExtents.getX());
+                                                                       break;
+                                                               }
+                                                       case 1:
+                                                               {
+                                                                       shape = createConeShapeY(halfExtents.getX(),halfExtents.getY());
+                                                                       break;
+                                                               }
+                                                       case 2:
+                                                               {
+                                                                       shape = createConeShapeZ(halfExtents.getX(),halfExtents.getZ());
+                                                                       break;
+                                                               }
+                                                       default:
+                                                               {
+                                                                       printf("unknown Cone up axis\n");
+                                                               }
+
+                                                       };
+
+
+
+                                                       break;
+                                               }
+                                       case MULTI_SPHERE_SHAPE_PROXYTYPE:
+                                               {
+                                                       btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd;
+                                                       int numSpheres = mss->m_localPositionArraySize;
+
+                                                       btAlignedObjectArray<btVector3> tmpPos;
+                                                       btAlignedObjectArray<btScalar> radii;
+                                                       radii.resize(numSpheres);
+                                                       tmpPos.resize(numSpheres);
+                                                       int i;
+                                                       for ( i=0;i<numSpheres;i++)
+                                                       {
+                                                               tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);
+                                                               radii[i] = mss->m_localPositionArrayPtr[i].m_radius;
+                                                       }
+                                                       shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres);
+                                                       break;
+                                               }
+                                       case CONVEX_HULL_SHAPE_PROXYTYPE:
+                                               {
+                                               //      int sz = sizeof(btConvexHullShapeData);
+                                               //      int sz2 = sizeof(btConvexInternalShapeData);
+                                               //      int sz3 = sizeof(btCollisionShapeData);
+                                                       btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd;
+                                                       int numPoints = convexData->m_numUnscaledPoints;
+
+                                                       btAlignedObjectArray<btVector3> tmpPoints;
+                                                       tmpPoints.resize(numPoints);
+                                                       int i;
+                                                       for ( i=0;i<numPoints;i++)
+                                                       {
+#ifdef BT_USE_DOUBLE_PRECISION
+                                                       if (convexData->m_unscaledPointsDoublePtr)
+                                                               tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]);
+                                                       if (convexData->m_unscaledPointsFloatPtr)
+                                                               tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]);
+#else
+                                                       if (convexData->m_unscaledPointsFloatPtr)
+                                                               tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]);
+                                                       if (convexData->m_unscaledPointsDoublePtr)
+                                                               tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]);
+#endif //BT_USE_DOUBLE_PRECISION
+                                                       }
+                                                       btConvexHullShape* hullShape = createConvexHullShape();
+                                                       for (i=0;i<numPoints;i++)
+                                                       {
+                                                               hullShape->addPoint(tmpPoints[i]);
+                                                       }
+                                                       hullShape->setMargin(bsd->m_collisionMargin);
+                                                       //hullShape->initializePolyhedralFeatures();
+                                                       shape = hullShape;
+                                                       break;
+                                               }
+                                       default:
+                                               {
+                                                       printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType);
+                                               }
+                               }
+
+                               if (shape)
+                               {
+                                       shape->setMargin(bsd->m_collisionMargin);
+
+                                       btVector3 localScaling;
+                                       localScaling.deSerializeFloat(bsd->m_localScaling);
+                                       shape->setLocalScaling(localScaling);
+
+                               }
+                               break;
+                       }
+               case TRIANGLE_MESH_SHAPE_PROXYTYPE:
+               {
+                       btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData;
+                       btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface);
+                       btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
+                       if (!meshInterface->getNumSubParts())
+                       {
+                               return 0;
+                       }
+
+                       btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);
+                       meshInterface->setScaling(scaling);
+
+
+                       btOptimizedBvh* bvh = 0;
+#if 1
+                       if (trimesh->m_quantizedFloatBvh)
+                       {
+                               btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);
+                               if (bvhPtr && *bvhPtr)
+                               {
+                                       bvh = *bvhPtr;
+                               } else
+                               {
+                                       bvh = createOptimizedBvh();
+                                       bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
+                               }
+                       }
+                       if (trimesh->m_quantizedDoubleBvh)
+                       {
+                               btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);
+                               if (bvhPtr && *bvhPtr)
+                               {
+                                       bvh = *bvhPtr;
+                               } else
+                               {
+                                       bvh = createOptimizedBvh();
+                                       bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
+                               }
+                       }
+#endif
+
+
+                       btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh);
+                       trimeshShape->setMargin(trimesh->m_collisionMargin);
+                       shape = trimeshShape;
+
+                       if (trimesh->m_triangleInfoMap)
+                       {
+                               btTriangleInfoMap* map = createTriangleInfoMap();
+                               map->deSerialize(*trimesh->m_triangleInfoMap);
+                               trimeshShape->setTriangleInfoMap(map);
+
+#ifdef USE_INTERNAL_EDGE_UTILITY
+                               gContactAddedCallback = btAdjustInternalEdgeContactsCallback;
+#endif //USE_INTERNAL_EDGE_UTILITY
+
+                       }
+
+                       //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);
+                       break;
+               }
+               case COMPOUND_SHAPE_PROXYTYPE:
+                       {
+                               btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;
+                               btCompoundShape* compoundShape = createCompoundShape();
+
+
+                               btAlignedObjectArray<btCollisionShape*> childShapes;
+                               for (int i=0;i<compoundData->m_numChildShapes;i++)
+                               {
+                                       btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;
+
+                                       btCollisionShape* childShape = convertCollisionShape(cd);
+                                       if (childShape)
+                                       {
+                                               btTransform localTransform;
+                                               localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);
+                                               compoundShape->addChildShape(localTransform,childShape);
+                                       } else
+                                       {
+#ifdef _DEBUG
+                                               printf("error: couldn't create childShape for compoundShape\n");
+#endif
+                                       }
+
+                               }
+                               shape = compoundShape;
+
+                               break;
+                       }
+               case SOFTBODY_SHAPE_PROXYTYPE:
+                       {
+                               return 0;
+                       }
+               default:
+                       {
+#ifdef _DEBUG
+                               printf("unsupported shape type (%d)\n",shapeData->m_shapeType);
+#endif
+                       }
+               }
+
+               return shape;
+
+}
+
+
+
+char* btCollisionWorldImporter::duplicateName(const char* name)
+{
+       if (name)
+       {
+               int l = (int)strlen(name);
+               char* newName = new char[l+1];
+               memcpy(newName,name,l);
+               newName[l] = 0;
+               m_allocatedNames.push_back(newName);
+               return newName;
+       }
+       return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData&  meshData)
+{
+       btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer();
+
+       for (int i=0;i<meshData.m_numMeshParts;i++)
+       {
+               btIndexedMesh meshPart;
+               meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles;
+               meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices;
+
+
+               if (meshData.m_meshPartsPtr[i].m_indices32)
+               {
+                       meshPart.m_indexType = PHY_INTEGER;
+                       meshPart.m_triangleIndexStride = 3*sizeof(int);
+                       int* indexArray = (int*)btAlignedAlloc(sizeof(int)*3*meshPart.m_numTriangles,16);
+                       m_indexArrays.push_back(indexArray);
+                       for (int j=0;j<3*meshPart.m_numTriangles;j++)
+                       {
+                               indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value;
+                       }
+                       meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
+               } else
+               {
+                       if (meshData.m_meshPartsPtr[i].m_3indices16)
+                       {
+                               meshPart.m_indexType = PHY_SHORT;
+                               meshPart.m_triangleIndexStride = sizeof(short int)*3;//sizeof(btShortIntIndexTripletData);
+
+                               short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);
+                               m_shortIndexArrays.push_back(indexArray);
+
+                               for (int j=0;j<meshPart.m_numTriangles;j++)
+                               {
+                                       indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0];
+                                       indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1];
+                                       indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2];
+                               }
+
+                               meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
+                       }
+                       if (meshData.m_meshPartsPtr[i].m_indices16)
+                       {
+                               meshPart.m_indexType = PHY_SHORT;
+                               meshPart.m_triangleIndexStride = 3*sizeof(short int);
+                               short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);
+                               m_shortIndexArrays.push_back(indexArray);
+                               for (int j=0;j<3*meshPart.m_numTriangles;j++)
+                               {
+                                       indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value;
+                               }
+
+                               meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
+                       }
+
+                       if (meshData.m_meshPartsPtr[i].m_3indices8)
+                       {
+                               meshPart.m_indexType = PHY_UCHAR;
+                               meshPart.m_triangleIndexStride = sizeof(unsigned char)*3;
+
+                               unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char)*3*meshPart.m_numTriangles,16);
+                               m_charIndexArrays.push_back(indexArray);
+
+                               for (int j=0;j<meshPart.m_numTriangles;j++)
+                               {
+                                       indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0];
+                                       indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1];
+                                       indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2];
+                               }
+
+                               meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
+                       }
+               }
+
+               if (meshData.m_meshPartsPtr[i].m_vertices3f)
+               {
+                       meshPart.m_vertexType = PHY_FLOAT;
+                       meshPart.m_vertexStride = sizeof(btVector3FloatData);
+                       btVector3FloatData* vertices = (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*meshPart.m_numVertices,16);
+                       m_floatVertexArrays.push_back(vertices);
+
+                       for (int j=0;j<meshPart.m_numVertices;j++)
+                       {
+                               vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0];
+                               vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1];
+                               vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2];
+                               vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3];
+                       }
+                       meshPart.m_vertexBase = (const unsigned char*)vertices;
+               } else
+               {
+                       meshPart.m_vertexType = PHY_DOUBLE;
+                       meshPart.m_vertexStride = sizeof(btVector3DoubleData);
+
+
+                       btVector3DoubleData* vertices = (btVector3DoubleData*) btAlignedAlloc(sizeof(btVector3DoubleData)*meshPart.m_numVertices,16);
+                       m_doubleVertexArrays.push_back(vertices);
+
+                       for (int j=0;j<meshPart.m_numVertices;j++)
+                       {
+                               vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0];
+                               vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1];
+                               vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2];
+                               vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3];
+                       }
+                       meshPart.m_vertexBase = (const unsigned char*)vertices;
+               }
+
+               if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase)
+               {
+                       meshInterface->addIndexedMesh(meshPart,meshPart.m_indexType);
+               }
+       }
+
+       return meshInterface;
+}
+
+
+btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)
+{
+       //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter
+       btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;
+
+       newData->m_scaling = interfaceData->m_scaling;
+       newData->m_numMeshParts = interfaceData->m_numMeshParts;
+       newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];
+
+       for(int i = 0;i < newData->m_numMeshParts;i++)
+       {
+               btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i];
+               btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];
+
+               curNewPart->m_numTriangles = curPart->m_numTriangles;
+               curNewPart->m_numVertices = curPart->m_numVertices;
+
+               if(curPart->m_vertices3f)
+               {
+                       curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];
+                       memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices);
+               }
+               else
+                       curNewPart->m_vertices3f = NULL;
+
+               if(curPart->m_vertices3d)
+               {
+                       curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];
+                       memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices);
+               }
+               else
+                       curNewPart->m_vertices3d = NULL;
+
+               int numIndices = curNewPart->m_numTriangles * 3;
+               ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time
+               ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized
+               bool uninitialized3indices8Workaround =false;
+
+               if(curPart->m_indices32)
+               {
+                       uninitialized3indices8Workaround=true;
+                       curNewPart->m_indices32 = new btIntIndexData[numIndices];
+                       memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices);
+               }
+               else
+                       curNewPart->m_indices32 = NULL;
+
+               if(curPart->m_3indices16)
+               {
+                       uninitialized3indices8Workaround=true;
+                       curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles];
+                       memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles);
+               }
+               else
+                       curNewPart->m_3indices16 = NULL;
+
+               if(curPart->m_indices16)
+               {
+                       uninitialized3indices8Workaround=true;
+                       curNewPart->m_indices16 = new btShortIntIndexData[numIndices];
+                       memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices);
+               }
+               else
+                       curNewPart->m_indices16 = NULL;
+
+               if(!uninitialized3indices8Workaround && curPart->m_3indices8)
+               {
+                       curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles];
+                       memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles);
+               }
+               else
+                       curNewPart->m_3indices8 = NULL;
+
+       }
+
+       m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);
+
+       return(newData);
+}
+
+#ifdef USE_INTERNAL_EDGE_UTILITY
+extern ContactAddedCallback            gContactAddedCallback;
+
+static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp,  const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
+{
+
+       btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);
+               //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
+               //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
+       return true;
+}
+#endif //USE_INTERNAL_EDGE_UTILITY
+
+
+/*
+btRigidBody*  btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName)
+{
+       btVector3 localInertia;
+       localInertia.setZero();
+
+       if (mass)
+               shape->calculateLocalInertia(mass,localInertia);
+
+       btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
+       body->setWorldTransform(startTransform);
+
+       if (m_dynamicsWorld)
+               m_dynamicsWorld->addRigidBody(body);
+
+       if (bodyName)
+       {
+               char* newname = duplicateName(bodyName);
+               m_objectNameMap.insert(body,newname);
+               m_nameBodyMap.insert(newname,body);
+       }
+       m_allocatedRigidBodies.push_back(body);
+       return body;
+
+}
+*/
+
+btCollisionObject* btCollisionWorldImporter::getCollisionObjectByName(const char* name)
+{
+       btCollisionObject** bodyPtr = m_nameColObjMap.find(name);
+       if (bodyPtr && *bodyPtr)
+       {
+               return *bodyPtr;
+       }
+       return 0;
+}
+
+btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName)
+{
+       btCollisionObject* colObj = new btCollisionObject();
+       colObj->setWorldTransform(startTransform);
+       colObj->setCollisionShape(shape);
+       m_collisionWorld->addCollisionObject(colObj);//todo: flags etc
+
+       if (bodyName)
+       {
+               char* newname = duplicateName(bodyName);
+               m_objectNameMap.insert(colObj,newname);
+               m_nameColObjMap.insert(newname,colObj);
+       }
+       m_allocatedCollisionObjects.push_back(colObj);
+
+       return colObj;
+}
+
+
+
+btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
+{
+       btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+btCollisionShape* btCollisionWorldImporter::createBoxShape(const btVector3& halfExtents)
+{
+       btBoxShape* shape = new btBoxShape(halfExtents);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+btCollisionShape* btCollisionWorldImporter::createSphereShape(btScalar radius)
+{
+       btSphereShape* shape = new btSphereShape(radius);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+
+btCollisionShape* btCollisionWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)
+{
+       btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)
+{
+       btCapsuleShape* shape = new btCapsuleShape(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)
+{
+       btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius,btScalar height)
+{
+       btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius));
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius,btScalar height)
+{
+       btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius));
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height)
+{
+       btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height));
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius,btScalar height)
+{
+       btConeShapeX* shape = new btConeShapeX(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius,btScalar height)
+{
+       btConeShape* shape = new btConeShape(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius,btScalar height)
+{
+       btConeShapeZ* shape = new btConeShapeZ(radius,height);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btTriangleIndexVertexArray*    btCollisionWorldImporter::createTriangleMeshContainer()
+{
+       btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();
+       m_allocatedTriangleIndexArrays.push_back(in);
+       return in;
+}
+
+btOptimizedBvh*        btCollisionWorldImporter::createOptimizedBvh()
+{
+       btOptimizedBvh* bvh = new btOptimizedBvh();
+       m_allocatedBvhs.push_back(bvh);
+       return bvh;
+}
+
+
+btTriangleInfoMap* btCollisionWorldImporter::createTriangleInfoMap()
+{
+       btTriangleInfoMap* tim = new btTriangleInfoMap();
+       m_allocatedTriangleInfoMaps.push_back(tim);
+       return tim;
+}
+
+btBvhTriangleMeshShape* btCollisionWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)
+{
+       if (bvh)
+       {
+               btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false);
+               bvhTriMesh->setOptimizedBvh(bvh);
+               m_allocatedCollisionShapes.push_back(bvhTriMesh);
+               return bvhTriMesh;
+       }
+
+       btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true);
+       m_allocatedCollisionShapes.push_back(ts);
+       return ts;
+
+}
+btCollisionShape* btCollisionWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)
+{
+       return 0;
+}
+#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
+btGImpactMeshShape* btCollisionWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)
+{
+       btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+
+}
+#endif //SUPPORT_GIMPACT_SHAPE_IMPORT
+
+btConvexHullShape* btCollisionWorldImporter::createConvexHullShape()
+{
+       btConvexHullShape* shape = new btConvexHullShape();
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btCompoundShape* btCollisionWorldImporter::createCompoundShape()
+{
+       btCompoundShape* shape = new btCompoundShape();
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+
+btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling)
+{
+       btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres)
+{
+       btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres);
+       m_allocatedCollisionShapes.push_back(shape);
+       return shape;
+}
+
+
+
+       // query for data
+int    btCollisionWorldImporter::getNumCollisionShapes() const
+{
+       return m_allocatedCollisionShapes.size();
+}
+
+btCollisionShape* btCollisionWorldImporter::getCollisionShapeByIndex(int index)
+{
+       return m_allocatedCollisionShapes[index];
+}
+
+btCollisionShape* btCollisionWorldImporter::getCollisionShapeByName(const char* name)
+{
+       btCollisionShape** shapePtr = m_nameShapeMap.find(name);
+       if (shapePtr&& *shapePtr)
+       {
+               return *shapePtr;
+       }
+       return 0;
+}
+
+
+const char*    btCollisionWorldImporter::getNameForPointer(const void* ptr) const
+{
+       const char*const * namePtr = m_objectNameMap.find(ptr);
+       if (namePtr && *namePtr)
+               return *namePtr;
+       return 0;
+}
+
+
+int btCollisionWorldImporter::getNumRigidBodies() const
+{
+       return m_allocatedRigidBodies.size();
+}
+
+btCollisionObject* btCollisionWorldImporter::getRigidBodyByIndex(int index) const
+{
+       return m_allocatedRigidBodies[index];
+}
+
+
+int btCollisionWorldImporter::getNumBvhs() const
+{
+       return m_allocatedBvhs.size();
+}
+ btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const
+{
+       return m_allocatedBvhs[index];
+}
+
+int btCollisionWorldImporter::getNumTriangleInfoMaps() const
+{
+       return m_allocatedTriangleInfoMaps.size();
+}
+
+btTriangleInfoMap* btCollisionWorldImporter::getTriangleInfoMapByIndex(int index) const
+{
+       return m_allocatedTriangleInfoMaps[index];
+}
+
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h
new file mode 100644 (file)
index 0000000..9a6d16f
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2014 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.
+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 BT_COLLISION_WORLD_IMPORTER_H
+#define BT_COLLISION_WORLD_IMPORTER_H
+
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btHashMap.h"
+
+class btCollisionShape;
+class btCollisionObject;
+struct btBulletSerializedArrays;
+
+
+struct ConstraintInput;
+class btCollisionWorld;
+struct btCollisionShapeData;
+class btTriangleIndexVertexArray;
+class btStridingMeshInterface;
+struct btStridingMeshInterfaceData;
+class btGImpactMeshShape;
+class btOptimizedBvh;
+struct btTriangleInfoMap;
+class btBvhTriangleMeshShape;
+class btPoint2PointConstraint;
+class btHingeConstraint;
+class btConeTwistConstraint;
+class btGeneric6DofConstraint;
+class btGeneric6DofSpringConstraint;
+class btSliderConstraint;
+class btGearConstraint;
+struct btContactSolverInfo;
+
+
+
+
+class btCollisionWorldImporter
+{
+protected:
+       btCollisionWorld* m_collisionWorld;
+
+       int m_verboseMode;
+
+       btAlignedObjectArray<btCollisionShape*>  m_allocatedCollisionShapes;
+       btAlignedObjectArray<btCollisionObject*> m_allocatedRigidBodies;
+
+       btAlignedObjectArray<btOptimizedBvh*>    m_allocatedBvhs;
+       btAlignedObjectArray<btTriangleInfoMap*> m_allocatedTriangleInfoMaps;
+       btAlignedObjectArray<btTriangleIndexVertexArray*> m_allocatedTriangleIndexArrays;
+       btAlignedObjectArray<btStridingMeshInterfaceData*> m_allocatedbtStridingMeshInterfaceDatas;
+       btAlignedObjectArray<btCollisionObject*> m_allocatedCollisionObjects;
+
+
+       btAlignedObjectArray<char*>                             m_allocatedNames;
+
+       btAlignedObjectArray<int*>                              m_indexArrays;
+       btAlignedObjectArray<short int*>                m_shortIndexArrays;
+       btAlignedObjectArray<unsigned char*>    m_charIndexArrays;
+
+       btAlignedObjectArray<btVector3FloatData*>       m_floatVertexArrays;
+       btAlignedObjectArray<btVector3DoubleData*>      m_doubleVertexArrays;
+
+
+       btHashMap<btHashPtr,btOptimizedBvh*>    m_bvhMap;
+       btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
+
+       btHashMap<btHashString,btCollisionShape*>       m_nameShapeMap;
+       btHashMap<btHashString,btCollisionObject*>      m_nameColObjMap;
+
+       btHashMap<btHashPtr,const char*>        m_objectNameMap;
+
+       btHashMap<btHashPtr,btCollisionShape*>  m_shapeMap;
+       btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
+
+
+       //methods
+
+
+
+       char*   duplicateName(const char* name);
+
+       btCollisionShape* convertCollisionShape(  btCollisionShapeData* shapeData  );
+
+
+public:
+
+       btCollisionWorldImporter(btCollisionWorld* world);
+
+       virtual ~btCollisionWorldImporter();
+
+    bool       convertAllObjects( btBulletSerializedArrays* arrays);
+
+               ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load.
+       ///make sure you don't use the dynamics world containing objects after you call this method
+       virtual void deleteAllData();
+
+       void    setVerboseMode(int verboseMode)
+       {
+               m_verboseMode = verboseMode;
+       }
+
+       int getVerboseMode() const
+       {
+               return m_verboseMode;
+       }
+
+               // query for data
+       int     getNumCollisionShapes() const;
+       btCollisionShape* getCollisionShapeByIndex(int index);
+       int getNumRigidBodies() const;
+       btCollisionObject* getRigidBodyByIndex(int index) const;
+       int getNumConstraints() const;
+
+       int getNumBvhs() const;
+       btOptimizedBvh*  getBvhByIndex(int index) const;
+       int getNumTriangleInfoMaps() const;
+       btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const;
+
+       // queris involving named objects
+       btCollisionShape* getCollisionShapeByName(const char* name);
+       btCollisionObject* getCollisionObjectByName(const char* name);
+
+
+       const char*     getNameForPointer(const void* ptr) const;
+
+       ///those virtuals are called by load and can be overridden by the user
+
+
+
+       //bodies
+
+       virtual btCollisionObject*  createCollisionObject(      const btTransform& startTransform,      btCollisionShape* shape,const char* bodyName);
+
+       ///shapes
+
+       virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
+       virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
+       virtual btCollisionShape* createSphereShape(btScalar radius);
+       virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
+       virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
+       virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
+
+       virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
+       virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
+       virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
+       virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height);
+       virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height);
+       virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height);
+       virtual class btTriangleIndexVertexArray*       createTriangleMeshContainer();
+       virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
+       virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
+#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
+       virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
+#endif //SUPPORT_GIMPACT_SHAPE_IMPORT
+       virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);
+
+       virtual class btConvexHullShape* createConvexHullShape();
+       virtual class btCompoundShape* createCompoundShape();
+       virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
+
+       virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
+
+       virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
+
+       ///acceleration and connectivity structures
+       virtual btOptimizedBvh* createOptimizedBvh();
+       virtual btTriangleInfoMap* createTriangleInfoMap();
+
+
+
+
+};
+
+
+#endif //BT_WORLD_IMPORTER_H
index 286e6c31f2f52554c9de698730b77813407aa764..a80c438d12abe23ac3e22102e030900f115336a2 100644 (file)
@@ -123,7 +123,7 @@ public:
 
                //backup
                btTransform     orgTrans = m_compoundColObjWrap->getWorldTransform();
-               btTransform     orgInterpolationTrans = m_compoundColObjWrap->getWorldTransform();
+               
                const btTransform& childTrans = compoundShape->getChildTransform(index);
                btTransform     newChildWorldTrans = orgTrans*childTrans ;
 
@@ -232,7 +232,9 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
                m_compoundShapeRevision = compoundShape->getUpdateRevision();
        }
 
-
+    if (m_childCollisionAlgorithms.size()==0)
+        return;
+    
        const btDbvt* tree = compoundShape->getDynamicAabbTree();
        //use a dynamic aabb tree to cull potential child-overlaps
        btCompoundLeafCallback  callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
@@ -292,7 +294,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
                btManifoldArray manifoldArray;
         const btCollisionShape* childShape = 0;
         btTransform    orgTrans;
-        btTransform    orgInterpolationTrans;
+        
         btTransform    newChildWorldTrans;
         btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;        
         
@@ -302,8 +304,8 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
                        {
                                childShape = compoundShape->getChildShape(i);
                        //if not longer overlapping, remove the algorithm
-                orgTrans = colObjWrap->getWorldTransform();
-                orgInterpolationTrans = colObjWrap->getWorldTransform();
+                               orgTrans = colObjWrap->getWorldTransform();
+                
                                const btTransform& childTrans = compoundShape->getChildTransform(i);
                 newChildWorldTrans = orgTrans*childTrans ;
 
index 95780fb2d2729f99ffc9e4e345ca680d1453b823..1d64d84b87b7df98c0c82c952b6fa44fddf178fb 100644 (file)
@@ -112,10 +112,9 @@ struct     btCompoundCompoundLeafCallback : btDbvt::ICollide
                                                                        btManifoldResult*       resultOut,
                                                                        btHashedSimplePairCache* childAlgorithmsCache,
                                                                        btPersistentManifold*   sharedManifold)
-               :m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
+               :m_numOverlapPairs(0),m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
                m_childCollisionAlgorithmCache(childAlgorithmsCache),
-               m_sharedManifold(sharedManifold),
-               m_numOverlapPairs(0)
+               m_sharedManifold(sharedManifold)
        {
 
        }
index 4ec9ae713862284239f4d7b503f9a1e22b218362..1cb3d2e7a145d431724b91b72ea38d0dc32307db 100644 (file)
@@ -47,8 +47,6 @@ subject to the following restrictions:
 
 btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*                  simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
 {
-       m_numPerturbationIterations = 0;
-       m_minimumPointsPerturbationThreshold = 3;
        m_simplexSolver = simplexSolver;
        m_pdSolver = pdSolver;
 }
@@ -57,15 +55,13 @@ btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc()
 { 
 }
 
-btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int /* numPerturbationIterations */, int /* minimumPointsPerturbationThreshold */)
 : btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
 m_simplexSolver(simplexSolver),
 m_pdSolver(pdSolver),
 m_ownManifold (false),
 m_manifoldPtr(mf),
-m_lowLevelOfDetail(false),
- m_numPerturbationIterations(numPerturbationIterations),
-m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
+m_lowLevelOfDetail(false)
 {
        (void)body0Wrap;
        (void)body1Wrap;
index 18d9385a1804f6169abe4d4f45558d49a05710f2..24d133677862b4668a12140e3519d61c5f49e029 100644 (file)
@@ -40,9 +40,6 @@ class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
        btPersistentManifold*   m_manifoldPtr;
        bool                    m_lowLevelOfDetail;
        
-       int m_numPerturbationIterations;
-       int m_minimumPointsPerturbationThreshold;
-
 public:
 
        btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
index e23f5f7a88d688090e410ca1dddec95f37b39b40..912a52855682bf6067deba11ca4537fbdfeb9c5c 100644 (file)
@@ -88,20 +88,19 @@ partId, int triangleIndex)
         //just for debugging purposes
         //printf("triangle %d",m_triangleCount++);
 
-        const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
+
 
        btCollisionAlgorithmConstructionInfo ci;
        ci.m_dispatcher1 = m_dispatcher;
 
-       //const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
-
-       
 
 
 #if 0  
+       
        ///debug drawing of the overlapping triangles
        if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
        {
+               const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
                btVector3 color(1,1,0);
                btTransform& tr = ob->getWorldTransform();
                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
index c3cacec4a4f6d391a0edaddeac258defd5eb255d..d42f00a637ffe1f5b9f0eb0454c9f6866c88bc72 100644 (file)
@@ -105,12 +105,12 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
        int maxSize = sizeof(btConvexConvexAlgorithm);
        int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
        int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
-       int sl = sizeof(btConvexSeparatingDistanceUtil);
-       sl = sizeof(btGjkPairDetector);
+       int maxSize4 = sizeof(btCompoundCompoundCollisionAlgorithm);
+
        int     collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
        collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
        collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
-
+       collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
                
        if (constructionInfo.m_persistentManifoldPool)
        {
index cfcca5654de5db933d3d01324693304051149569..8c8a7c3c1e3be70e2f7502cc0fc406013fbfef1a 100644 (file)
@@ -28,9 +28,7 @@ int gFindSimplePairs =0;
 
 
 
-btHashedSimplePairCache::btHashedSimplePairCache():
-       m_blockedForChanges(false)
-{
+btHashedSimplePairCache::btHashedSimplePairCache() {
        int initialAllocatedSize= 2;
        m_overlappingPairArray.reserve(initialAllocatedSize);
        growTables();
index e88ef97e968bdbc3c8e3fd80f07f5ddf56410e0f..186964d723e2c48613f90a11bf82f292122c71a6 100644 (file)
@@ -55,9 +55,7 @@ extern int gFindSimplePairs;
 class btHashedSimplePairCache
 {
        btSimplePairArray       m_overlappingPairArray;
-       
-       bool            m_blockedForChanges;
-       
+               
 
 protected:
        
index 73fa4e87ea42f2f6bd9358fe18d705e92e93ccbc..6cba442ca5dabd636011af1690cec0ac5cbc8a4f 100644 (file)
@@ -193,7 +193,7 @@ struct btConnectivityProcessor : public btTriangleCallback
                                btScalar len2 = calculatedEdge.length2();
 
                                btScalar correctedAngle(0);
-                               btVector3 calculatedNormalB = normalA;
+                               //btVector3 calculatedNormalB = normalA;
                                bool isConvex = false;
 
                                if (len2<m_triangleInfoMap->m_planarEpsilon)
@@ -213,10 +213,6 @@ struct btConnectivityProcessor : public btTriangleCallback
                                        isConvex = (dotA<0.);
 
                                        correctedAngle = isConvex ? ang4 : -ang4;
-                                       btQuaternion orn2(calculatedEdge,-correctedAngle);
-                                       calculatedNormalB = btMatrix3x3(orn2)*normalA;
-
-
                                }
 
                                
index 493d635539ed4f2f7af3079488805fb5e1c0e473..1fa4995d160c30ba58681af6c39428361553a562 100644 (file)
@@ -39,7 +39,11 @@ ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
 
        bool m_useQuantizedAabbCompression;
        bool m_ownsBvh;
+#ifdef __clang__
+       bool m_pad[11] __attribute__((unused));////need padding due to alignment
+#else
        bool m_pad[11];////need padding due to alignment
+#endif
 
 public:
 
index 7578bb258dfad4f0b91dda20609f91937b326181..f8c55ace4eb9ea3cc9d6232072d3bf3a780aa2c8 100644 (file)
@@ -117,6 +117,7 @@ public:
        ///fills the dataBuffer and returns the struct name (and 0 on failure)
        virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
 
+       SIMD_FORCE_INLINE       void    deSerializeFloat(struct btCapsuleShapeData* dataBuffer);
 
 };
 
@@ -181,4 +182,13 @@ SIMD_FORCE_INLINE  const char*     btCapsuleShape::serialize(void* dataBuffer, btSeri
        return "btCapsuleShapeData";
 }
 
+SIMD_FORCE_INLINE      void    btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer)
+{
+       m_implicitShapeDimensions.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_implicitShapeDimensions);
+       m_collisionMargin = dataBuffer->m_convexInternalShapeData.m_collisionMargin;
+       m_localScaling.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_localScaling);
+       //it is best to already pre-allocate the matching btCapsuleShape*(X/Z) version to match m_upAxis
+       m_upAxis = dataBuffer->m_upAxis;
+}
+
 #endif //BT_CAPSULE_SHAPE_H
index ff017a206716e8f919eae221e358e827342c2ae0..5e86568005ec8a01bf86bd83f1242cf36f3a5ca7 100644 (file)
@@ -29,12 +29,13 @@ ATTRIBUTE_ALIGNED16(class) btCollisionShape
 protected:
        int m_shapeType;
        void* m_userPointer;
+       int m_userIndex;
 
 public:
 
        BT_DECLARE_ALIGNED_ALLOCATOR();
 
-       btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
+       btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0), m_userIndex(-1)
        {
        }
 
@@ -130,6 +131,16 @@ public:
        {
                return m_userPointer;
        }
+       void setUserIndex(int index)
+       {
+               m_userIndex = index;
+       }
+
+       int getUserIndex() const
+       {
+               return m_userIndex;
+       }
+
 
        virtual int     calculateSerializeBufferSize() const;
 
index 0aa75f2bff3b037071ae2c318f81a2d6a0efe762..e8c8c336cd2cc04a4f826538f60a3f020ed2d5f5 100644 (file)
@@ -18,7 +18,7 @@ subject to the following restrictions:
 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
 #include "LinearMath/btSerializer.h"
 
-btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
+btCompoundShape::btCompoundShape(bool enableDynamicAabbTree, const int initialChildCapacity)
 : m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)),
 m_localAabbMax(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)),
 m_dynamicAabbTree(0),
@@ -34,6 +34,8 @@ m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
                m_dynamicAabbTree = new(mem) btDbvt();
                btAssert(mem==m_dynamicAabbTree);
        }
+
+       m_children.reserve(initialChildCapacity);
 }
 
 
@@ -77,8 +79,8 @@ void  btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
        if (m_dynamicAabbTree)
        {
                const btDbvtVolume      bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
-               int index = m_children.size();
-               child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
+               size_t index = m_children.size();
+               child.m_node = m_dynamicAabbTree->insert(bounds,reinterpret_cast<void*>(index) );
        }
 
        m_children.push_back(child);
@@ -312,7 +314,8 @@ void btCompoundShape::createAabbTreeFromChildren()
             child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax);
 
             const btDbvtVolume  bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
-            child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
+                       size_t index2 = index;
+            child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index2) );
         }
     }
 }
index 141034a8e8c12ce507cdb1be0d32293036c7bcc8..4eef8dba3068c0f3ddeb7913577ce8da879b7f42 100644 (file)
@@ -53,6 +53,7 @@ SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompou
 /// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
 ATTRIBUTE_ALIGNED16(class) btCompoundShape     : public btCollisionShape
 {
+protected:
        btAlignedObjectArray<btCompoundShapeChild> m_children;
        btVector3                                               m_localAabbMin;
        btVector3                                               m_localAabbMax;
@@ -64,13 +65,12 @@ ATTRIBUTE_ALIGNED16(class) btCompoundShape  : public btCollisionShape
 
        btScalar        m_collisionMargin;
 
-protected:
        btVector3       m_localScaling;
 
 public:
        BT_DECLARE_ALIGNED_ALLOCATOR();
 
-       btCompoundShape(bool enableDynamicAabbTree = true);
+       explicit btCompoundShape(bool enableDynamicAabbTree = true, const int initialChildCapacity = 0);
 
        virtual ~btCompoundShape();
 
index 02ea5033b1564a0109e18709accfea2f6de613de..0623e351a9703fb564be8ed31ff99e74e4dba435 100644 (file)
@@ -13,9 +13,9 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
-//#if defined (_WIN32) || defined (__i386__)
-//#define BT_USE_SSE_IN_API
-//#endif
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
 
 #include "btConvexHullShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
index f4324c1f401b0e4d0708eca86904b1926f885f73..4f45319a83a90377050bd0ec4afec7e5eddea76f 100644 (file)
@@ -21,6 +21,7 @@ subject to the following restrictions:
 #include "btConvexPolyhedron.h"
 #include "LinearMath/btHashMap.h"
 
+
 btConvexPolyhedron::btConvexPolyhedron()
 {
 
@@ -33,7 +34,7 @@ btConvexPolyhedron::~btConvexPolyhedron()
 
 inline bool IsAlmostZero(const btVector3& v)
 {
-       if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false;
+       if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6)      return false;
        return true;
 }
 
index fb0d9fdb75a8dc450b864d3fa561b2c9d6c416e7..b56d72917de264142f22c75b5fee1d1a5a331acd 100644 (file)
@@ -13,9 +13,9 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
-//#if defined (_WIN32) || defined (__i386__)
-//#define BT_USE_SSE_IN_API
-//#endif
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
 
 #include "btConvexShape.h"
 #include "btTriangleShape.h"
@@ -48,7 +48,7 @@ btConvexShape::~btConvexShape()
 }
 
 
-void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
+void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin,btVector3& witnesPtMax) const
 {
        btVector3 localAxis = dir*trans.getBasis();
        btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
@@ -56,12 +56,16 @@ void btConvexShape::project(const btTransform& trans, const btVector3& dir, btSc
 
        min = vtx1.dot(dir);
        max = vtx2.dot(dir);
-
+       witnesPtMax = vtx2;
+       witnesPtMin = vtx1;
+       
        if(min>max)
        {
                btScalar tmp = min;
                min = max;
                max = tmp;
+               witnesPtMax = vtx1;
+               witnesPtMin = vtx2;
        }
 }
 
index 290cd9fd13c4e664570cdd347cce1b8ed1a55501..875f2ac195aa1cc3225b656ac760323b474da6e9 100644 (file)
@@ -52,7 +52,8 @@ public:
        btScalar getMarginNonVirtual () const;
        void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
 
-       virtual void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const;
+
+       virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const;
 
        
        //notice that the vectors should be unit length
index 26322791d041353aca86237740fcf08f54f8b576..441a89c6bb66d2c92bcb663ece8d6734bc2b3ca1 100644 (file)
@@ -59,15 +59,13 @@ PHY_ScalarType hdt, bool flipQuadEdges
 )
 {
        // validation
-       btAssert(heightStickWidth > 1 && "bad width");
-       btAssert(heightStickLength > 1 && "bad length");
-       btAssert(heightfieldData && "null heightfield data");
+       btAssert(heightStickWidth > 1);// && "bad width");
+       btAssert(heightStickLength > 1);// && "bad length");
+       btAssert(heightfieldData);// && "null heightfield data");
        // btAssert(heightScale) -- do we care?  Trust caller here
-       btAssert(minHeight <= maxHeight && "bad min/max height");
-       btAssert(upAxis >= 0 && upAxis < 3 &&
-           "bad upAxis--should be in range [0,2]");
-       btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
-           "Bad height data type enum");
+       btAssert(minHeight <= maxHeight);// && "bad min/max height");
+       btAssert(upAxis >= 0 && upAxis < 3);// && "bad upAxis--should be in range [0,2]");
+       btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT);// && "Bad height data type enum");
 
        // initialize member variables
        m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
@@ -110,7 +108,7 @@ PHY_ScalarType hdt, bool flipQuadEdges
        default:
                {
                        //need to get valid m_upAxis
-                       btAssert(0 && "Bad m_upAxis");
+                       btAssert(0);// && "Bad m_upAxis");
                }
        }
 
@@ -365,14 +363,15 @@ void      btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
                        {
         //first triangle
         getVertex(x,j,vertices[0]);
-        getVertex(x+1,j,vertices[1]);
-        getVertex(x+1,j+1,vertices[2]);
+               getVertex(x, j + 1, vertices[1]);
+               getVertex(x + 1, j + 1, vertices[2]);
         callback->processTriangle(vertices,x,j);
         //second triangle
       //  getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
         getVertex(x+1,j+1,vertices[1]);
-        getVertex(x,j+1,vertices[2]);
-        callback->processTriangle(vertices,x,j);                               
+               getVertex(x + 1, j, vertices[2]);
+               callback->processTriangle(vertices, x, j);
+
                        } else
                        {
         //first triangle
index 6abfdffa6775e04199cfa4e7f591efe09e30b9a5..a7362ea01f4000f9b1b1a1dba20acfeec5ce7661 100644 (file)
@@ -13,9 +13,9 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
-//#if defined (_WIN32) || defined (__i386__)
-//#define BT_USE_SSE_IN_API
-//#endif
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
 
 #include "btMultiSphereShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
index 2b92ab7d1b7707bd9180c17cade3efa80bbeff45..5ebaede4a88b74d3bb243153f6ee23837e255543 100644 (file)
@@ -25,7 +25,6 @@ subject to the following restrictions:
 ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape
 {
     btAlignedObjectArray <btMaterial*> m_materialList;
-    int ** m_triangleMaterials;
 
 public:
 
index 9095c592d87d64b9d77403b8986b4694184e508a..4854f370f73b175dfe9e5362fa8bb21715ed50e5 100644 (file)
@@ -12,9 +12,9 @@ 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.
 */
-//#if defined (_WIN32) || defined (__i386__)
-//#define BT_USE_SSE_IN_API
-//#endif
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
 
 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
 #include "btConvexPolyhedron.h"
index 38ef8f03706724f12cef6d923cfbca69a43b2a00..d17141e3f205fca2faccda18db82ebe7ba799b07 100644 (file)
@@ -21,7 +21,7 @@ subject to the following restrictions:
 btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
 : btConcaveShape (), m_planeNormal(planeNormal.normalized()),
 m_planeConstant(planeConstant),
-m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
+m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
 {
        m_shapeType = STATIC_PLANE_PROXYTYPE;
        //      btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );
index 5fbed334ec13f7766056a1eaabc4795f0f12c4ae..e4de73209309c921fb9673d97607940e280bc9ae 100644 (file)
@@ -75,6 +75,13 @@ void btTriangleMesh::addIndex(int index)
        }
 }
 
+void   btTriangleMesh::addTriangleIndices(int index1, int index2, int index3 )
+{
+       m_indexedMeshes[0].m_numTriangles++;
+       addIndex( index1 );
+       addIndex( index2 );
+       addIndex( index3 );
+}
 
 int    btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices)
 {
index 0afc2321ff0d728a8bd962fde19b449d19957007..ac4afa7f6b21e6f6ee037ffa7370a8d6af0205fb 100644 (file)
@@ -52,7 +52,10 @@ class btTriangleMesh : public btTriangleIndexVertexArray
                ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes.
                ///In general it is better to directly use btTriangleIndexVertexArray instead.
                void    addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false);
-               
+
+               ///Add a triangle using its indices. Make sure the indices are pointing within the vertices array, so add the vertices first (and to be sure, avoid removal of duplicate vertices)      
+               void    addTriangleIndices(int index1, int index2, int index3 );
+       
                int getNumTriangles() const;
 
                virtual void    preallocateVertices(int numverts);
diff --git a/extern/bullet2/src/BulletCollision/Doxyfile b/extern/bullet2/src/BulletCollision/Doxyfile
deleted file mode 100644 (file)
index 4ecb6ac..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-# Doxyfile 1.2.4
-
-# This file describes the settings to be used by doxygen for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# General configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project. 
-PROJECT_NAME           = "Bullet Continuous Collision Detection Library"
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = 
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, 
-# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, 
-# Polish, Portuguese and Slovene.
-
-OUTPUT_LANGUAGE        = English
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES 
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation. 
-
-EXTRACT_PRIVATE        = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation. 
-
-EXTRACT_STATIC         = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled. 
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these class will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled. 
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this. 
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed. 
-
-REPEAT_BRIEF           = YES
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description. 
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used. 
-
-FULL_PATH_NAMES        = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH        = 
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation. 
-
-INTERNAL_DOCS          = NO
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a class diagram (in Html and LaTeX) for classes with base or 
-# super classes. Setting the tag to NO turns the diagrams off. 
-
-CLASS_DIAGRAMS         = YES
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation. 
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible. 
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower case letters. If set to YES upper case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# users are adviced to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden. 
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this. 
-
-VERBATIM_HEADERS       = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put list of the files that are included by a file in the documentation 
-# of that file. 
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments  will behave just like the Qt-style comments (thus requiring an 
-# explict @brief command for a brief description. 
-
-JAVADOC_AUTOBRIEF      = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# reimplements. 
-
-INHERIT_DOCS           = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members. 
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order. 
-
-SORT_MEMBER_DOCS       = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments. 
-
-TAB_SIZE               = 8
-
-# The ENABLE_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif. 
-
-ENABLED_SECTIONS       = 
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines. 
-
-ALIASES                = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used. 
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used. 
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled. 
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. 
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr. 
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces. 
-
-INPUT                  = .
-
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included. 
-
-FILE_PATTERNS          = *.h *.cpp *.c
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used. 
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag. 
-
-EXCLUDE                = 
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. 
-
-EXCLUDE_PATTERNS       = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command). 
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included. 
-
-EXAMPLE_PATTERNS       = 
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command). 
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output. 
-
-INPUT_FILTER           = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse. 
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces. 
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20]) 
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers. 
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output. 
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path. 
-
-HTML_OUTPUT            = html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet 
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used. 
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation. 
-
-GENERATE_HTMLHELP      = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it. 
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation. 
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript and frames is required (for instance Netscape 4.0+ 
-# or Internet explorer 4.0+). 
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown. 
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output. 
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path. 
-
-LATEX_OUTPUT           = latex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general. 
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used. 
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output. 
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing! 
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer. 
-
-PDF_HYPERLINKS         = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation. 
-
-USE_PDFLATEX           = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML. 
-
-LATEX_BATCHMODE        = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimised for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path. 
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general. 
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using a WORD or other. 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links. 
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assigments. You only have to provide 
-# replacements, missing definitions are set to their default value. 
-
-RTF_STYLESHEET_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages 
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path. 
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3) 
-
-MAN_EXTENSION          = .3
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation. Warning: This feature 
-# is still experimental and very incomplete.
-
-GENERATE_XML           = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files. 
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES. 
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_PREDEFINED tags. 
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found. 
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor. 
-
-INCLUDE_PATH           = ../../generic/extern
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used. 
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. 
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition. 
-
-EXPAND_AS_DEFINED      = 
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tagfiles. 
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads. 
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed. 
-
-ALLEXTERNALS           = NO
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl'). 
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default) 
-
-HAVE_DOT               = YES
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes. 
-
-COLLABORATION_GRAPH    = YES
-
-# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to 
-# YES then doxygen will generate a graph for each documented file showing 
-# the direct and indirect include dependencies of the file with other 
-# documented files. 
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to 
-# YES then doxygen will generate a graph for each documented header file showing 
-# the documented files that directly or indirectly include this file 
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one. 
-
-GRAPHICAL_HIERARCHY    = YES
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found on the path. 
-
-DOT_PATH               = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images. 
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images. 
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs. 
-
-GENERATE_LEGEND        = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored. 
-
-SEARCHENGINE           = NO
-
-# The CGI_NAME tag should be the name of the CGI script that 
-# starts the search engine (doxysearch) with the correct parameters. 
-# A script with this name will be generated by doxygen. 
-
-CGI_NAME               = search.cgi
-
-# The CGI_URL tag should be the absolute URL to the directory where the 
-# cgi binaries are located. See the documentation of your http daemon for 
-# details. 
-
-CGI_URL                = 
-
-# The DOC_URL tag should be the absolute URL to the directory where the 
-# documentation is located. If left blank the absolute path to the 
-# documentation, with file:// prepended to it, will be used. 
-
-DOC_URL                = 
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the 
-# documentation is located. If left blank the directory on the local machine 
-# will be used. 
-
-DOC_ABSPATH            = 
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
-# is installed. 
-
-BIN_ABSPATH            = c:\program files\doxygen\bin
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
-# documentation generated for other projects. This allows doxysearch to search 
-# the documentation for these projects as well. 
-
-EXT_DOC_PATHS          = 
index 915277404d611ec0bbd55293e17bf58b0c6c1a1c..d98051da3d60bf6e0201a3ca475092218dc4c874 100644 (file)
@@ -404,12 +404,12 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
        CLASS_POINT & vPointA,
        CLASS_POINT & vPointB)
 {
-    CLASS_POINT _AD,_BD,_N;
+    CLASS_POINT _AD,_BD,n;
     vec4f _M;//plane
     VEC_DIFF(_AD,vA2,vA1);
     VEC_DIFF(_BD,vB2,vB1);
-    VEC_CROSS(_N,_AD,_BD);
-    GREAL _tp = VEC_DOT(_N,_N);
+    VEC_CROSS(n,_AD,_BD);
+    GREAL _tp = VEC_DOT(n,n);
     if(_tp<G_EPSILON)//ARE PARALELE
     {
        //project B over A
@@ -424,10 +424,10 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
        _M[2] = VEC_DOT(vA1,_AD);
        _M[3] = VEC_DOT(vA2,_AD);
        //mid points
-       _N[0] = (_M[0]+_M[1])*0.5f;
-       _N[1] = (_M[2]+_M[3])*0.5f;
+       n[0] = (_M[0]+_M[1])*0.5f;
+       n[1] = (_M[2]+_M[3])*0.5f;
 
-       if(_N[0]<_N[1])
+       if(n[0]<n[1])
        {
                if(_M[1]<_M[2])
                {
@@ -467,7 +467,7 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
     }
 
 
-    VEC_CROSS(_M,_N,_BD);
+    VEC_CROSS(_M,n,_BD);
     _M[3] = VEC_DOT(_M,vB1);
 
     LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,btScalar(0), btScalar(1));
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h
new file mode 100644 (file)
index 0000000..9eb880b
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2014 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.
+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 BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H
+#define BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H
+
+#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision...
+#include "btGjkEpa3.h"
+#include "btGjkCollisionDescription.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+
+
+
+
+
+
+template <typename btConvexTemplate>
+bool btGjkEpaCalcPenDepth(const btConvexTemplate& a, const btConvexTemplate& b,
+                          const btGjkCollisionDescription& colDesc,
+                          btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB)
+{
+    (void)v;
+    
+    // const btScalar                          radialmargin(btScalar(0.));
+    
+    btVector3  guessVector(b.getWorldTransform().getOrigin()-a.getWorldTransform().getOrigin());//?? why not use the GJK input?
+    
+    btGjkEpaSolver3::sResults  results;
+
+    
+    if(btGjkEpaSolver3_Penetration(a,b,guessVector,results))
+        
+    {
+        //     debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
+        //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
+        wWitnessOnA = results.witnesses[0];
+        wWitnessOnB = results.witnesses[1];
+        v = results.normal;
+        return true;
+    } else
+    {
+        if(btGjkEpaSolver3_Distance(a,b,guessVector,results))
+        {
+            wWitnessOnA = results.witnesses[0];
+            wWitnessOnB = results.witnesses[1];
+            v = results.normal;
+            return false;
+        }
+    }
+    return false;
+}
+
+template <typename btConvexTemplate, typename btGjkDistanceTemplate>
+int    btComputeGjkEpaPenetration(const btConvexTemplate& a, const btConvexTemplate& b, const btGjkCollisionDescription& colDesc, btVoronoiSimplexSolver& simplexSolver, btGjkDistanceTemplate* distInfo)
+{
+    
+    bool m_catchDegeneracies  = true;
+    btScalar m_cachedSeparatingDistance = 0.f;
+    
+    btScalar distance=btScalar(0.);
+    btVector3  normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
+    
+    btVector3 pointOnA,pointOnB;
+    btTransform        localTransA = a.getWorldTransform();
+    btTransform localTransB = b.getWorldTransform();
+    
+    btScalar marginA = a.getMargin();
+    btScalar marginB = b.getMargin();
+    
+    int m_curIter = 0;
+    int gGjkMaxIter = colDesc.m_maxGjkIterations;//this is to catch invalid input, perhaps check for #NaN?
+    btVector3 m_cachedSeparatingAxis = colDesc.m_firstDir;
+    
+    bool isValid = false;
+    bool checkSimplex = false;
+    bool checkPenetration = true;
+    int m_degenerateSimplex = 0;
+    
+    int m_lastUsedMethod = -1;
+    
+    {
+        btScalar squaredDistance = BT_LARGE_FLOAT;
+        btScalar delta = btScalar(0.);
+        
+        btScalar margin = marginA + marginB;
+        
+        
+        
+        simplexSolver.reset();
+        
+        for ( ; ; )
+            //while (true)
+        {
+            
+            btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* localTransA.getBasis();
+            btVector3 seperatingAxisInB = m_cachedSeparatingAxis* localTransB.getBasis();
+            
+            btVector3 pInA = a.getLocalSupportWithoutMargin(seperatingAxisInA);
+            btVector3 qInB = b.getLocalSupportWithoutMargin(seperatingAxisInB);
+            
+            btVector3  pWorld = localTransA(pInA);
+            btVector3  qWorld = localTransB(qInB);
+            
+            
+            
+            btVector3 w        = pWorld - qWorld;
+            delta = m_cachedSeparatingAxis.dot(w);
+            
+            // potential exit, they don't overlap
+            if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * colDesc.m_maximumDistanceSquared))
+            {
+                m_degenerateSimplex = 10;
+                checkSimplex=true;
+                //checkPenetration = false;
+                break;
+            }
+            
+            //exit 0: the new point is already in the simplex, or we didn't come any closer
+            if (simplexSolver.inSimplex(w))
+            {
+                m_degenerateSimplex = 1;
+                checkSimplex = true;
+                break;
+            }
+            // are we getting any closer ?
+            btScalar f0 = squaredDistance - delta;
+            btScalar f1 = squaredDistance * colDesc.m_gjkRelError2;
+            
+            if (f0 <= f1)
+            {
+                if (f0 <= btScalar(0.))
+                {
+                    m_degenerateSimplex = 2;
+                } else
+                {
+                    m_degenerateSimplex = 11;
+                }
+                checkSimplex = true;
+                break;
+            }
+            
+            //add current vertex to simplex
+            simplexSolver.addVertex(w, pWorld, qWorld);
+            btVector3 newCachedSeparatingAxis;
+            
+            //calculate the closest point to the origin (update vector v)
+            if (!simplexSolver.closest(newCachedSeparatingAxis))
+            {
+                m_degenerateSimplex = 3;
+                checkSimplex = true;
+                break;
+            }
+            
+            if(newCachedSeparatingAxis.length2()<colDesc.m_gjkRelError2)
+            {
+                m_cachedSeparatingAxis = newCachedSeparatingAxis;
+                m_degenerateSimplex = 6;
+                checkSimplex = true;
+                break;
+            }
+            
+            btScalar previousSquaredDistance = squaredDistance;
+            squaredDistance = newCachedSeparatingAxis.length2();
+#if 0
+            ///warning: this termination condition leads to some problems in 2d test case see Bullet/Demos/Box2dDemo
+            if (squaredDistance>previousSquaredDistance)
+            {
+                m_degenerateSimplex = 7;
+                squaredDistance = previousSquaredDistance;
+                checkSimplex = false;
+                break;
+            }
+#endif //
+            
+            
+            //redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
+            
+            //are we getting any closer ?
+            if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance)
+            {
+                //                             m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+                checkSimplex = true;
+                m_degenerateSimplex = 12;
+                
+                break;
+            }
+            
+            m_cachedSeparatingAxis = newCachedSeparatingAxis;
+            
+            //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject
+            if (m_curIter++ > gGjkMaxIter)
+            {
+#if defined(DEBUG) || defined (_DEBUG)
+                
+                printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);
+                printf("sepAxis=(%f,%f,%f), squaredDistance = %f\n",
+                       m_cachedSeparatingAxis.getX(),
+                       m_cachedSeparatingAxis.getY(),
+                       m_cachedSeparatingAxis.getZ(),
+                       squaredDistance);
+#endif
+                
+                break;
+                
+            }
+            
+            
+            bool check = (!simplexSolver.fullSimplex());
+            //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex());
+            
+            if (!check)
+            {
+                //do we need this backup_closest here ?
+                //                             m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+                m_degenerateSimplex = 13;
+                break;
+            }
+        }
+        
+        if (checkSimplex)
+        {
+            simplexSolver.compute_points(pointOnA, pointOnB);
+            normalInB = m_cachedSeparatingAxis;
+            
+            btScalar lenSqr =m_cachedSeparatingAxis.length2();
+            
+            //valid normal
+            if (lenSqr < 0.0001)
+            {
+                m_degenerateSimplex = 5;
+            }
+            if (lenSqr > SIMD_EPSILON*SIMD_EPSILON)
+            {
+                btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+                normalInB *= rlen; //normalize
+                
+                btScalar s = btSqrt(squaredDistance);
+                
+                btAssert(s > btScalar(0.0));
+                pointOnA -= m_cachedSeparatingAxis * (marginA / s);
+                pointOnB += m_cachedSeparatingAxis * (marginB / s);
+                distance = ((btScalar(1.)/rlen) - margin);
+                isValid = true;
+                
+                m_lastUsedMethod = 1;
+            } else
+            {
+                m_lastUsedMethod = 2;
+            }
+        }
+        
+        bool catchDegeneratePenetrationCase =
+        (m_catchDegeneracies &&  m_degenerateSimplex && ((distance+margin) < 0.01));
+        
+        //if (checkPenetration && !isValid)
+        if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
+        {
+            //penetration case
+            
+            //if there is no way to handle penetrations, bail out
+            
+            // Penetration depth case.
+            btVector3 tmpPointOnA,tmpPointOnB;
+            
+            m_cachedSeparatingAxis.setZero();
+            
+            bool isValid2 = btGjkEpaCalcPenDepth(a,b,
+                                                 colDesc,
+                                                 m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB);
+            
+            if (isValid2)
+            {
+                btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
+                btScalar lenSqr = tmpNormalInB.length2();
+                if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON))
+                {
+                    tmpNormalInB = m_cachedSeparatingAxis;
+                    lenSqr = m_cachedSeparatingAxis.length2();
+                }
+                
+                if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
+                {
+                    tmpNormalInB /= btSqrt(lenSqr);
+                    btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
+                    //only replace valid penetrations when the result is deeper (check)
+                    if (!isValid || (distance2 < distance))
+                    {
+                        distance = distance2;
+                        pointOnA = tmpPointOnA;
+                        pointOnB = tmpPointOnB;
+                        normalInB = tmpNormalInB;
+                        
+                        isValid = true;
+                        m_lastUsedMethod = 3;
+                    } else
+                    {
+                        m_lastUsedMethod = 8;
+                    }
+                } else
+                {
+                    m_lastUsedMethod = 9;
+                }
+            } else
+                
+            {
+                ///this is another degenerate case, where the initial GJK calculation reports a degenerate case
+                ///EPA reports no penetration, and the second GJK (using the supporting vector without margin)
+                ///reports a valid positive distance. Use the results of the second GJK instead of failing.
+                ///thanks to Jacob.Langford for the reproduction case
+                ///http://code.google.com/p/bullet/issues/detail?id=250
+                
+                
+                if (m_cachedSeparatingAxis.length2() > btScalar(0.))
+                {
+                    btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin;
+                    //only replace valid distances when the distance is less
+                    if (!isValid || (distance2 < distance))
+                    {
+                        distance = distance2;
+                        pointOnA = tmpPointOnA;
+                        pointOnB = tmpPointOnB;
+                        pointOnA -= m_cachedSeparatingAxis * marginA ;
+                        pointOnB += m_cachedSeparatingAxis * marginB ;
+                        normalInB = m_cachedSeparatingAxis;
+                        normalInB.normalize();
+                        
+                        isValid = true;
+                        m_lastUsedMethod = 6;
+                    } else
+                    {
+                        m_lastUsedMethod = 5;
+                    }
+                }
+            }
+        }
+    }
+    
+    
+    
+    if (isValid && ((distance < 0) || (distance*distance < colDesc.m_maximumDistanceSquared)))
+    {
+        
+        m_cachedSeparatingAxis = normalInB;
+        m_cachedSeparatingDistance = distance;
+        distInfo->m_distance = distance;
+        distInfo->m_normalBtoA = normalInB;
+        distInfo->m_pointOnB = pointOnB;
+        distInfo->m_pointOnA = pointOnB+normalInB*distance;
+        return 0;
+    }
+    return -m_lastUsedMethod;
+}
+
+
+
+
+#endif //BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h
new file mode 100644 (file)
index 0000000..0b49b0e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2014 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.
+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 GJK_COLLISION_DESCRIPTION_H
+#define GJK_COLLISION_DESCRIPTION_H
+
+#include "LinearMath/btVector3.h"
+
+struct btGjkCollisionDescription
+{
+    btVector3  m_firstDir;
+    int                        m_maxGjkIterations;
+    btScalar   m_maximumDistanceSquared;
+    btScalar   m_gjkRelError2;
+    btGjkCollisionDescription()
+    :m_firstDir(0,1,0),
+    m_maxGjkIterations(1000),
+    m_maximumDistanceSquared(1e30f),
+    m_gjkRelError2(1.0e-6)
+    {
+    }
+    virtual ~btGjkCollisionDescription()
+    {
+    }
+};
+
+#endif //GJK_COLLISION_DESCRIPTION_H
+
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h
new file mode 100644 (file)
index 0000000..ce1f24b
--- /dev/null
@@ -0,0 +1,1035 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2014 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.
+*/
+
+/*
+Initial GJK-EPA collision solver by Nathanael Presson, 2008
+Improvements and refactoring by Erwin Coumans, 2008-2014
+*/
+#ifndef BT_GJK_EPA3_H
+#define BT_GJK_EPA3_H
+
+#include "LinearMath/btTransform.h"
+#include "btGjkCollisionDescription.h"
+
+
+
+struct btGjkEpaSolver3
+{
+struct sResults
+       {
+       enum eStatus
+               {
+               Separated,              /* Shapes doesnt penetrate                                                                                              */ 
+               Penetrating,    /* Shapes are penetrating                                                                                               */ 
+               GJK_Failed,             /* GJK phase fail, no big issue, shapes are probably just 'touching'    */ 
+               EPA_Failed              /* EPA phase fail, bigger problem, need to save parameters, and debug   */ 
+               }               status;
+       btVector3       witnesses[2];
+       btVector3       normal;
+       btScalar        distance;
+       };
+
+
+};
+
+
+
+#if defined(DEBUG) || defined (_DEBUG)
+#include <stdio.h> //for debug printf
+#ifdef __SPU__
+#include <spu_printf.h>
+#define printf spu_printf
+#endif //__SPU__
+#endif
+
+
+    
+    // Config
+    
+    /* GJK     */
+#define GJK_MAX_ITERATIONS     128
+#define GJK_ACCURARY           ((btScalar)0.0001)
+#define GJK_MIN_DISTANCE       ((btScalar)0.0001)
+#define GJK_DUPLICATED_EPS     ((btScalar)0.0001)
+#define GJK_SIMPLEX2_EPS       ((btScalar)0.0)
+#define GJK_SIMPLEX3_EPS       ((btScalar)0.0)
+#define GJK_SIMPLEX4_EPS       ((btScalar)0.0)
+    
+    /* EPA     */
+#define EPA_MAX_VERTICES       64
+#define EPA_MAX_FACES          (EPA_MAX_VERTICES*2)
+#define EPA_MAX_ITERATIONS     255
+#define EPA_ACCURACY           ((btScalar)0.0001)
+#define EPA_FALLBACK           (10*EPA_ACCURACY)
+#define EPA_PLANE_EPS          ((btScalar)0.00001)
+#define EPA_INSIDE_EPS         ((btScalar)0.01)
+    
+    
+    // Shorthands
+    typedef unsigned int       U;
+    typedef unsigned char      U1;
+    
+    // MinkowskiDiff
+    template <typename btConvexTemplate>
+    struct     MinkowskiDiff
+    {
+        const btConvexTemplate* m_convexAPtr;
+        const btConvexTemplate* m_convexBPtr;
+        
+        btMatrix3x3                            m_toshape1;
+        btTransform                            m_toshape0;
+        
+        bool                                   m_enableMargin;
+        
+        
+        MinkowskiDiff(const btConvexTemplate& a, const btConvexTemplate& b)
+        :m_convexAPtr(&a),
+        m_convexBPtr(&b)
+        {
+        }
+        
+        void                                   EnableMargin(bool enable)
+        {
+            m_enableMargin = enable;
+        }
+        inline btVector3               Support0(const btVector3& d) const
+        {
+            return m_convexAPtr->getLocalSupportWithMargin(d);
+        }
+        inline btVector3               Support1(const btVector3& d) const
+        {
+            return m_toshape0*m_convexBPtr->getLocalSupportWithMargin(m_toshape1*d);
+        }
+        
+        
+        inline btVector3               Support(const btVector3& d) const
+        {
+            return(Support0(d)-Support1(-d));
+        }
+        btVector3                              Support(const btVector3& d,U index) const
+        {
+            if(index)
+                return(Support1(d));
+            else
+                return(Support0(d));
+        }
+    };
+    
+enum   eGjkStatus
+{
+    eGjkValid,
+    eGjkInside,
+    eGjkFailed
+};
+
+    // GJK
+    template <typename btConvexTemplate>
+    struct     GJK
+    {
+        /* Types               */
+        struct sSV
+        {
+            btVector3  d,w;
+        };
+        struct sSimplex
+        {
+            sSV*               c[4];
+            btScalar   p[4];
+            U                  rank;
+        };
+        
+        /* Fields              */
+        
+        MinkowskiDiff<btConvexTemplate>                        m_shape;
+        btVector3              m_ray;
+        btScalar               m_distance;
+        sSimplex               m_simplices[2];
+        sSV                            m_store[4];
+        sSV*                   m_free[4];
+        U                              m_nfree;
+        U                              m_current;
+        sSimplex*              m_simplex;
+        eGjkStatus      m_status;
+        /* Methods             */
+        
+        GJK(const btConvexTemplate& a, const btConvexTemplate& b)
+        :m_shape(a,b)
+        {
+            Initialize();
+        }
+        void                           Initialize()
+        {
+            m_ray              =       btVector3(0,0,0);
+            m_nfree            =       0;
+            m_status   =       eGjkFailed;
+            m_current  =       0;
+            m_distance =       0;
+        }
+        eGjkStatus                     Evaluate(const MinkowskiDiff<btConvexTemplate>& shapearg,const btVector3& guess)
+        {
+            U                  iterations=0;
+            btScalar   sqdist=0;
+            btScalar   alpha=0;
+            btVector3  lastw[4];
+            U                  clastw=0;
+            /* Initialize solver               */
+            m_free[0]                  =       &m_store[0];
+            m_free[1]                  =       &m_store[1];
+            m_free[2]                  =       &m_store[2];
+            m_free[3]                  =       &m_store[3];
+            m_nfree                            =       4;
+            m_current                  =       0;
+            m_status                   =       eGjkValid;
+            m_shape                            =       shapearg;
+            m_distance                 =       0;
+            /* Initialize simplex              */
+            m_simplices[0].rank        =       0;
+            m_ray                              =       guess;
+            const btScalar     sqrl=   m_ray.length2();
+            appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
+            m_simplices[0].p[0]        =       1;
+            m_ray                              =       m_simplices[0].c[0]->w;
+            sqdist                             =       sqrl;
+            lastw[0]                   =
+            lastw[1]                   =
+            lastw[2]                   =
+            lastw[3]                   =       m_ray;
+            /* Loop                                            */
+            do {
+                const U                next=1-m_current;
+                sSimplex&      cs=m_simplices[m_current];
+                sSimplex&      ns=m_simplices[next];
+                /* Check zero                                                  */
+                const btScalar rl=m_ray.length();
+                if(rl<GJK_MIN_DISTANCE)
+                {/* Touching or inside                         */
+                    m_status=eGjkInside;
+                    break;
+                }
+                /* Append new vertice in -'v' direction        */
+                appendvertice(cs,-m_ray);
+                const btVector3&       w=cs.c[cs.rank-1]->w;
+                bool                           found=false;
+                for(U i=0;i<4;++i)
+                {
+                    if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
+                    { found=true;break; }
+                }
+                if(found)
+                {/* Return old simplex                         */
+                    removevertice(m_simplices[m_current]);
+                    break;
+                }
+                else
+                {/* Update lastw                                       */
+                    lastw[clastw=(clastw+1)&3]=w;
+                }
+                /* Check for termination                               */
+                const btScalar omega=btDot(m_ray,w)/rl;
+                alpha=btMax(omega,alpha);
+                if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
+                {/* Return old simplex                         */
+                    removevertice(m_simplices[m_current]);
+                    break;
+                }
+                /* Reduce simplex                                              */
+                btScalar       weights[4];
+                U                      mask=0;
+                switch(cs.rank)
+                {
+                    case       2:      sqdist=projectorigin(   cs.c[0]->w,
+                                                     cs.c[1]->w,
+                                                     weights,mask);break;
+                    case       3:      sqdist=projectorigin(   cs.c[0]->w,
+                                                     cs.c[1]->w,
+                                                     cs.c[2]->w,
+                                                     weights,mask);break;
+                    case       4:      sqdist=projectorigin(   cs.c[0]->w,
+                                                     cs.c[1]->w,
+                                                     cs.c[2]->w,
+                                                     cs.c[3]->w,
+                                                     weights,mask);break;
+                }
+                if(sqdist>=0)
+                {/* Valid      */
+                    ns.rank            =       0;
+                    m_ray              =       btVector3(0,0,0);
+                    m_current  =       next;
+                    for(U i=0,ni=cs.rank;i<ni;++i)
+                    {
+                        if(mask&(1<<i))
+                        {
+                            ns.c[ns.rank]              =       cs.c[i];
+                            ns.p[ns.rank++]            =       weights[i];
+                            m_ray                              +=      cs.c[i]->w*weights[i];
+                        }
+                        else
+                        {
+                            m_free[m_nfree++]  =       cs.c[i];
+                        }
+                    }
+                    if(mask==15) m_status=eGjkInside;
+                }
+                else
+                {/* Return old simplex                         */
+                    removevertice(m_simplices[m_current]);
+                    break;
+                }
+                m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eGjkFailed;
+            } while(m_status==eGjkValid);
+            m_simplex=&m_simplices[m_current];
+            switch(m_status)
+            {
+                case   eGjkValid:              m_distance=m_ray.length();break;
+                case   eGjkInside:     m_distance=0;break;
+                default:
+                {
+                }
+            }
+            return(m_status);
+        }
+        bool                                   EncloseOrigin()
+        {
+            switch(m_simplex->rank)
+            {
+                case   1:
+                {
+                    for(U i=0;i<3;++i)
+                    {
+                        btVector3              axis=btVector3(0,0,0);
+                        axis[i]=1;
+                        appendvertice(*m_simplex, axis);
+                        if(EncloseOrigin())    return(true);
+                        removevertice(*m_simplex);
+                        appendvertice(*m_simplex,-axis);
+                        if(EncloseOrigin())    return(true);
+                        removevertice(*m_simplex);
+                    }
+                }
+                    break;
+                case   2:
+                {
+                    const btVector3    d=m_simplex->c[1]->w-m_simplex->c[0]->w;
+                    for(U i=0;i<3;++i)
+                    {
+                        btVector3              axis=btVector3(0,0,0);
+                        axis[i]=1;
+                        const btVector3        p=btCross(d,axis);
+                        if(p.length2()>0)
+                        {
+                            appendvertice(*m_simplex, p);
+                            if(EncloseOrigin())        return(true);
+                            removevertice(*m_simplex);
+                            appendvertice(*m_simplex,-p);
+                            if(EncloseOrigin())        return(true);
+                            removevertice(*m_simplex);
+                        }
+                    }
+                }
+                    break;
+                case   3:
+                {
+                    const btVector3    n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w,
+                                              m_simplex->c[2]->w-m_simplex->c[0]->w);
+                    if(n.length2()>0)
+                    {
+                        appendvertice(*m_simplex,n);
+                        if(EncloseOrigin())    return(true);
+                        removevertice(*m_simplex);
+                        appendvertice(*m_simplex,-n);
+                        if(EncloseOrigin())    return(true);
+                        removevertice(*m_simplex);
+                    }
+                }
+                    break;
+                case   4:
+                {
+                    if(btFabs(det(     m_simplex->c[0]->w-m_simplex->c[3]->w,
+                                  m_simplex->c[1]->w-m_simplex->c[3]->w,
+                                  m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
+                        return(true);
+                }
+                    break;
+            }
+            return(false);
+        }
+        /* Internals   */
+        void                           getsupport(const btVector3& d,sSV& sv) const
+        {
+            sv.d       =       d/d.length();
+            sv.w       =       m_shape.Support(sv.d);
+        }
+        void                           removevertice(sSimplex& simplex)
+        {
+            m_free[m_nfree++]=simplex.c[--simplex.rank];
+        }
+        void                           appendvertice(sSimplex& simplex,const btVector3& v)
+        {
+            simplex.p[simplex.rank]=0;
+            simplex.c[simplex.rank]=m_free[--m_nfree];
+            getsupport(v,*simplex.c[simplex.rank++]);
+        }
+        static btScalar                det(const btVector3& a,const btVector3& b,const btVector3& c)
+        {
+            return(    a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
+                   a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
+                   a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
+        }
+        static btScalar                projectorigin(  const btVector3& a,
+                                          const btVector3& b,
+                                          btScalar* w,U& m)
+        {
+            const btVector3    d=b-a;
+            const btScalar     l=d.length2();
+            if(l>GJK_SIMPLEX2_EPS)
+            {
+                const btScalar t(l>0?-btDot(a,d)/l:0);
+                if(t>=1)               { w[0]=0;w[1]=1;m=2;return(b.length2()); }
+                else if(t<=0)  { w[0]=1;w[1]=0;m=1;return(a.length2()); }
+                else                   { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
+            }
+            return(-1);
+        }
+        static btScalar                projectorigin(  const btVector3& a,
+                                          const btVector3& b,
+                                          const btVector3& c,
+                                          btScalar* w,U& m)
+        {
+            static const U             imd3[]={1,2,0};
+            const btVector3*   vt[]={&a,&b,&c};
+            const btVector3            dl[]={a-b,b-c,c-a};
+            const btVector3            n=btCross(dl[0],dl[1]);
+            const btScalar             l=n.length2();
+            if(l>GJK_SIMPLEX3_EPS)
+            {
+                btScalar       mindist=-1;
+                btScalar       subw[2]={0.f,0.f};
+                U                      subm(0);
+                for(U i=0;i<3;++i)
+                {
+                    if(btDot(*vt[i],btCross(dl[i],n))>0)
+                    {
+                        const U                        j=imd3[i];
+                        const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm));
+                        if((mindist<0)||(subd<mindist))
+                        {
+                            mindist            =       subd;
+                            m                  =       static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
+                            w[i]               =       subw[0];
+                            w[j]               =       subw[1];
+                            w[imd3[j]] =       0;
+                        }
+                    }
+                }
+                if(mindist<0)
+                {
+                    const btScalar     d=btDot(a,n);
+                    const btScalar     s=btSqrt(l);
+                    const btVector3    p=n*(d/l);
+                    mindist    =       p.length2();
+                    m          =       7;
+                    w[0]       =       (btCross(dl[1],b-p)).length()/s;
+                    w[1]       =       (btCross(dl[2],c-p)).length()/s;
+                    w[2]       =       1-(w[0]+w[1]);
+                }
+                return(mindist);
+            }
+            return(-1);
+        }
+        static btScalar                projectorigin(  const btVector3& a,
+                                          const btVector3& b,
+                                          const btVector3& c,
+                                          const btVector3& d,
+                                          btScalar* w,U& m)
+        {
+            static const U             imd3[]={1,2,0};
+            const btVector3*   vt[]={&a,&b,&c,&d};
+            const btVector3            dl[]={a-d,b-d,c-d};
+            const btScalar             vl=det(dl[0],dl[1],dl[2]);
+            const bool                 ng=(vl*btDot(a,btCross(b-c,a-b)))<=0;
+            if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
+            {
+                btScalar       mindist=-1;
+                btScalar       subw[3]={0.f,0.f,0.f};
+                U                      subm(0);
+                for(U i=0;i<3;++i)
+                {
+                    const U                    j=imd3[i];
+                    const btScalar     s=vl*btDot(d,btCross(dl[i],dl[j]));
+                    if(s>0)
+                    {
+                        const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
+                        if((mindist<0)||(subd<mindist))
+                        {
+                            mindist            =       subd;
+                            m                  =       static_cast<U>((subm&1?1<<i:0)+
+                                                           (subm&2?1<<j:0)+
+                                                           (subm&4?8:0));
+                            w[i]               =       subw[0];
+                            w[j]               =       subw[1];
+                            w[imd3[j]] =       0;
+                            w[3]               =       subw[2];
+                        }
+                    }
+                }
+                if(mindist<0)
+                {
+                    mindist    =       0;
+                    m          =       15;
+                    w[0]       =       det(c,b,d)/vl;
+                    w[1]       =       det(a,c,d)/vl;
+                    w[2]       =       det(b,a,d)/vl;
+                    w[3]       =       1-(w[0]+w[1]+w[2]);
+                }
+                return(mindist);
+            }
+            return(-1);
+        }
+    };
+
+
+enum   eEpaStatus
+{
+    eEpaValid,
+    eEpaTouching,
+    eEpaDegenerated,
+    eEpaNonConvex,
+    eEpaInvalidHull,
+    eEpaOutOfFaces,
+    eEpaOutOfVertices,
+    eEpaAccuraryReached,
+    eEpaFallBack,
+    eEpaFailed
+};
+
+
+    // EPA
+template <typename btConvexTemplate>
+    struct     EPA
+    {
+        /* Types               */
+       
+        struct sFace
+        {
+            btVector3  n;
+            btScalar   d;
+            typename GJK<btConvexTemplate>::sSV*               c[3];
+            sFace*             f[3];
+            sFace*             l[2];
+            U1                 e[3];
+            U1                 pass;
+        };
+        struct sList
+        {
+            sFace*             root;
+            U                  count;
+            sList() : root(0),count(0) {}
+        };
+        struct sHorizon
+        {
+            sFace*             cf;
+            sFace*             ff;
+            U                  nf;
+            sHorizon() : cf(0),ff(0),nf(0)     {}
+        };
+       
+        /* Fields              */
+        eEpaStatus             m_status;
+        typename GJK<btConvexTemplate>::sSimplex       m_result;
+        btVector3              m_normal;
+        btScalar               m_depth;
+        typename GJK<btConvexTemplate>::sSV                            m_sv_store[EPA_MAX_VERTICES];
+        sFace                  m_fc_store[EPA_MAX_FACES];
+        U                              m_nextsv;
+        sList                  m_hull;
+        sList                  m_stock;
+        /* Methods             */
+        EPA()
+        {
+            Initialize();
+        }
+        
+        
+        static inline void             bind(sFace* fa,U ea,sFace* fb,U eb)
+        {
+            fa->e[ea]=(U1)eb;fa->f[ea]=fb;
+            fb->e[eb]=(U1)ea;fb->f[eb]=fa;
+        }
+        static inline void             append(sList& list,sFace* face)
+        {
+            face->l[0] =       0;
+            face->l[1] =       list.root;
+            if(list.root) list.root->l[0]=face;
+            list.root  =       face;
+            ++list.count;
+        }
+        static inline void             remove(sList& list,sFace* face)
+        {
+            if(face->l[1]) face->l[1]->l[0]=face->l[0];
+            if(face->l[0]) face->l[0]->l[1]=face->l[1];
+            if(face==list.root) list.root=face->l[1];
+            --list.count;
+        }
+        
+        
+        void                           Initialize()
+        {
+            m_status   =       eEpaFailed;
+            m_normal   =       btVector3(0,0,0);
+            m_depth            =       0;
+            m_nextsv   =       0;
+            for(U i=0;i<EPA_MAX_FACES;++i)
+            {
+                append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
+            }
+        }
+        eEpaStatus                     Evaluate(GJK<btConvexTemplate>& gjk,const btVector3& guess)
+        {
+            typename GJK<btConvexTemplate>::sSimplex&  simplex=*gjk.m_simplex;
+            if((simplex.rank>1)&&gjk.EncloseOrigin())
+            {
+                
+                /* Clean up                            */
+                while(m_hull.root)
+                {
+                    sFace*     f = m_hull.root;
+                    remove(m_hull,f);
+                    append(m_stock,f);
+                }
+                m_status       =       eEpaValid;
+                m_nextsv       =       0;
+                /* Orient simplex              */
+                if(gjk.det(    simplex.c[0]->w-simplex.c[3]->w,
+                           simplex.c[1]->w-simplex.c[3]->w,
+                           simplex.c[2]->w-simplex.c[3]->w)<0)
+                {
+                    btSwap(simplex.c[0],simplex.c[1]);
+                    btSwap(simplex.p[0],simplex.p[1]);
+                }
+                /* Build initial hull  */
+                sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
+                    newface(simplex.c[1],simplex.c[0],simplex.c[3],true),
+                    newface(simplex.c[2],simplex.c[1],simplex.c[3],true),
+                    newface(simplex.c[0],simplex.c[2],simplex.c[3],true)};
+                if(m_hull.count==4)
+                {
+                    sFace*             best=findbest();
+                    sFace              outer=*best;
+                    U                  pass=0;
+                    U                  iterations=0;
+                    bind(tetra[0],0,tetra[1],0);
+                    bind(tetra[0],1,tetra[2],0);
+                    bind(tetra[0],2,tetra[3],0);
+                    bind(tetra[1],1,tetra[3],2);
+                    bind(tetra[1],2,tetra[2],1);
+                    bind(tetra[2],2,tetra[3],1);
+                    m_status=eEpaValid;
+                    for(;iterations<EPA_MAX_ITERATIONS;++iterations)
+                    {
+                        if(m_nextsv<EPA_MAX_VERTICES)
+                        {
+                            sHorizon           horizon;
+                            typename GJK<btConvexTemplate>::sSV*                       w=&m_sv_store[m_nextsv++];
+                            bool                       valid=true;
+                            best->pass =       (U1)(++pass);
+                            gjk.getsupport(best->n,*w);
+                            const btScalar     wdist=btDot(best->n,w->w)-best->d;
+                            if(wdist>EPA_ACCURACY)
+                            {
+                                for(U j=0;(j<3)&&valid;++j)
+                                {
+                                    valid&=expand(     pass,w,
+                                                  best->f[j],best->e[j],
+                                                  horizon);
+                                }
+                                if(valid&&(horizon.nf>=3))
+                                {
+                                    bind(horizon.cf,1,horizon.ff,2);
+                                    remove(m_hull,best);
+                                    append(m_stock,best);
+                                    best=findbest();
+                                    outer=*best;
+                                } else { m_status=eEpaInvalidHull;break; }
+                            } else { m_status=eEpaAccuraryReached;break; }
+                        } else { m_status=eEpaOutOfVertices;break; }
+                    }
+                    const btVector3    projection=outer.n*outer.d;
+                    m_normal   =       outer.n;
+                    m_depth            =       outer.d;
+                    m_result.rank      =       3;
+                    m_result.c[0]      =       outer.c[0];
+                    m_result.c[1]      =       outer.c[1];
+                    m_result.c[2]      =       outer.c[2];
+                    m_result.p[0]      =       btCross(        outer.c[1]->w-projection,
+                                                outer.c[2]->w-projection).length();
+                    m_result.p[1]      =       btCross(        outer.c[2]->w-projection,
+                                                outer.c[0]->w-projection).length();
+                    m_result.p[2]      =       btCross(        outer.c[0]->w-projection,
+                                                outer.c[1]->w-projection).length();
+                    const btScalar     sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
+                    m_result.p[0]      /=      sum;
+                    m_result.p[1]      /=      sum;
+                    m_result.p[2]      /=      sum;
+                    return(m_status);
+                }
+            }
+            /* Fallback                */
+            m_status   =       eEpaFallBack;
+            m_normal   =       -guess;
+            const btScalar     nl=m_normal.length();
+            if(nl>0)
+                m_normal       =       m_normal/nl;
+            else
+                m_normal       =       btVector3(1,0,0);
+            m_depth    =       0;
+            m_result.rank=1;
+            m_result.c[0]=simplex.c[0];
+            m_result.p[0]=1;
+            return(m_status);
+        }
+        bool getedgedist(sFace* face, typename GJK<btConvexTemplate>::sSV* a, typename GJK<btConvexTemplate>::sSV* b, btScalar& dist)
+        {
+            const btVector3 ba = b->w - a->w;
+            const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane
+            const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required
+            
+            if(a_dot_nab < 0)
+            {
+                // Outside of edge a->b
+                
+                const btScalar ba_l2 = ba.length2();
+                const btScalar a_dot_ba = btDot(a->w, ba);
+                const btScalar b_dot_ba = btDot(b->w, ba);
+                
+                if(a_dot_ba > 0)
+                {
+                    // Pick distance vertex a
+                    dist = a->w.length();
+                }
+                else if(b_dot_ba < 0)
+                {
+                    // Pick distance vertex b
+                    dist = b->w.length();
+                }
+                else
+                {
+                    // Pick distance to edge a->b
+                    const btScalar a_dot_b = btDot(a->w, b->w);
+                    dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0));
+                }
+                
+                return true;
+            }
+            
+            return false;
+        }
+        sFace*                         newface(typename GJK<btConvexTemplate>::sSV* a,typename GJK<btConvexTemplate>::sSV* b,typename GJK<btConvexTemplate>::sSV* c,bool forced)
+        {
+            if(m_stock.root)
+            {
+                sFace* face=m_stock.root;
+                remove(m_stock,face);
+                append(m_hull,face);
+                face->pass     =       0;
+                face->c[0]     =       a;
+                face->c[1]     =       b;
+                face->c[2]     =       c;
+                face->n                =       btCross(b->w-a->w,c->w-a->w);
+                const btScalar l=face->n.length();
+                const bool             v=l>EPA_ACCURACY;
+                
+                if(v)
+                {
+                    if(!(getedgedist(face, a, b, face->d) ||
+                         getedgedist(face, b, c, face->d) ||
+                         getedgedist(face, c, a, face->d)))
+                    {
+                        // Origin projects to the interior of the triangle
+                        // Use distance to triangle plane
+                        face->d = btDot(a->w, face->n) / l;
+                    }
+                    
+                    face->n /= l;
+                    if(forced || (face->d >= -EPA_PLANE_EPS))
+                    {
+                        return face;
+                    }
+                    else
+                        m_status=eEpaNonConvex;
+                }
+                else
+                    m_status=eEpaDegenerated;
+                
+                remove(m_hull, face);
+                append(m_stock, face);
+                return 0;
+                
+            }
+            m_status = m_stock.root ? eEpaOutOfVertices : eEpaOutOfFaces;
+            return 0;
+        }
+        sFace*                         findbest()
+        {
+            sFace*             minf=m_hull.root;
+            btScalar   mind=minf->d*minf->d;
+            for(sFace* f=minf->l[1];f;f=f->l[1])
+            {
+                const btScalar sqd=f->d*f->d;
+                if(sqd<mind)
+                {
+                    minf=f;
+                    mind=sqd;
+                }
+            }
+            return(minf);
+        }
+        bool                           expand(U pass,typename GJK<btConvexTemplate>::sSV* w,sFace* f,U e,sHorizon& horizon)
+        {
+            static const U     i1m3[]={1,2,0};
+            static const U     i2m3[]={2,0,1};
+            if(f->pass!=pass)
+            {
+                const U        e1=i1m3[e];
+                if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+                {
+                    sFace*     nf=newface(f->c[e1],f->c[e],w,false);
+                    if(nf)
+                    {
+                        bind(nf,0,f,e);
+                        if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
+                        horizon.cf=nf;
+                        ++horizon.nf;
+                        return(true);
+                    }
+                }
+                else
+                {
+                    const U    e2=i2m3[e];
+                    f->pass            =       (U1)pass;
+                    if(        expand(pass,w,f->f[e1],f->e[e1],horizon)&&
+                       expand(pass,w,f->f[e2],f->e[e2],horizon))
+                    {
+                        remove(m_hull,f);
+                        append(m_stock,f);
+                        return(true);
+                    }
+                }
+            }
+            return(false);
+        }
+        
+    };
+    
+    template <typename btConvexTemplate>
+    static void        Initialize(     const btConvexTemplate& a, const btConvexTemplate& b,
+                           btGjkEpaSolver3::sResults& results,
+                           MinkowskiDiff<btConvexTemplate>& shape)
+    {
+        /* Results             */ 
+        results.witnesses[0]   =
+        results.witnesses[1]   =       btVector3(0,0,0);
+        results.status                 =       btGjkEpaSolver3::sResults::Separated;
+        /* Shape               */ 
+       
+        shape.m_toshape1               =       b.getWorldTransform().getBasis().transposeTimes(a.getWorldTransform().getBasis());
+        shape.m_toshape0               =       a.getWorldTransform().inverseTimes(b.getWorldTransform());
+        
+    }
+    
+
+//
+// Api
+//
+
+
+
+//
+template <typename btConvexTemplate>
+bool           btGjkEpaSolver3_Distance(const btConvexTemplate& a, const btConvexTemplate& b,
+                                      const btVector3& guess,
+                                      btGjkEpaSolver3::sResults& results)
+{
+    MinkowskiDiff<btConvexTemplate>                    shape(a,b);
+    Initialize(a,b,results,shape);
+    GJK<btConvexTemplate>                              gjk(a,b);
+    eGjkStatus gjk_status=gjk.Evaluate(shape,guess);
+    if(gjk_status==eGjkValid)
+    {
+        btVector3      w0=btVector3(0,0,0);
+        btVector3      w1=btVector3(0,0,0);
+        for(U i=0;i<gjk.m_simplex->rank;++i)
+        {
+            const btScalar     p=gjk.m_simplex->p[i];
+            w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+            w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+        }
+        results.witnesses[0]   =       a.getWorldTransform()*w0;
+        results.witnesses[1]   =       a.getWorldTransform()*w1;
+        results.normal                 =       w0-w1;
+        results.distance               =       results.normal.length();
+        results.normal                 /=      results.distance>GJK_MIN_DISTANCE?results.distance:1;
+        return(true);
+    }
+    else
+    {
+        results.status =       gjk_status==eGjkInside?
+        btGjkEpaSolver3::sResults::Penetrating :
+        btGjkEpaSolver3::sResults::GJK_Failed  ;
+        return(false);
+    }
+}
+
+
+template <typename btConvexTemplate>
+bool   btGjkEpaSolver3_Penetration(const btConvexTemplate& a,
+                                     const btConvexTemplate& b,
+                                     const btVector3& guess,
+                                     btGjkEpaSolver3::sResults& results)
+{
+    MinkowskiDiff<btConvexTemplate>                    shape(a,b);
+    Initialize(a,b,results,shape);
+    GJK<btConvexTemplate>                              gjk(a,b);
+    eGjkStatus gjk_status=gjk.Evaluate(shape,-guess);
+    switch(gjk_status)
+    {
+        case   eGjkInside:
+        {
+            EPA<btConvexTemplate>                              epa;
+            eEpaStatus epa_status=epa.Evaluate(gjk,-guess);
+            if(epa_status!=eEpaFailed)
+            {
+                btVector3      w0=btVector3(0,0,0);
+                for(U i=0;i<epa.m_result.rank;++i)
+                {
+                    w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
+                }
+                results.status                 =       btGjkEpaSolver3::sResults::Penetrating;
+                results.witnesses[0]   =       a.getWorldTransform()*w0;
+                results.witnesses[1]   =       a.getWorldTransform()*(w0-epa.m_normal*epa.m_depth);
+                results.normal                 =       -epa.m_normal;
+                results.distance               =       -epa.m_depth;
+                return(true);
+            } else results.status=btGjkEpaSolver3::sResults::EPA_Failed;
+        }
+            break;
+        case   eGjkFailed:
+            results.status=btGjkEpaSolver3::sResults::GJK_Failed;
+            break;
+        default:
+        {
+        }
+    }
+    return(false);
+}
+
+#if 0
+int    btComputeGjkEpaPenetration2(const btCollisionDescription& colDesc, btDistanceInfo* distInfo)
+{
+    btGjkEpaSolver3::sResults results;
+    btVector3 guess = colDesc.m_firstDir;
+    
+    bool res = btGjkEpaSolver3::Penetration(colDesc.m_objA,colDesc.m_objB,
+                                            colDesc.m_transformA,colDesc.m_transformB,
+                                            colDesc.m_localSupportFuncA,colDesc.m_localSupportFuncB,
+                                            guess,
+                                            results);
+    if (res)
+    {
+        if ((results.status==btGjkEpaSolver3::sResults::Penetrating) || results.status==GJK::eStatus::Inside)
+        {
+            //normal could be 'swapped'
+            
+            distInfo->m_distance = results.distance;
+            distInfo->m_normalBtoA = results.normal;
+            btVector3 tmpNormalInB = results.witnesses[1]-results.witnesses[0];
+            btScalar lenSqr = tmpNormalInB.length2();
+            if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON))
+            {
+                tmpNormalInB = results.normal;
+                lenSqr = results.normal.length2();
+            }
+            
+            if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
+            {
+                tmpNormalInB /= btSqrt(lenSqr);
+                btScalar distance2 = -(results.witnesses[0]-results.witnesses[1]).length();
+                //only replace valid penetrations when the result is deeper (check)
+                //if ((distance2 < results.distance))
+                {
+                    distInfo->m_distance = distance2;
+                    distInfo->m_pointOnA= results.witnesses[0];
+                    distInfo->m_pointOnB= results.witnesses[1];
+                    distInfo->m_normalBtoA= tmpNormalInB;
+                    return 0;
+                }
+            }
+        }
+        
+    }
+    
+    return -1;
+}
+#endif
+
+template <typename btConvexTemplate, typename btDistanceInfoTemplate>
+int    btComputeGjkDistance(const btConvexTemplate& a, const btConvexTemplate& b,
+                         const btGjkCollisionDescription& colDesc, btDistanceInfoTemplate* distInfo)
+{
+    btGjkEpaSolver3::sResults results;
+    btVector3 guess = colDesc.m_firstDir;
+    
+    bool isSeparated = btGjkEpaSolver3_Distance(       a,b,
+                                                 guess,
+                                                 results);
+    if (isSeparated)
+    {
+        distInfo->m_distance = results.distance;
+        distInfo->m_pointOnA= results.witnesses[0];
+        distInfo->m_pointOnB= results.witnesses[1];
+        distInfo->m_normalBtoA= results.normal;
+        return 0;
+    }
+    
+    return -1;
+}
+
+/* Symbols cleanup             */ 
+
+#undef GJK_MAX_ITERATIONS
+#undef GJK_ACCURARY
+#undef GJK_MIN_DISTANCE
+#undef GJK_DUPLICATED_EPS
+#undef GJK_SIMPLEX2_EPS
+#undef GJK_SIMPLEX3_EPS
+#undef GJK_SIMPLEX4_EPS
+
+#undef EPA_MAX_VERTICES
+#undef EPA_MAX_FACES
+#undef EPA_MAX_ITERATIONS
+#undef EPA_ACCURACY
+#undef EPA_FALLBACK
+#undef EPA_PLANE_EPS
+#undef EPA_INSIDE_EPS
+
+
+
+#endif //BT_GJK_EPA3_H
+
index 8877579496b06698219918fed07e6a46cc4ed697..759443a9613fd99a2a91de47c7828dce0bb12dff 100644 (file)
@@ -26,7 +26,6 @@ subject to the following restrictions:
 #ifdef __SPU__
 #include <spu_printf.h>
 #define printf spu_printf
-//#define DEBUG_SPU_COLLISION_DETECTION 1
 #endif //__SPU__
 #endif
 
@@ -81,17 +80,18 @@ void        btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
 #ifdef __SPU__
 void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
 #else
-void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
+void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw)
 #endif
 {
        m_cachedSeparatingDistance = 0.f;
 
        btScalar distance=btScalar(0.);
        btVector3       normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
+
        btVector3 pointOnA,pointOnB;
        btTransform     localTransA = input.m_transformA;
        btTransform localTransB = input.m_transformB;
-       btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
+       btVector3 positionOffset=(localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
        localTransA.getOrigin() -= positionOffset;
        localTransB.getOrigin() -= positionOffset;
 
@@ -102,17 +102,11 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
 
        gNumGjkChecks++;
 
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-       spu_printf("inside gjk\n");
-#endif
        //for CCD we don't use margins
        if (m_ignoreMargin)
        {
                marginA = btScalar(0.);
                marginB = btScalar(0.);
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-               spu_printf("ignoring margin\n");
-#endif
        }
 
        m_curIter = 0;
@@ -143,37 +137,13 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                        btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
                        btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
 
-#if 1
-
-                       btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
-                       btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
-
-//                     btVector3 pInA  = localGetSupportingVertexWithoutMargin(m_shapeTypeA, m_minkowskiA, seperatingAxisInA,input.m_convexVertexData[0]);//, &featureIndexA);
-//                     btVector3 qInB  = localGetSupportingVertexWithoutMargin(m_shapeTypeB, m_minkowskiB, seperatingAxisInB,input.m_convexVertexData[1]);//, &featureIndexB);
 
-#else
-#ifdef __SPU__
                        btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
                        btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
-#else
-                       btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
-                       btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
-#ifdef TEST_NON_VIRTUAL
-                       btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
-                       btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
-                       btAssert((pInAv-pInA).length() < 0.0001);
-                       btAssert((qInBv-qInB).length() < 0.0001);
-#endif //
-#endif //__SPU__
-#endif
-
 
                        btVector3  pWorld = localTransA(pInA);  
                        btVector3  qWorld = localTransB(qInB);
 
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-               spu_printf("got local supporting vertices\n");
-#endif
 
                        if (check2d)
                        {
@@ -217,14 +187,8 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                                break;
                        }
 
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-               spu_printf("addVertex 1\n");
-#endif
                        //add current vertex to simplex
                        m_simplexSolver->addVertex(w, pWorld, qWorld);
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-               spu_printf("addVertex 2\n");
-#endif
                        btVector3 newCachedSeparatingAxis;
 
                        //calculate the closest point to the origin (update vector v)
@@ -274,7 +238,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                          //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject   
               if (m_curIter++ > gGjkMaxIter)   
               {   
-                      #if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION)
+                      #if defined(DEBUG) || defined (_DEBUG)
 
                               printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);   
                               printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n",   
@@ -307,6 +271,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                {
                        m_simplexSolver->compute_points(pointOnA, pointOnB);
                        normalInB = m_cachedSeparatingAxis;
+
                        btScalar lenSqr =m_cachedSeparatingAxis.length2();
                        
                        //valid normal
@@ -318,6 +283,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                        {
                                btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
                                normalInB *= rlen; //normalize
+
                                btScalar s = btSqrt(squaredDistance);
                        
                                btAssert(s > btScalar(0.0));
@@ -373,6 +339,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                                        {
                                                tmpNormalInB /= btSqrt(lenSqr);
                                                btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
+                                               m_lastUsedMethod = 3;
                                                //only replace valid penetrations when the result is deeper (check)
                                                if (!isValid || (distance2 < distance))
                                                {
@@ -380,8 +347,48 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                                                        pointOnA = tmpPointOnA;
                                                        pointOnB = tmpPointOnB;
                                                        normalInB = tmpNormalInB;
+                                                       ///todo: need to track down this EPA penetration solver degeneracy
+                                                       ///the penetration solver reports penetration but the contact normal
+                                                       ///connecting the contact points is pointing in the opposite direction
+                                                       ///until then, detect the issue and revert the normal
+                                                       {
+                                                               btScalar d1=0;
+                                                               {
+                                                                       btVector3 seperatingAxisInA = (normalInB)* input.m_transformA.getBasis();
+                                                                       btVector3 seperatingAxisInB = -normalInB* input.m_transformB.getBasis();
+                                                               
+
+                                                                       btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+                                                                       btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+
+                                                                       btVector3  pWorld = localTransA(pInA);  
+                                                                       btVector3  qWorld = localTransB(qInB);
+                                                                       btVector3 w     = pWorld - qWorld;
+                                                                       d1 = (-normalInB).dot(w);
+                                                               }
+                                                               btScalar d0 = 0.f;
+                                                               {
+                                                                       btVector3 seperatingAxisInA = (-normalInB)* input.m_transformA.getBasis();
+                                                                       btVector3 seperatingAxisInB = normalInB* input.m_transformB.getBasis();
+                                                               
+
+                                                                       btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+                                                                       btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+
+                                                                       btVector3  pWorld = localTransA(pInA);  
+                                                                       btVector3  qWorld = localTransB(qInB);
+                                                                       btVector3 w     = pWorld - qWorld;
+                                                                       d0 = normalInB.dot(w);
+                                                               }
+                                                               if (d1>d0)
+                                                               {
+                                                                       m_lastUsedMethod = 10;
+                                                                       normalInB*=-1;
+                                                               } 
+
+                                                       }
                                                        isValid = true;
-                                                       m_lastUsedMethod = 3;
+                                                       
                                                } else
                                                {
                                                        m_lastUsedMethod = 8;
@@ -413,6 +420,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
                                                        pointOnB += m_cachedSeparatingAxis * marginB ;
                                                        normalInB = m_cachedSeparatingAxis;
                                                        normalInB.normalize();
+
                                                        isValid = true;
                                                        m_lastUsedMethod = 6;
                                                } else
@@ -431,36 +439,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
 
        if (isValid && ((distance < 0) || (distance*distance < input.m_maximumDistanceSquared)))
        {
-#if 0
-///some debugging
-//             if (check2d)
-               {
-                       printf("n = %2.3f,%2.3f,%2.3f. ",normalInB[0],normalInB[1],normalInB[2]);
-                       printf("distance = %2.3f exit=%d deg=%d\n",distance,m_lastUsedMethod,m_degenerateSimplex);
-               }
-#endif 
 
-               if (m_fixContactNormalDirection)
-               {
-                       ///@workaround for sticky convex collisions
-                       //in some degenerate cases (usually when the use uses very small margins) 
-                       //the contact normal is pointing the wrong direction
-                       //so fix it now (until we can deal with all degenerate cases in GJK and EPA)
-                       //contact normals need to point from B to A in all cases, so we can simply check if the contact normal really points from B to A
-                       //We like to use a dot product of the normal against the difference of the centroids, 
-                       //once the centroid is available in the API
-                       //until then we use the center of the aabb to approximate the centroid
-                       btVector3 aabbMin,aabbMax;
-                       m_minkowskiA->getAabb(localTransA,aabbMin,aabbMax);
-                       btVector3 posA  = (aabbMax+aabbMin)*btScalar(0.5);
-               
-                       m_minkowskiB->getAabb(localTransB,aabbMin,aabbMax);
-                       btVector3 posB = (aabbMin+aabbMax)*btScalar(0.5);
-
-                       btVector3 diff = posA-posB;
-                       if (diff.dot(normalInB) < 0.f)
-                               normalInB *= -1.f;
-               }
                m_cachedSeparatingAxis = normalInB;
                m_cachedSeparatingDistance = distance;
 
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h
new file mode 100644 (file)
index 0000000..a22a0ba
--- /dev/null
@@ -0,0 +1,908 @@
+
+/***
+ * ---------------------------------
+ * Copyright (c)2012 Daniel Fiser <danfis@danfis.cz>
+ *
+ *  This file was ported from mpr.c file, part of libccd.
+ *  The Minkoski Portal Refinement implementation was ported 
+ *  to OpenCL by Erwin Coumans for the Bullet 3 Physics library.
+ *  The original MPR idea and implementation is by Gary Snethen
+ *  in XenoCollide, see http://github.com/erwincoumans/xenocollide
+ *
+ *  Distributed under the OSI-approved BSD License (the "License");
+ *  see <http://www.opensource.org/licenses/bsd-license.php>.
+ *  This software is distributed WITHOUT ANY WARRANTY; without even the
+ *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *  See the License for more information.
+ */
+
+///2014 Oct, Erwin Coumans, Use templates to avoid void* casts
+
+#ifndef BT_MPR_PENETRATION_H
+#define BT_MPR_PENETRATION_H
+
+#define BT_DEBUG_MPR1
+
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+//#define MPR_AVERAGE_CONTACT_POSITIONS
+
+
+struct btMprCollisionDescription
+{
+    btVector3  m_firstDir;
+    int                        m_maxGjkIterations;
+    btScalar   m_maximumDistanceSquared;
+    btScalar   m_gjkRelError2;
+   
+    btMprCollisionDescription()
+    :  m_firstDir(0,1,0),
+        m_maxGjkIterations(1000),
+        m_maximumDistanceSquared(1e30f),
+        m_gjkRelError2(1.0e-6)
+    {
+    }
+    virtual ~btMprCollisionDescription()
+    {
+    }
+};
+
+struct btMprDistanceInfo
+{
+    btVector3  m_pointOnA;
+    btVector3  m_pointOnB;
+    btVector3  m_normalBtoA;
+    btScalar   m_distance;
+};
+
+#ifdef __cplusplus
+#define BT_MPR_SQRT sqrtf
+#else
+#define BT_MPR_SQRT sqrt
+#endif
+#define BT_MPR_FMIN(x, y) ((x) < (y) ? (x) : (y))
+#define BT_MPR_FABS fabs
+
+#define BT_MPR_TOLERANCE 1E-6f
+#define BT_MPR_MAX_ITERATIONS 1000
+
+struct _btMprSupport_t 
+{
+    btVector3 v;  //!< Support point in minkowski sum
+    btVector3 v1; //!< Support point in obj1
+    btVector3 v2; //!< Support point in obj2
+};
+typedef struct _btMprSupport_t btMprSupport_t;
+
+struct _btMprSimplex_t 
+{
+    btMprSupport_t ps[4];
+    int last; //!< index of last added point
+};
+typedef struct _btMprSimplex_t btMprSimplex_t;
+
+inline btMprSupport_t* btMprSimplexPointW(btMprSimplex_t *s, int idx)
+{
+    return &s->ps[idx];
+}
+
+inline void btMprSimplexSetSize(btMprSimplex_t *s, int size)
+{
+    s->last = size - 1;
+}
+
+#ifdef DEBUG_MPR
+inline void btPrintPortalVertex(_btMprSimplex_t* portal, int index)
+{
+    printf("portal[%d].v = %f,%f,%f, v1=%f,%f,%f, v2=%f,%f,%f\n", index, portal->ps[index].v.x(),portal->ps[index].v.y(),portal->ps[index].v.z(),
+           portal->ps[index].v1.x(),portal->ps[index].v1.y(),portal->ps[index].v1.z(),
+           portal->ps[index].v2.x(),portal->ps[index].v2.y(),portal->ps[index].v2.z());
+}
+#endif //DEBUG_MPR
+
+
+
+
+inline int btMprSimplexSize(const btMprSimplex_t *s)
+{
+    return s->last + 1;
+}
+
+
+inline const btMprSupport_t* btMprSimplexPoint(const btMprSimplex_t* s, int idx)
+{
+    // here is no check on boundaries
+    return &s->ps[idx];
+}
+
+inline void btMprSupportCopy(btMprSupport_t *d, const btMprSupport_t *s)
+{
+    *d = *s;
+}
+
+inline void btMprSimplexSet(btMprSimplex_t *s, size_t pos, const btMprSupport_t *a)
+{
+    btMprSupportCopy(s->ps + pos, a);
+}
+
+
+inline void btMprSimplexSwap(btMprSimplex_t *s, size_t pos1, size_t pos2)
+{
+    btMprSupport_t supp;
+
+    btMprSupportCopy(&supp, &s->ps[pos1]);
+    btMprSupportCopy(&s->ps[pos1], &s->ps[pos2]);
+    btMprSupportCopy(&s->ps[pos2], &supp);
+}
+
+
+inline int btMprIsZero(float val)
+{
+    return BT_MPR_FABS(val) < FLT_EPSILON;
+}
+
+
+
+inline int btMprEq(float _a, float _b)
+{
+    float ab;
+    float a, b;
+
+    ab = BT_MPR_FABS(_a - _b);
+    if (BT_MPR_FABS(ab) < FLT_EPSILON)
+        return 1;
+
+    a = BT_MPR_FABS(_a);
+    b = BT_MPR_FABS(_b);
+    if (b > a){
+        return ab < FLT_EPSILON * b;
+    }else{
+        return ab < FLT_EPSILON * a;
+    }
+}
+
+
+inline int btMprVec3Eq(const btVector3* a, const btVector3 *b)
+{
+    return btMprEq((*a).x(), (*b).x())
+            && btMprEq((*a).y(), (*b).y())
+            && btMprEq((*a).z(), (*b).z());
+}
+
+
+
+
+
+
+
+
+
+
+
+template <typename btConvexTemplate>
+inline void btFindOrigin(const btConvexTemplate& a, const btConvexTemplate& b, const btMprCollisionDescription& colDesc,btMprSupport_t *center)
+{
+
+       center->v1 = a.getObjectCenterInWorld();
+    center->v2 = b.getObjectCenterInWorld();
+    center->v = center->v1 - center->v2;
+}
+
+inline void btMprVec3Set(btVector3 *v, float x, float y, float z)
+{
+       v->setValue(x,y,z);
+}
+
+inline void btMprVec3Add(btVector3 *v, const btVector3 *w)
+{
+       *v += *w;
+}
+
+inline void btMprVec3Copy(btVector3 *v, const btVector3 *w)
+{
+    *v = *w;
+}
+
+inline void btMprVec3Scale(btVector3 *d, float k)
+{
+    *d *= k;
+}
+
+inline float btMprVec3Dot(const btVector3 *a, const btVector3 *b)
+{
+    float dot;
+
+       dot = btDot(*a,*b);
+    return dot;
+}
+
+
+inline float btMprVec3Len2(const btVector3 *v)
+{
+    return btMprVec3Dot(v, v);
+}
+
+inline void btMprVec3Normalize(btVector3 *d)
+{
+    float k = 1.f / BT_MPR_SQRT(btMprVec3Len2(d));
+    btMprVec3Scale(d, k);
+}
+
+inline void btMprVec3Cross(btVector3 *d, const btVector3 *a, const btVector3 *b)
+{
+       *d = btCross(*a,*b);
+       
+}
+
+
+inline void btMprVec3Sub2(btVector3 *d, const btVector3 *v, const btVector3 *w)
+{
+       *d = *v - *w;
+}
+
+inline void btPortalDir(const btMprSimplex_t *portal, btVector3 *dir)
+{
+    btVector3 v2v1, v3v1;
+
+    btMprVec3Sub2(&v2v1, &btMprSimplexPoint(portal, 2)->v,
+                       &btMprSimplexPoint(portal, 1)->v);
+    btMprVec3Sub2(&v3v1, &btMprSimplexPoint(portal, 3)->v,
+                       &btMprSimplexPoint(portal, 1)->v);
+    btMprVec3Cross(dir, &v2v1, &v3v1);
+    btMprVec3Normalize(dir);
+}
+
+
+inline int portalEncapsulesOrigin(const btMprSimplex_t *portal,
+                                       const btVector3 *dir)
+{
+    float dot;
+    dot = btMprVec3Dot(dir, &btMprSimplexPoint(portal, 1)->v);
+    return btMprIsZero(dot) || dot > 0.f;
+}
+
+inline int portalReachTolerance(const btMprSimplex_t *portal,
+                                     const btMprSupport_t *v4,
+                                     const btVector3 *dir)
+{
+    float dv1, dv2, dv3, dv4;
+    float dot1, dot2, dot3;
+
+    // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4}
+
+    dv1 = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, dir);
+    dv2 = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, dir);
+    dv3 = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, dir);
+    dv4 = btMprVec3Dot(&v4->v, dir);
+
+    dot1 = dv4 - dv1;
+    dot2 = dv4 - dv2;
+    dot3 = dv4 - dv3;
+
+    dot1 = BT_MPR_FMIN(dot1, dot2);
+    dot1 = BT_MPR_FMIN(dot1, dot3);
+
+    return btMprEq(dot1, BT_MPR_TOLERANCE) || dot1 < BT_MPR_TOLERANCE;
+}
+
+inline int portalCanEncapsuleOrigin(const btMprSimplex_t *portal,
+                                         const btMprSupport_t *v4,
+                                         const btVector3 *dir)
+{
+    float dot;
+    dot = btMprVec3Dot(&v4->v, dir);
+    return btMprIsZero(dot) || dot > 0.f;
+}
+
+inline void btExpandPortal(btMprSimplex_t *portal,
+                              const btMprSupport_t *v4)
+{
+    float dot;
+    btVector3 v4v0;
+
+    btMprVec3Cross(&v4v0, &v4->v, &btMprSimplexPoint(portal, 0)->v);
+    dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &v4v0);
+    if (dot > 0.f){
+        dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &v4v0);
+        if (dot > 0.f){
+            btMprSimplexSet(portal, 1, v4);
+        }else{
+            btMprSimplexSet(portal, 3, v4);
+        }
+    }else{
+        dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &v4v0);
+        if (dot > 0.f){
+            btMprSimplexSet(portal, 2, v4);
+        }else{
+            btMprSimplexSet(portal, 1, v4);
+        }
+    }
+}
+template <typename btConvexTemplate>
+inline void btMprSupport(const btConvexTemplate& a, const btConvexTemplate& b,
+                         const btMprCollisionDescription& colDesc,
+                                                                                                       const btVector3& dir, btMprSupport_t *supp)
+{
+       btVector3 seperatingAxisInA = dir* a.getWorldTransform().getBasis();
+       btVector3 seperatingAxisInB = -dir* b.getWorldTransform().getBasis();
+
+       btVector3 pInA = a.getLocalSupportWithMargin(seperatingAxisInA);
+       btVector3 qInB = b.getLocalSupportWithMargin(seperatingAxisInB);
+
+       supp->v1 = a.getWorldTransform()(pInA);
+       supp->v2 = b.getWorldTransform()(qInB);
+       supp->v = supp->v1 - supp->v2;
+}
+
+
+template <typename btConvexTemplate>
+static int btDiscoverPortal(const btConvexTemplate& a, const btConvexTemplate& b,
+                            const btMprCollisionDescription& colDesc,
+                                                                                                       btMprSimplex_t *portal)
+{
+    btVector3 dir, va, vb;
+    float dot;
+    int cont;
+       
+       
+
+    // vertex 0 is center of portal
+    btFindOrigin(a,b,colDesc, btMprSimplexPointW(portal, 0));
+   
+    
+    // vertex 0 is center of portal
+    btMprSimplexSetSize(portal, 1);
+    
+
+
+       btVector3 zero = btVector3(0,0,0);
+       btVector3* org = &zero;
+
+    if (btMprVec3Eq(&btMprSimplexPoint(portal, 0)->v, org)){
+        // Portal's center lies on origin (0,0,0) => we know that objects
+        // intersect but we would need to know penetration info.
+        // So move center little bit...
+        btMprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f);
+        btMprVec3Add(&btMprSimplexPointW(portal, 0)->v, &va);
+    }
+
+
+    // vertex 1 = support in direction of origin
+    btMprVec3Copy(&dir, &btMprSimplexPoint(portal, 0)->v);
+    btMprVec3Scale(&dir, -1.f);
+    btMprVec3Normalize(&dir);
+
+
+    btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 1));
+    btMprSimplexSetSize(portal, 2);
+
+    // test if origin isn't outside of v1
+    dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &dir);
+       
+
+    if (btMprIsZero(dot) || dot < 0.f)
+        return -1;
+
+
+    // vertex 2
+    btMprVec3Cross(&dir, &btMprSimplexPoint(portal, 0)->v,
+                       &btMprSimplexPoint(portal, 1)->v);
+    if (btMprIsZero(btMprVec3Len2(&dir))){
+        if (btMprVec3Eq(&btMprSimplexPoint(portal, 1)->v, org)){
+            // origin lies on v1
+            return 1;
+        }else{
+            // origin lies on v0-v1 segment
+            return 2;
+        }
+    }
+
+    btMprVec3Normalize(&dir);
+    btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 2));
+    
+    
+    
+    dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &dir);
+    if (btMprIsZero(dot) || dot < 0.f)
+        return -1;
+
+    btMprSimplexSetSize(portal, 3);
+
+    // vertex 3 direction
+    btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v,
+                     &btMprSimplexPoint(portal, 0)->v);
+    btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v,
+                     &btMprSimplexPoint(portal, 0)->v);
+    btMprVec3Cross(&dir, &va, &vb);
+    btMprVec3Normalize(&dir);
+
+    // it is better to form portal faces to be oriented "outside" origin
+    dot = btMprVec3Dot(&dir, &btMprSimplexPoint(portal, 0)->v);
+    if (dot > 0.f){
+        btMprSimplexSwap(portal, 1, 2);
+        btMprVec3Scale(&dir, -1.f);
+    }
+
+    while (btMprSimplexSize(portal) < 4){
+                btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 3));
+        
+        dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &dir);
+        if (btMprIsZero(dot) || dot < 0.f)
+            return -1;
+
+        cont = 0;
+
+        // test if origin is outside (v1, v0, v3) - set v2 as v3 and
+        // continue
+        btMprVec3Cross(&va, &btMprSimplexPoint(portal, 1)->v,
+                          &btMprSimplexPoint(portal, 3)->v);
+        dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v);
+        if (dot < 0.f && !btMprIsZero(dot)){
+            btMprSimplexSet(portal, 2, btMprSimplexPoint(portal, 3));
+      &