Upgraded to Bullet 2.74. The upgrade introduced a few bugs, which need to be fixed...
authorErwin Coumans <blender@erwincoumans.com>
Tue, 3 Mar 2009 03:41:24 +0000 (03:41 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Tue, 3 Mar 2009 03:41:24 +0000 (03:41 +0000)
In particular, the Bullet vehicle seems broken, and some soft-body demos don't work.
No new features or benefits are added yet, but a few improvements are planned before Blender 2.49 release.

Please update the build systems, and add those 3 files:
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp

I'll watch the Blender mailing list, in case this commit causes some issues.

229 files changed:
extern/bullet2/src/Bullet-C-Api.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
extern/bullet2/src/BulletCollision/CMakeLists.txt
extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.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/btCompoundCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h
extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp
extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h
extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h
extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h
extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h
extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h
extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp
extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h
extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h
extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h
extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h
extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h
extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h
extern/bullet2/src/BulletCollision/Gimpact/gim_math.h
extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h
extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h
extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp
extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
extern/bullet2/src/BulletDynamics/CMakeLists.txt
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
extern/bullet2/src/BulletSoftBody/CMakeLists.txt
extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
extern/bullet2/src/BulletSoftBody/btSoftBody.h
extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
extern/bullet2/src/BulletSoftBody/btSparseSDF.h
extern/bullet2/src/LinearMath/CMakeLists.txt
extern/bullet2/src/LinearMath/btAabbUtil2.h
extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
extern/bullet2/src/LinearMath/btAlignedAllocator.h
extern/bullet2/src/LinearMath/btAlignedObjectArray.h
extern/bullet2/src/LinearMath/btConvexHull.cpp
extern/bullet2/src/LinearMath/btConvexHull.h
extern/bullet2/src/LinearMath/btIDebugDraw.h
extern/bullet2/src/LinearMath/btMatrix3x3.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/btStackAlloc.h
extern/bullet2/src/LinearMath/btTransform.h
extern/bullet2/src/LinearMath/btTransformUtil.h
extern/bullet2/src/LinearMath/btVector3.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

index 8074aed..a4a8a70 100644 (file)
@@ -38,37 +38,37 @@ typedef plReal      plQuaternion[4];
 extern "C" { 
 #endif
 
-/*     Particular physics SDK */
+/**    Particular physics SDK (C-API) */
        PL_DECLARE_HANDLE(plPhysicsSdkHandle);
 
-/*     Dynamics world, belonging to some physics SDK */
+/**    Dynamics world, belonging to some physics SDK (C-API)*/
        PL_DECLARE_HANDLE(plDynamicsWorldHandle);
 
-/* Rigid Body that can be part of a Dynamics World */  
+/** Rigid Body that can be part of a Dynamics World (C-API)*/  
        PL_DECLARE_HANDLE(plRigidBodyHandle);
 
-/*     Collision Shape/Geometry, property of a Rigid Body */
+/**    Collision Shape/Geometry, property of a Rigid Body (C-API)*/
        PL_DECLARE_HANDLE(plCollisionShapeHandle);
 
-/* Constraint for Rigid Bodies */
+/** Constraint for Rigid Bodies (C-API)*/
        PL_DECLARE_HANDLE(plConstraintHandle);
 
-/* Triangle Mesh interface */
+/** Triangle Mesh interface (C-API)*/
        PL_DECLARE_HANDLE(plMeshInterfaceHandle);
 
-/* Broadphase Scene/Proxy Handles */
+/** Broadphase Scene/Proxy Handles (C-API)*/
        PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
        PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
        PL_DECLARE_HANDLE(plCollisionWorldHandle);
 
-/*
+/**
        Create and Delete a Physics SDK 
 */
 
        extern  plPhysicsSdkHandle      plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
        extern  void            plDeletePhysicsSdk(plPhysicsSdkHandle   physicsSdk);
 
-/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
+/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
 
        typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
 
index d7eea33..7776330 100644 (file)
 // 3. This notice may not be removed or altered from any source distribution.
 #include "btAxisSweep3.h"
 
-#include <assert.h>
 
-btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
-:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
+btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
 {
        // 1 handle is reserved as sentinel
        btAssert(maxHandles > 1 && maxHandles < 32767);
@@ -30,8 +29,8 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
 }
 
 
-bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
-:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
+bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
 {
        // 1 handle is reserved as sentinel
        btAssert(maxHandles > 1 && maxHandles < 2147483647);
index d0ad09a..cad21b4 100644 (file)
 #ifndef AXIS_SWEEP_3_H
 #define AXIS_SWEEP_3_H
 
-#include "LinearMath/btPoint3.h"
 #include "LinearMath/btVector3.h"
 #include "btOverlappingPairCache.h"
 #include "btBroadphaseInterface.h"
 #include "btBroadphaseProxy.h"
 #include "btOverlappingPairCallback.h"
+#include "btDbvtBroadphase.h"
 
 //#define DEBUG_BROADPHASE 1
 #define USE_OVERLAP_TEST_ON_REMOVES 1
@@ -42,6 +42,7 @@ protected:
 
 public:
        
+ BT_DECLARE_ALIGNED_ALLOCATOR();
 
        class Edge
        {
@@ -61,8 +62,7 @@ public:
                // indexes into the edge arrays
                BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3];            // 6 * 2 = 12
 //             BP_FP_INT_TYPE m_uniqueId;
-               BP_FP_INT_TYPE m_pad;
-               
+               btBroadphaseProxy*      m_dbvtProxy;//for faster raycast
                //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
        
                SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
@@ -71,8 +71,8 @@ public:
 
        
 protected:
-       btPoint3 m_worldAabbMin;                                                // overall system bounds
-       btPoint3 m_worldAabbMax;                                                // overall system bounds
+       btVector3 m_worldAabbMin;                                               // overall system bounds
+       btVector3 m_worldAabbMax;                                               // overall system bounds
 
        btVector3 m_quantize;                                           // scaling factor for quantization
 
@@ -94,6 +94,12 @@ protected:
 
        int     m_invalidPair;
 
+       ///additional dynamic aabb structure, used to accelerate ray cast queries.
+       ///can be disabled using a optional argument in the constructor
+       btDbvtBroadphase*       m_raycastAccelerator;
+       btOverlappingPairCache* m_nullPairCache;
+
+
        // allocation/deallocation
        BP_FP_INT_TYPE allocHandle();
        void freeHandle(BP_FP_INT_TYPE handle);
@@ -108,7 +114,7 @@ protected:
        //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
        //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
 
-       void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
+       
 
        void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
        void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
@@ -117,7 +123,7 @@ protected:
 
 public:
 
-       btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);
+       btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
 
        virtual ~btAxisSweep3Internal();
 
@@ -128,17 +134,26 @@ public:
 
        virtual void    calculateOverlappingPairs(btDispatcher* dispatcher);
        
-       BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+       BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
        void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
-       void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
+       void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
        SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
 
+       virtual void resetPool(btDispatcher* dispatcher);
+
        void    processAllOverlappingPairs(btOverlapCallback* callback);
 
        //Broadphase Interface
        virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
        virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
        virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+       virtual void  getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+       
+       virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+       
+       void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
+       ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
+       void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
        
        bool    testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
 
@@ -206,7 +221,7 @@ void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinalit
        }
 
        if (checkCardinality)
-               assert(numEdges == m_numHandles*2+1);
+               btAssert(numEdges == m_numHandles*2+1);
 }
 #endif //DEBUG_BROADPHASE
 
@@ -217,7 +232,12 @@ btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy(  const btV
                BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
                
                Handle* handle = getHandle(handleId);
-                               
+               
+               if (m_raycastAccelerator)
+               {
+                       btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
+                       handle->m_dbvtProxy = rayProxy;
+               }
                return handle;
 }
 
@@ -227,6 +247,8 @@ template <typename BP_FP_INT_TYPE>
 void   btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
 {
        Handle* handle = static_cast<Handle*>(proxy);
+       if (m_raycastAccelerator)
+               m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
        removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
 }
 
@@ -234,22 +256,80 @@ template <typename BP_FP_INT_TYPE>
 void   btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
 {
        Handle* handle = static_cast<Handle*>(proxy);
+       handle->m_aabbMin = aabbMin;
+       handle->m_aabbMax = aabbMax;
        updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
+       if (m_raycastAccelerator)
+               m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
+
+}
+
+template <typename BP_FP_INT_TYPE>
+void   btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+       if (m_raycastAccelerator)
+       {
+               m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
+       } else
+       {
+               //choose axis?
+               BP_FP_INT_TYPE axis = 0;
+               //for each proxy
+               for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
+               {
+                       if (m_pEdges[axis][i].IsMax())
+                       {
+                               rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
+                       }
+               }
+       }
+}
+
 
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+       Handle* pHandle = static_cast<Handle*>(proxy);
+       aabbMin = pHandle->m_aabbMin;
+       aabbMax = pHandle->m_aabbMax;
 }
 
 
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+       Handle* pHandle = static_cast<Handle*>(proxy);
+
+       unsigned short vecInMin[3];
+       unsigned short vecInMax[3];
+
+       vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
+       vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
+       vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
+       vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
+       vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
+       vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
+       
+       aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
+       aabbMin += m_worldAabbMin;
+       
+       aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
+       aabbMax += m_worldAabbMin;
+}
+
 
 
 
 template <typename BP_FP_INT_TYPE>
-btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache )
+btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
 :m_bpHandleMask(handleMask),
 m_handleSentinel(handleSentinel),
 m_pairCache(pairCache),
 m_userPairCallback(0),
 m_ownsPairCache(false),
-m_invalidPair(0)
+m_invalidPair(0),
+m_raycastAccelerator(0)
 {
        BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
 
@@ -260,7 +340,14 @@ m_invalidPair(0)
                m_ownsPairCache = true;
        }
 
-       //assert(bounds.HasVolume());
+       if (!disableRaycastAccelerator)
+       {
+               m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache();
+               m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache);
+               m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
+       }
+
+       //btAssert(bounds.HasVolume());
 
        // init bounds
        m_worldAabbMin = worldAabbMin;
@@ -320,7 +407,14 @@ m_invalidPair(0)
 template <typename BP_FP_INT_TYPE>
 btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
 {
-       
+       if (m_raycastAccelerator)
+       {
+               m_nullPairCache->~btOverlappingPairCache();
+               btAlignedFree(m_nullPairCache);
+               m_raycastAccelerator->~btDbvtBroadphase();
+               btAlignedFree (m_raycastAccelerator);
+       }
+
        for (int i = 2; i >= 0; i--)
        {
                btAlignedFree(m_pEdgesRawPtr[i]);
@@ -335,27 +429,31 @@ btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
 }
 
 template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
 {
-       btPoint3 clampedPoint(point);
-       
-
-
+#ifdef OLD_CLAMPING_METHOD
+       ///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
+       ///see http://code.google.com/p/bullet/issues/detail?id=87
+       btVector3 clampedPoint(point);
        clampedPoint.setMax(m_worldAabbMin);
        clampedPoint.setMin(m_worldAabbMax);
-
        btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
        out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
        out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
        out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
-       
+#else
+       btVector3 v = (point - m_worldAabbMin) * m_quantize;
+       out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax);
+       out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax);
+       out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax);
+#endif //OLD_CLAMPING_METHOD
 }
 
 
 template <typename BP_FP_INT_TYPE>
 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
 {
-       assert(m_firstFreeHandle);
+       btAssert(m_firstFreeHandle);
 
        BP_FP_INT_TYPE handle = m_firstFreeHandle;
        m_firstFreeHandle = getHandle(handle)->GetNextFree();
@@ -367,7 +465,7 @@ BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
 template <typename BP_FP_INT_TYPE>
 void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
 {
-       assert(handle > 0 && handle < m_maxHandles);
+       btAssert(handle > 0 && handle < m_maxHandles);
 
        getHandle(handle)->SetNextFree(m_firstFreeHandle);
        m_firstFreeHandle = handle;
@@ -377,7 +475,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
 
 
 template <typename BP_FP_INT_TYPE>
-BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
 {
        // quantize the bounds
        BP_FP_INT_TYPE min[3], max[3];
@@ -440,7 +538,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
 
        //explicitly remove the pairs containing the proxy
        //we could do it also in the sortMinUp (passing true)
-       //todo: compare performance
+       ///@todo: compare performance
        if (!m_pairCache->hasDeferredRemoval())
        {
                m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
@@ -489,6 +587,21 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
        
 }
 
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
+{
+       if (m_numHandles == 0)
+       {
+               m_firstFreeHandle = 1;
+               {
+                       for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
+                               m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
+                       m_pHandles[m_maxHandles - 1].SetNextFree(0);
+               }
+       }
+}       
+
+
 extern int gOverlappingPairs;
 //#include <stdio.h>
 
@@ -529,6 +642,7 @@ void        btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
 
                        if (!isDuplicate)
                        {
+                               ///important to use an AABB test that is consistent with the broadphase
                                bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
 
                                if (hasOverlap)
@@ -574,10 +688,6 @@ void       btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
                //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
        }
 
-
-
-       
-
 }
 
 
@@ -616,10 +726,10 @@ bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA,
 }
 
 template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
 {
-//     assert(bounds.IsFinite());
-       //assert(bounds.HasVolume());
+//     btAssert(bounds.IsFinite());
+       //btAssert(bounds.HasVolume());
 
        Handle* pHandle = getHandle(handle);
 
@@ -895,7 +1005,7 @@ class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
 {
 public:
 
-       btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
+       btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
 
 };
 
@@ -906,7 +1016,7 @@ class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
 {
 public:
 
-       bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
+       bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
 
 };
 
index 200ac36..b7bbaf5 100644 (file)
@@ -21,8 +21,22 @@ subject to the following restrictions:
 struct btDispatcherInfo;
 class btDispatcher;
 #include "btBroadphaseProxy.h"
+
 class btOverlappingPairCache;
 
+
+
+struct btBroadphaseRayCallback
+{
+       ///added some cached data to accelerate ray-AABB tests
+       btVector3               m_rayDirectionInverse;
+       unsigned int    m_signs[3];
+       btScalar                m_lambda_max;
+
+       virtual ~btBroadphaseRayCallback() {}
+       virtual bool    process(const btBroadphaseProxy* proxy) = 0;
+};
+
 #include "LinearMath/btVector3.h"
 
 ///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
@@ -36,7 +50,10 @@ public:
        virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
        virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
        virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
-       
+       virtual void    getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
+
+       virtual void    rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
+
        ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
        virtual void    calculateOverlappingPairs(btDispatcher* dispatcher)=0;
 
@@ -47,6 +64,9 @@ public:
        ///will add some transform later
        virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
 
+       ///reset broadphase internal structures, to ensure determinism/reproducability
+       virtual void resetPool(btDispatcher* dispatcher) {};
+
        virtual void    printStats() = 0;
 
 };
index a074a0b..be261ec 100644 (file)
@@ -17,20 +17,24 @@ subject to the following restrictions:
 #define BROADPHASE_PROXY_H
 
 #include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btVector3.h"
 #include "LinearMath/btAlignedAllocator.h"
 
 
 /// btDispatcher uses these types
 /// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
 /// to facilitate type checking
+/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
 enum BroadphaseNativeTypes
 {
-// polyhedral convex shapes
+       // polyhedral convex shapes
        BOX_SHAPE_PROXYTYPE,
        TRIANGLE_SHAPE_PROXYTYPE,
        TETRAHEDRAL_SHAPE_PROXYTYPE,
        CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
        CONVEX_HULL_SHAPE_PROXYTYPE,
+       CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
+       CUSTOM_POLYHEDRAL_SHAPE_TYPE,
 //implicit convex shapes
 IMPLICIT_CONVEX_SHAPES_START_HERE,
        SPHERE_SHAPE_PROXYTYPE,
@@ -42,6 +46,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
        UNIFORM_SCALING_SHAPE_PROXYTYPE,
        MINKOWSKI_SUM_SHAPE_PROXYTYPE,
        MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+       CUSTOM_CONVEX_SHAPE_TYPE,
 //concave shapes
 CONCAVE_SHAPES_START_HERE,
        //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
@@ -58,13 +63,18 @@ CONCAVE_SHAPES_START_HERE,
        
        EMPTY_SHAPE_PROXYTYPE,
        STATIC_PLANE_PROXYTYPE,
+       CUSTOM_CONCAVE_SHAPE_TYPE,
 CONCAVE_SHAPES_END_HERE,
 
        COMPOUND_SHAPE_PROXYTYPE,
 
        SOFTBODY_SHAPE_PROXYTYPE,
+       HFFLUID_SHAPE_PROXYTYPE,
+       HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
+       INVALID_SHAPE_PROXYTYPE,
 
        MAX_BROADPHASE_COLLISION_TYPES
+       
 };
 
 
@@ -83,20 +93,20 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
                KinematicFilter = 4,
                DebrisFilter = 8,
                        SensorTrigger = 16,
+                       CharacterFilter = 32,
                AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
        };
 
        //Usually the client btCollisionObject or Rigidbody class
        void*   m_clientObject;
-
        short int m_collisionFilterGroup;
        short int m_collisionFilterMask;
-
        void*   m_multiSapParentProxy;          
-
-
        int                     m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
 
+       btVector3       m_aabbMin;
+       btVector3       m_aabbMax;
+
        SIMD_FORCE_INLINE int getUid() const
        {
                return m_uniqueId;
@@ -107,10 +117,12 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
        {
        }
 
-       btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
+       btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
                :m_clientObject(userPtr),
                m_collisionFilterGroup(collisionFilterGroup),
-               m_collisionFilterMask(collisionFilterMask)
+               m_collisionFilterMask(collisionFilterMask),
+               m_aabbMin(aabbMin),
+               m_aabbMax(aabbMax)
        {
                m_multiSapParentProxy = multiSapParentProxy;
        }
@@ -159,7 +171,7 @@ ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
        m_pProxy0(0),
                m_pProxy1(0),
                m_algorithm(0),
-               m_userInfo(0)
+               m_internalInfo1(0)
        {
        }
 
@@ -169,14 +181,14 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
                :               m_pProxy0(other.m_pProxy0),
                                m_pProxy1(other.m_pProxy1),
                                m_algorithm(other.m_algorithm),
-                               m_userInfo(other.m_userInfo)
+                               m_internalInfo1(other.m_internalInfo1)
        {
        }
        btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
        {
 
                //keep them sorted, so the std::set operations work
-               if (&proxy0 < &proxy1)
+               if (proxy0.m_uniqueId < proxy1.m_uniqueId)
         { 
             m_pProxy0 = &proxy0; 
             m_pProxy1 = &proxy1; 
@@ -188,7 +200,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
         }
 
                m_algorithm = 0;
-               m_userInfo = 0;
+               m_internalInfo1 = 0;
 
        }
        
@@ -196,7 +208,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
        btBroadphaseProxy* m_pProxy1;
        
        mutable btCollisionAlgorithm* m_algorithm;
-       mutable void* m_userInfo;
+       union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
 
 };
 
@@ -217,8 +229,13 @@ class btBroadphasePairSortPredicate
 
                bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
                {
-                        return a.m_pProxy0 > b.m_pProxy0 || 
-                               (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
+                       const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
+                       const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
+                       const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
+                       const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
+
+                        return uidA0 > uidB0 || 
+                               (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
                                (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); 
                }
 };
index 7c41c8d..a6e36b4 100644 (file)
@@ -23,188 +23,188 @@ typedef btAlignedObjectArray<const btDbvtNode*>   tConstNodeArray;
 //
 struct btDbvtNodeEnumerator : btDbvt::ICollide
 {
-tConstNodeArray        nodes;
-void Process(const btDbvtNode* n) { nodes.push_back(n); }
+       tConstNodeArray nodes;
+       void Process(const btDbvtNode* n) { nodes.push_back(n); }
 };
 
 //
 static DBVT_INLINE int                 indexof(const btDbvtNode* node)
 {
-return(node->parent->childs[1]==node);
+       return(node->parent->childs[1]==node);
 }
 
 //
 static DBVT_INLINE btDbvtVolume        merge(  const btDbvtVolume& a,
-                                                                               const btDbvtVolume& b)
+                                                                         const btDbvtVolume& b)
 {
-#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char locals[sizeof(btDbvtAabbMm)];
-btDbvtVolume&  res=*(btDbvtVolume*)locals;
+#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
+       ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
+       btDbvtVolume&   res=*(btDbvtVolume*)locals;
 #else
-btDbvtVolume   res;
+               btDbvtVolume    res;
 #endif
-Merge(a,b,res);
-return(res);
+       Merge(a,b,res);
+       return(res);
 }
 
 // volume+edge lengths
 static DBVT_INLINE btScalar            size(const btDbvtVolume& a)
 {
-const btVector3        edges=a.Lengths();
-return(        edges.x()*edges.y()*edges.z()+
+       const btVector3 edges=a.Lengths();
+       return( edges.x()*edges.y()*edges.z()+
                edges.x()+edges.y()+edges.z());
 }
 
 //
 static void                                            getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
 {
-if(node->isinternal())
+       if(node->isinternal())
        {
-       getmaxdepth(node->childs[0],depth+1,maxdepth);
-       getmaxdepth(node->childs[0],depth+1,maxdepth);
+               getmaxdepth(node->childs[0],depth+1,maxdepth);
+               getmaxdepth(node->childs[0],depth+1,maxdepth);
        } else maxdepth=btMax(maxdepth,depth);
 }
 
 //
 static DBVT_INLINE void                        deletenode(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* node)
+                                                                                  btDbvtNode* node)
 {
-btAlignedFree(pdbvt->m_free);
-pdbvt->m_free=node;
+       btAlignedFree(pdbvt->m_free);
+       pdbvt->m_free=node;
 }
-       
+
 //
 static void                                            recursedeletenode(      btDbvt* pdbvt,
-                                                                                                       btDbvtNode* node)
+                                                                                                 btDbvtNode* node)
 {
-if(!node->isleaf())
+       if(!node->isleaf())
        {
-       recursedeletenode(pdbvt,node->childs[0]);
-       recursedeletenode(pdbvt,node->childs[1]);
+               recursedeletenode(pdbvt,node->childs[0]);
+               recursedeletenode(pdbvt,node->childs[1]);
        }
-if(node==pdbvt->m_root) pdbvt->m_root=0;
-deletenode(pdbvt,node);
+       if(node==pdbvt->m_root) pdbvt->m_root=0;
+       deletenode(pdbvt,node);
 }
 
 //
 static DBVT_INLINE btDbvtNode* createnode(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* parent,
-                                                                                       void* data)
+                                                                                  btDbvtNode* parent,
+                                                                                  void* data)
 {
-btDbvtNode*    node;
-if(pdbvt->m_free)
+       btDbvtNode*     node;
+       if(pdbvt->m_free)
        { node=pdbvt->m_free;pdbvt->m_free=0; }
        else
        { node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
-node->parent   =       parent;
-node->data             =       data;
-node->childs[1]        =       0;
-return(node);
+       node->parent    =       parent;
+       node->data              =       data;
+       node->childs[1] =       0;
+       return(node);
 }
 
 //
 static DBVT_INLINE btDbvtNode* createnode(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* parent,
-                                                                                       const btDbvtVolume& volume,
-                                                                                       void* data)
+                                                                                  btDbvtNode* parent,
+                                                                                  const btDbvtVolume& volume,
+                                                                                  void* data)
 {
-btDbvtNode*    node=createnode(pdbvt,parent,data);
-node->volume=volume;
-return(node);
+       btDbvtNode*     node=createnode(pdbvt,parent,data);
+       node->volume=volume;
+       return(node);
 }
 
 //
 static DBVT_INLINE btDbvtNode* createnode(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* parent,
-                                                                                       const btDbvtVolume& volume0,
-                                                                                       const btDbvtVolume& volume1,
-                                                                                       void* data)
+                                                                                  btDbvtNode* parent,
+                                                                                  const btDbvtVolume& volume0,
+                                                                                  const btDbvtVolume& volume1,
+                                                                                  void* data)
 {
-btDbvtNode*    node=createnode(pdbvt,parent,data);
-Merge(volume0,volume1,node->volume);
-return(node);
+       btDbvtNode*     node=createnode(pdbvt,parent,data);
+       Merge(volume0,volume1,node->volume);
+       return(node);
 }
 
 //
 static void                                            insertleaf(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* root,
-                                                                                       btDbvtNode* leaf)
+                                                                                  btDbvtNode* root,
+                                                                                  btDbvtNode* leaf)
 {
-if(!pdbvt->m_root)
+       if(!pdbvt->m_root)
        {
-       pdbvt->m_root   =       leaf;
-       leaf->parent    =       0;
+               pdbvt->m_root   =       leaf;
+               leaf->parent    =       0;
        }
        else
        {
-       if(!root->isleaf())
+               if(!root->isleaf())
                {
-               do      {
-                       root=root->childs[Select(       leaf->volume,
-                                                                               root->childs[0]->volume,
-                                                                               root->childs[1]->volume)];
+                       do      {
+                               root=root->childs[Select(       leaf->volume,
+                                       root->childs[0]->volume,
+                                       root->childs[1]->volume)];
                        } while(!root->isleaf());
                }
-       btDbvtNode*     prev=root->parent;
-       btDbvtNode*     node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
-       if(prev)
+               btDbvtNode*     prev=root->parent;
+               btDbvtNode*     node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
+               if(prev)
                {
-               prev->childs[indexof(root)]     =       node;
-               node->childs[0]                         =       root;root->parent=node;
-               node->childs[1]                         =       leaf;leaf->parent=node;
-               do      {
-                       if(!prev->volume.Contain(node->volume))
-                               Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+                       prev->childs[indexof(root)]     =       node;
+                       node->childs[0]                         =       root;root->parent=node;
+                       node->childs[1]                         =       leaf;leaf->parent=node;
+                       do      {
+                               if(!prev->volume.Contain(node->volume))
+                                       Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
                                else
-                               break;
-                       node=prev;
+                                       break;
+                               node=prev;
                        } while(0!=(prev=node->parent));
                }
                else
                {
-               node->childs[0] =       root;root->parent=node;
-               node->childs[1] =       leaf;leaf->parent=node;
-               pdbvt->m_root   =       node;
+                       node->childs[0] =       root;root->parent=node;
+                       node->childs[1] =       leaf;leaf->parent=node;
+                       pdbvt->m_root   =       node;
                }
        }
 }
-       
+
 //
 static btDbvtNode*                             removeleaf(     btDbvt* pdbvt,
-                                                                                       btDbvtNode* leaf)
+                                                                                  btDbvtNode* leaf)
 {
-if(leaf==pdbvt->m_root)
+       if(leaf==pdbvt->m_root)
        {
-       pdbvt->m_root=0;
-       return(0);
+               pdbvt->m_root=0;
+               return(0);
        }
        else
        {
-       btDbvtNode*     parent=leaf->parent;
-       btDbvtNode*     prev=parent->parent;
-       btDbvtNode*     sibling=parent->childs[1-indexof(leaf)];                        
-       if(prev)
+               btDbvtNode*     parent=leaf->parent;
+               btDbvtNode*     prev=parent->parent;
+               btDbvtNode*     sibling=parent->childs[1-indexof(leaf)];                        
+               if(prev)
                {
-               prev->childs[indexof(parent)]=sibling;
-               sibling->parent=prev;
-               deletenode(pdbvt,parent);
-               while(prev)
+                       prev->childs[indexof(parent)]=sibling;
+                       sibling->parent=prev;
+                       deletenode(pdbvt,parent);
+                       while(prev)
                        {
-                       const btDbvtVolume      pb=prev->volume;
-                       Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
-                       if(NotEqual(pb,prev->volume))
+                               const btDbvtVolume      pb=prev->volume;
+                               Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+                               if(NotEqual(pb,prev->volume))
                                {
-                               prev=prev->parent;
+                                       prev=prev->parent;
                                } else break;
                        }
-               return(prev?prev:pdbvt->m_root);
+                       return(prev?prev:pdbvt->m_root);
                }
                else
                {                                                               
-               pdbvt->m_root=sibling;
-               sibling->parent=0;
-               deletenode(pdbvt,parent);
-               return(pdbvt->m_root);
+                       pdbvt->m_root=sibling;
+                       sibling->parent=0;
+                       deletenode(pdbvt,parent);
+                       return(pdbvt->m_root);
                }                       
        }
 }
@@ -215,33 +215,33 @@ static void                                               fetchleaves(btDbvt* pdbvt,
                                                                                        tNodeArray& leaves,
                                                                                        int depth=-1)
 {
-if(root->isinternal()&&depth)
+       if(root->isinternal()&&depth)
        {
-       fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
-       fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
-       deletenode(pdbvt,root);
+               fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
+               fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
+               deletenode(pdbvt,root);
        }
        else
        {
-       leaves.push_back(root);
+               leaves.push_back(root);
        }
 }
 
 //
 static void                                            split(  const tNodeArray& leaves,
-                                                                               tNodeArray& left,
-                                                                               tNodeArray& right,
-                                                                               const btVector3& org,
-                                                                               const btVector3& axis)
+                                                                         tNodeArray& left,
+                                                                         tNodeArray& right,
+                                                                         const btVector3& org,
+                                                                         const btVector3& axis)
 {
-left.resize(0);
-right.resize(0);
-for(int i=0,ni=leaves.size();i<ni;++i)
+       left.resize(0);
+       right.resize(0);
+       for(int i=0,ni=leaves.size();i<ni;++i)
        {
-       if(dot(axis,leaves[i]->volume.Center()-org)<0)
-               left.push_back(leaves[i]);
+               if(dot(axis,leaves[i]->volume.Center()-org)<0)
+                       left.push_back(leaves[i]);
                else
-               right.push_back(leaves[i]);
+                       right.push_back(leaves[i]);
        }
 }
 
@@ -249,49 +249,49 @@ for(int i=0,ni=leaves.size();i<ni;++i)
 static btDbvtVolume                            bounds( const tNodeArray& leaves)
 {
 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char        locals[sizeof(btDbvtVolume)];
-btDbvtVolume&  volume=*(btDbvtVolume*)locals;
-volume=leaves[0]->volume;
+       ATTRIBUTE_ALIGNED16(char        locals[sizeof(btDbvtVolume)]);
+       btDbvtVolume&   volume=*(btDbvtVolume*)locals;
+       volume=leaves[0]->volume;
 #else
-btDbvtVolume volume=leaves[0]->volume;
+       btDbvtVolume volume=leaves[0]->volume;
 #endif
-for(int i=1,ni=leaves.size();i<ni;++i)
+       for(int i=1,ni=leaves.size();i<ni;++i)
        {
-       Merge(volume,leaves[i]->volume,volume);
+               Merge(volume,leaves[i]->volume,volume);
        }
-return(volume);
+       return(volume);
 }
 
 //
 static void                                            bottomup(       btDbvt* pdbvt,
-                                                                                       tNodeArray& leaves)
+                                                                                tNodeArray& leaves)
 {
-while(leaves.size()>1)
+       while(leaves.size()>1)
        {
-       btScalar        minsize=SIMD_INFINITY;
-       int                     minidx[2]={-1,-1};
-       for(int i=0;i<leaves.size();++i)
+               btScalar        minsize=SIMD_INFINITY;
+               int                     minidx[2]={-1,-1};
+               for(int i=0;i<leaves.size();++i)
                {
-               for(int j=i+1;j<leaves.size();++j)
+                       for(int j=i+1;j<leaves.size();++j)
                        {
-                       const btScalar  sz=size(merge(leaves[i]->volume,leaves[j]->volume));
-                       if(sz<minsize)
+                               const btScalar  sz=size(merge(leaves[i]->volume,leaves[j]->volume));
+                               if(sz<minsize)
                                {
-                               minsize         =       sz;
-                               minidx[0]       =       i;
-                               minidx[1]       =       j;
+                                       minsize         =       sz;
+                                       minidx[0]       =       i;
+                                       minidx[1]       =       j;
                                }
                        }
                }
-       btDbvtNode*     n[]     =       {leaves[minidx[0]],leaves[minidx[1]]};
-       btDbvtNode*     p       =       createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
-       p->childs[0]            =       n[0];
-       p->childs[1]            =       n[1];
-       n[0]->parent            =       p;
-       n[1]->parent            =       p;
-       leaves[minidx[0]]       =       p;
-       leaves.swap(minidx[1],leaves.size()-1);
-       leaves.pop_back();
+               btDbvtNode*     n[]     =       {leaves[minidx[0]],leaves[minidx[1]]};
+               btDbvtNode*     p       =       createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
+               p->childs[0]            =       n[0];
+               p->childs[1]            =       n[1];
+               n[0]->parent            =       p;
+               n[1]->parent            =       p;
+               leaves[minidx[0]]       =       p;
+               leaves.swap(minidx[1],leaves.size()-1);
+               leaves.pop_back();
        }
 }
 
@@ -300,175 +300,181 @@ static btDbvtNode*                      topdown(btDbvt* pdbvt,
                                                                        tNodeArray& leaves,
                                                                        int bu_treshold)
 {
-static const btVector3 axis[]={btVector3(1,0,0),
-                                                               btVector3(0,1,0),
-                                                               btVector3(0,0,1)};
-if(leaves.size()>1)
+       static const btVector3  axis[]={btVector3(1,0,0),
+               btVector3(0,1,0),
+               btVector3(0,0,1)};
+       if(leaves.size()>1)
        {
-       if(leaves.size()>bu_treshold)
+               if(leaves.size()>bu_treshold)
                {
-               const btDbvtVolume      vol=bounds(leaves);
-               const btVector3                 org=vol.Center();
-               tNodeArray                              sets[2];
-               int                                             bestaxis=-1;
-               int                                             bestmidp=leaves.size();
-               int                                             splitcount[3][2]={{0,0},{0,0},{0,0}};
-               int i;
-               for( i=0;i<leaves.size();++i)
+                       const btDbvtVolume      vol=bounds(leaves);
+                       const btVector3                 org=vol.Center();
+                       tNodeArray                              sets[2];
+                       int                                             bestaxis=-1;
+                       int                                             bestmidp=leaves.size();
+                       int                                             splitcount[3][2]={{0,0},{0,0},{0,0}};
+                       int i;
+                       for( i=0;i<leaves.size();++i)
                        {
-                       const btVector3 x=leaves[i]->volume.Center()-org;
-                       for(int j=0;j<3;++j)
+                               const btVector3 x=leaves[i]->volume.Center()-org;
+                               for(int j=0;j<3;++j)
                                {
-                               ++splitcount[j][dot(x,axis[j])>0?1:0];
+                                       ++splitcount[j][dot(x,axis[j])>0?1:0];
                                }
                        }
-               for( i=0;i<3;++i)
+                       for( i=0;i<3;++i)
                        {
-                       if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
+                               if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
                                {
-                               const int       midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
-                               if(midp<bestmidp)
+                                       const int       midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
+                                       if(midp<bestmidp)
                                        {
-                                       bestaxis=i;
-                                       bestmidp=midp;
+                                               bestaxis=i;
+                                               bestmidp=midp;
                                        }
                                }
                        }
-               if(bestaxis>=0)
+                       if(bestaxis>=0)
                        {
-                       sets[0].reserve(splitcount[bestaxis][0]);
-                       sets[1].reserve(splitcount[bestaxis][1]);
-                       split(leaves,sets[0],sets[1],org,axis[bestaxis]);
+                               sets[0].reserve(splitcount[bestaxis][0]);
+                               sets[1].reserve(splitcount[bestaxis][1]);
+                               split(leaves,sets[0],sets[1],org,axis[bestaxis]);
                        }
                        else
                        {
-                       sets[0].reserve(leaves.size()/2+1);
-                       sets[1].reserve(leaves.size()/2);
-                       for(int i=0,ni=leaves.size();i<ni;++i)
+                               sets[0].reserve(leaves.size()/2+1);
+                               sets[1].reserve(leaves.size()/2);
+                               for(int i=0,ni=leaves.size();i<ni;++i)
                                {
-                               sets[i&1].push_back(leaves[i]);
+                                       sets[i&1].push_back(leaves[i]);
                                }
                        }
-               btDbvtNode*     node=createnode(pdbvt,0,vol,0);
-               node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
-               node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
-               node->childs[0]->parent=node;
-               node->childs[1]->parent=node;
-               return(node);
+                       btDbvtNode*     node=createnode(pdbvt,0,vol,0);
+                       node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
+                       node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
+                       node->childs[0]->parent=node;
+                       node->childs[1]->parent=node;
+                       return(node);
                }
                else
                {
-               bottomup(pdbvt,leaves);
-               return(leaves[0]);
+                       bottomup(pdbvt,leaves);
+                       return(leaves[0]);
                }
        }
-return(leaves[0]);
+       return(leaves[0]);
 }
 
 //
 static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r)
 {
-btDbvtNode*    p=n->parent;
-btAssert(n->isinternal());
-if(p>n)
+       btDbvtNode*     p=n->parent;
+       btAssert(n->isinternal());
+       if(p>n)
        {
-       const int               i=indexof(n);
-       const int               j=1-i;
-       btDbvtNode*     s=p->childs[j];
-       btDbvtNode*     q=p->parent;
-       btAssert(n==p->childs[i]);
-       if(q) q->childs[indexof(p)]=n; else r=n;
-       s->parent=n;
-       p->parent=n;
-       n->parent=q;
-       p->childs[0]=n->childs[0];
-       p->childs[1]=n->childs[1];
-       n->childs[0]->parent=p;
-       n->childs[1]->parent=p;
-       n->childs[i]=p;
-       n->childs[j]=s;
-       btSwap(p->volume,n->volume);
-       return(p);
+               const int               i=indexof(n);
+               const int               j=1-i;
+               btDbvtNode*     s=p->childs[j];
+               btDbvtNode*     q=p->parent;
+               btAssert(n==p->childs[i]);
+               if(q) q->childs[indexof(p)]=n; else r=n;
+               s->parent=n;
+               p->parent=n;
+               n->parent=q;
+               p->childs[0]=n->childs[0];
+               p->childs[1]=n->childs[1];
+               n->childs[0]->parent=p;
+               n->childs[1]->parent=p;
+               n->childs[i]=p;
+               n->childs[j]=s;
+               btSwap(p->volume,n->volume);
+               return(p);
        }
-return(n);
+       return(n);
 }
 
-//
+#if 0
 static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count)
 {
-while(n&&(count--)) n=n->parent;
-return(n);
+       while(n&&(count--)) n=n->parent;
+       return(n);
 }
+#endif
 
 //
 // Api
 //
 
 //
-                               btDbvt::btDbvt()
+btDbvt::btDbvt()
 {
-m_root         =       0;
-m_free         =       0;
-m_lkhd         =       -1;
-m_leaves       =       0;
-m_opath                =       0;
+       m_root          =       0;
+       m_free          =       0;
+       m_lkhd          =       -1;
+       m_leaves        =       0;
+       m_opath         =       0;
 }
 
 //
-                               btDbvt::~btDbvt()
+btDbvt::~btDbvt()
 {
-clear();
+       clear();
 }
 
 //
 void                   btDbvt::clear()
 {
-if(m_root)     recursedeletenode(this,m_root);
-btAlignedFree(m_free);
-m_free=0;
+       if(m_root)      
+               recursedeletenode(this,m_root);
+       btAlignedFree(m_free);
+       m_free=0;
+       m_lkhd          =       -1;
+       m_stkStack.clear();
+       m_opath         =       0;
+       
 }
 
 //
 void                   btDbvt::optimizeBottomUp()
 {
-if(m_root)
+       if(m_root)
        {
-       tNodeArray leaves;
-       leaves.reserve(m_leaves);
-       fetchleaves(this,m_root,leaves);
-       bottomup(this,leaves);
-       m_root=leaves[0];
+               tNodeArray leaves;
+               leaves.reserve(m_leaves);
+               fetchleaves(this,m_root,leaves);
+               bottomup(this,leaves);
+               m_root=leaves[0];
        }
 }
 
 //
 void                   btDbvt::optimizeTopDown(int bu_treshold)
 {
-if(m_root)
+       if(m_root)
        {
-       tNodeArray      leaves;
-       leaves.reserve(m_leaves);
-       fetchleaves(this,m_root,leaves);
-       m_root=topdown(this,leaves,bu_treshold);
+               tNodeArray      leaves;
+               leaves.reserve(m_leaves);
+               fetchleaves(this,m_root,leaves);
+               m_root=topdown(this,leaves,bu_treshold);
        }
 }
 
 //
 void                   btDbvt::optimizeIncremental(int passes)
 {
-if(passes<0) passes=m_leaves;
-if(m_root&&(passes>0))
+       if(passes<0) passes=m_leaves;
+       if(m_root&&(passes>0))
        {
-       do      {
-               btDbvtNode*             node=m_root;
-               unsigned        bit=0;
-               while(node->isinternal())
+               do      {
+                       btDbvtNode*             node=m_root;
+                       unsigned        bit=0;
+                       while(node->isinternal())
                        {
-                       node=sort(node,m_root)->childs[(m_opath>>bit)&1];
-                       bit=(bit+1)&(sizeof(unsigned)*8-1);
+                               node=sort(node,m_root)->childs[(m_opath>>bit)&1];
+                               bit=(bit+1)&(sizeof(unsigned)*8-1);
                        }
-               update(node);
-               ++m_opath;
+                       update(node);
+                       ++m_opath;
                } while(--passes);
        }
 }
@@ -476,104 +482,104 @@ if(m_root&&(passes>0))
 //
 btDbvtNode*    btDbvt::insert(const btDbvtVolume& volume,void* data)
 {
-btDbvtNode*    leaf=createnode(this,0,volume,data);
-insertleaf(this,m_root,leaf);
-++m_leaves;
-return(leaf);
+       btDbvtNode*     leaf=createnode(this,0,volume,data);
+       insertleaf(this,m_root,leaf);
+       ++m_leaves;
+       return(leaf);
 }
 
 //
 void                   btDbvt::update(btDbvtNode* leaf,int lookahead)
 {
-btDbvtNode*    root=removeleaf(this,leaf);
-if(root)
+       btDbvtNode*     root=removeleaf(this,leaf);
+       if(root)
        {
-       if(lookahead>=0)
+               if(lookahead>=0)
                {
-               for(int i=0;(i<lookahead)&&root->parent;++i)
+                       for(int i=0;(i<lookahead)&&root->parent;++i)
                        {
-                       root=root->parent;
+                               root=root->parent;
                        }
                } else root=m_root;
        }
-insertleaf(this,root,leaf);
+       insertleaf(this,root,leaf);
 }
 
 //
-void                   btDbvt::update(btDbvtNode* leaf,const btDbvtVolume& volume)
+void                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
 {
-btDbvtNode*    root=removeleaf(this,leaf);
-if(root)
+       btDbvtNode*     root=removeleaf(this,leaf);
+       if(root)
        {
-       if(m_lkhd>=0)
+               if(m_lkhd>=0)
                {
-               for(int i=0;(i<m_lkhd)&&root->parent;++i)
+                       for(int i=0;(i<m_lkhd)&&root->parent;++i)
                        {
-                       root=root->parent;
+                               root=root->parent;
                        }
                } else root=m_root;
        }
-leaf->volume=volume;
-insertleaf(this,root,leaf);
+       leaf->volume=volume;
+       insertleaf(this,root,leaf);
 }
 
 //
-bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin)
+bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
 {
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
+       if(leaf->volume.Contain(volume)) return(false);
+       volume.Expand(btVector3(margin,margin,margin));
+       volume.SignedExpand(velocity);
+       update(leaf,volume);
+       return(true);
 }
 
 //
-bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity)
+bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
 {
-if(leaf->volume.Contain(volume)) return(false);
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
+       if(leaf->volume.Contain(volume)) return(false);
+       volume.SignedExpand(velocity);
+       update(leaf,volume);
+       return(true);
 }
 
 //
-bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin)
+bool                   btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
 {
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-update(leaf,volume);
-return(true);
+       if(leaf->volume.Contain(volume)) return(false);
+       volume.Expand(btVector3(margin,margin,margin));
+       update(leaf,volume);
+       return(true);
 }
 
 //
 void                   btDbvt::remove(btDbvtNode* leaf)
 {
-removeleaf(this,leaf);
-deletenode(this,leaf);
---m_leaves;
+       removeleaf(this,leaf);
+       deletenode(this,leaf);
+       --m_leaves;
 }
 
 //
 void                   btDbvt::write(IWriter* iwriter) const
 {
-btDbvtNodeEnumerator   nodes;
-nodes.nodes.reserve(m_leaves*2);
-enumNodes(m_root,nodes);
-iwriter->Prepare(m_root,nodes.nodes.size());
-for(int i=0;i<nodes.nodes.size();++i)
+       btDbvtNodeEnumerator    nodes;
+       nodes.nodes.reserve(m_leaves*2);
+       enumNodes(m_root,nodes);
+       iwriter->Prepare(m_root,nodes.nodes.size());
+       for(int i=0;i<nodes.nodes.size();++i)
        {
-       const btDbvtNode* n=nodes.nodes[i];
-       int                     p=-1;
-       if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
-       if(n->isinternal())
+               const btDbvtNode* n=nodes.nodes[i];
+               int                     p=-1;
+               if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
+               if(n->isinternal())
                {
-               const int       c0=nodes.nodes.findLinearSearch(n->childs[0]);
-               const int       c1=nodes.nodes.findLinearSearch(n->childs[1]);
-               iwriter->WriteNode(n,i,p,c0,c1);
+                       const int       c0=nodes.nodes.findLinearSearch(n->childs[0]);
+                       const int       c1=nodes.nodes.findLinearSearch(n->childs[1]);
+                       iwriter->WriteNode(n,i,p,c0,c1);
                }
                else
                {
-               iwriter->WriteLeaf(n,i,p);
+                       iwriter->WriteLeaf(n,i,p);
                }       
        }
 }
@@ -581,29 +587,29 @@ for(int i=0;i<nodes.nodes.size();++i)
 //
 void                   btDbvt::clone(btDbvt& dest,IClone* iclone) const
 {
-dest.clear();
-if(m_root!=0)
+       dest.clear();
+       if(m_root!=0)
        {       
-       btAlignedObjectArray<sStkCLN>   stack;
-       stack.reserve(m_leaves);
-       stack.push_back(sStkCLN(m_root,0));
-       do      {
-               const int               i=stack.size()-1;
-               const sStkCLN   e=stack[i];
-               btDbvtNode*                     n=createnode(&dest,e.parent,e.node->volume,e.node->data);
-               stack.pop_back();
-               if(e.parent!=0)
-                       e.parent->childs[i&1]=n;
+               btAlignedObjectArray<sStkCLN>   stack;
+               stack.reserve(m_leaves);
+               stack.push_back(sStkCLN(m_root,0));
+               do      {
+                       const int               i=stack.size()-1;
+                       const sStkCLN   e=stack[i];
+                       btDbvtNode*                     n=createnode(&dest,e.parent,e.node->volume,e.node->data);
+                       stack.pop_back();
+                       if(e.parent!=0)
+                               e.parent->childs[i&1]=n;
                        else
-                       dest.m_root=n;
-               if(e.node->isinternal())
+                               dest.m_root=n;
+                       if(e.node->isinternal())
                        {
-                       stack.push_back(sStkCLN(e.node->childs[0],n));
-                       stack.push_back(sStkCLN(e.node->childs[1],n));
+                               stack.push_back(sStkCLN(e.node->childs[0],n));
+                               stack.push_back(sStkCLN(e.node->childs[1],n));
                        }
                        else
                        {
-                       iclone->CloneLeaf(n);
+                               iclone->CloneLeaf(n);
                        }
                } while(stack.size()>0);
        }
@@ -612,31 +618,31 @@ if(m_root!=0)
 //
 int                            btDbvt::maxdepth(const btDbvtNode* node)
 {
-int    depth=0;
-if(node) getmaxdepth(node,1,depth);
-return(depth);
+       int     depth=0;
+       if(node) getmaxdepth(node,1,depth);
+       return(depth);
 }
 
 //
 int                            btDbvt::countLeaves(const btDbvtNode* node)
 {
-if(node->isinternal())
-       return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
+       if(node->isinternal())
+               return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
        else
-       return(1);
+               return(1);
 }
 
 //
 void                   btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
 {
-if(node->isinternal())
+       if(node->isinternal())
        {
-       extractLeaves(node->childs[0],leaves);
-       extractLeaves(node->childs[1],leaves);
+               extractLeaves(node->childs[0],leaves);
+               extractLeaves(node->childs[1],leaves);
        }
        else
        {
-       leaves.push_back(node);
+               leaves.push_back(node);
        }       
 }
 
@@ -657,19 +663,19 @@ q6600,2.4ghz
 /W3 /nologo /c /Wp64 /Zi /errorReport:prompt
 
 Benchmarking dbvt...
-        World scale: 100.000000
-        Extents base: 1.000000
-        Extents range: 4.000000
-        Leaves: 8192
-        sizeof(btDbvtVolume): 32 bytes
-        sizeof(btDbvtNode):   44 bytes
+World scale: 100.000000
+Extents base: 1.000000
+Extents range: 4.000000
+Leaves: 8192
+sizeof(btDbvtVolume): 32 bytes
+sizeof(btDbvtNode):   44 bytes
 [1] btDbvtVolume intersections: 3499 ms (-1%)
 [2] btDbvtVolume merges: 1934 ms (0%)
 [3] btDbvt::collideTT: 5485 ms (-21%)
 [4] btDbvt::collideTT self: 2814 ms (-20%)
 [5] btDbvt::collideTT xform: 7379 ms (-1%)
 [6] btDbvt::collideTT xform,self: 7270 ms (-2%)
-[7] btDbvt::collideRAY: 6314 ms (0%),(332143 r/s)
+[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
 [8] insert/remove: 2093 ms (0%),(1001983 ir/s)
 [9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
 [10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
@@ -684,606 +690,606 @@ Benchmarking dbvt...
 
 struct btDbvtBenchmark
 {
-struct NilPolicy : btDbvt::ICollide
+       struct NilPolicy : btDbvt::ICollide
        {
-       NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)             {}
-       void    Process(const btDbvtNode*,const btDbvtNode*)                            { ++m_pcount; }
-       void    Process(const btDbvtNode*)                                                                      { ++m_pcount; }
-       void    Process(const btDbvtNode*,btScalar depth)
+               NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)             {}
+               void    Process(const btDbvtNode*,const btDbvtNode*)                            { ++m_pcount; }
+               void    Process(const btDbvtNode*)                                                                      { ++m_pcount; }
+               void    Process(const btDbvtNode*,btScalar depth)
                {
-               ++m_pcount;
-               if(m_checksort)
+                       ++m_pcount;
+                       if(m_checksort)
                        { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
                }
-       int                     m_pcount;
-       btScalar        m_depth;
-       bool            m_checksort;
+               int                     m_pcount;
+               btScalar        m_depth;
+               bool            m_checksort;
        };
-struct P14 : btDbvt::ICollide
+       struct P14 : btDbvt::ICollide
        {
-       struct Node
+               struct Node
                {
-               const btDbvtNode*       leaf;
-               btScalar                        depth;
+                       const btDbvtNode*       leaf;
+                       btScalar                        depth;
                };
-       void Process(const btDbvtNode* leaf,btScalar depth)
+               void Process(const btDbvtNode* leaf,btScalar depth)
                {
-               Node    n;
-               n.leaf  =       leaf;
-               n.depth =       depth;
+                       Node    n;
+                       n.leaf  =       leaf;
+                       n.depth =       depth;
                }
-       static int sortfnc(const Node& a,const Node& b)
+               static int sortfnc(const Node& a,const Node& b)
                {
-               if(a.depth<b.depth) return(+1);
-               if(a.depth>b.depth) return(-1);
-               return(0);
+                       if(a.depth<b.depth) return(+1);
+                       if(a.depth>b.depth) return(-1);
+                       return(0);
                }
-       btAlignedObjectArray<Node>              m_nodes;
+               btAlignedObjectArray<Node>              m_nodes;
        };
-struct P15 : btDbvt::ICollide
+       struct P15 : btDbvt::ICollide
        {
-       struct Node
+               struct Node
                {
-               const btDbvtNode*       leaf;
-               btScalar                        depth;
+                       const btDbvtNode*       leaf;
+                       btScalar                        depth;
                };
-       void Process(const btDbvtNode* leaf)
+               void Process(const btDbvtNode* leaf)
                {
-               Node    n;
-               n.leaf  =       leaf;
-               n.depth =       dot(leaf->volume.Center(),m_axis);
+                       Node    n;
+                       n.leaf  =       leaf;
+                       n.depth =       dot(leaf->volume.Center(),m_axis);
                }
-       static int sortfnc(const Node& a,const Node& b)
+               static int sortfnc(const Node& a,const Node& b)
                {
-               if(a.depth<b.depth) return(+1);
-               if(a.depth>b.depth) return(-1);
-               return(0);
+                       if(a.depth<b.depth) return(+1);
+                       if(a.depth>b.depth) return(-1);
+                       return(0);
                }
-       btAlignedObjectArray<Node>              m_nodes;
-       btVector3                                               m_axis;
+               btAlignedObjectArray<Node>              m_nodes;
+               btVector3                                               m_axis;
        };
-static btScalar                        RandUnit()
+       static btScalar                 RandUnit()
        {
-       return(rand()/(btScalar)RAND_MAX);
+               return(rand()/(btScalar)RAND_MAX);
        }
-static btVector3               RandVector3()
+       static btVector3                RandVector3()
        {
-       return(btVector3(RandUnit(),RandUnit(),RandUnit()));
+               return(btVector3(RandUnit(),RandUnit(),RandUnit()));
        }
-static btVector3               RandVector3(btScalar cs)
+       static btVector3                RandVector3(btScalar cs)
        {
-       return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
+               return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
        }
-static btDbvtVolume    RandVolume(btScalar cs,btScalar eb,btScalar es)
+       static btDbvtVolume     RandVolume(btScalar cs,btScalar eb,btScalar es)
        {
-       return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
+               return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
        }
-static btTransform             RandTransform(btScalar cs)
+       static btTransform              RandTransform(btScalar cs)
        {
-       btTransform     t;
-       t.setOrigin(RandVector3(cs));
-       t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
-       return(t);
+               btTransform     t;
+               t.setOrigin(RandVector3(cs));
+               t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
+               return(t);
        }
-static void                            RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
+       static void                             RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
        {
-       dbvt.clear();
-       for(int i=0;i<leaves;++i)
+               dbvt.clear();
+               for(int i=0;i<leaves;++i)
                {
-               dbvt.insert(RandVolume(cs,eb,es),0);
+                       dbvt.insert(RandVolume(cs,eb,es),0);
                }
        }
 };
 
 void                   btDbvt::benchmark()
 {
-static const btScalar  cfgVolumeCenterScale            =       100;
-static const btScalar  cfgVolumeExentsBase                     =       1;
-static const btScalar  cfgVolumeExentsScale            =       4;
-static const int               cfgLeaves                                       =       8192;
-static const bool              cfgEnable                                       =       true;
+       static const btScalar   cfgVolumeCenterScale            =       100;
+       static const btScalar   cfgVolumeExentsBase                     =       1;
+       static const btScalar   cfgVolumeExentsScale            =       4;
+       static const int                cfgLeaves                                       =       8192;
+       static const bool               cfgEnable                                       =       true;
 
-//[1] btDbvtVolume intersections
-bool                                   cfgBenchmark1_Enable            =       cfgEnable;
-static const int               cfgBenchmark1_Iterations        =       8;
-static const int               cfgBenchmark1_Reference         =       3499;
-//[2] btDbvtVolume merges
-bool                                   cfgBenchmark2_Enable            =       cfgEnable;
-static const int               cfgBenchmark2_Iterations        =       4;
-static const int               cfgBenchmark2_Reference         =       1945;
-//[3] btDbvt::collideTT
-bool                                   cfgBenchmark3_Enable            =       cfgEnable;
-static const int               cfgBenchmark3_Iterations        =       512;
-static const int               cfgBenchmark3_Reference         =       5485;
-//[4] btDbvt::collideTT self
-bool                                   cfgBenchmark4_Enable            =       cfgEnable;
-static const int               cfgBenchmark4_Iterations        =       512;
-static const int               cfgBenchmark4_Reference         =       2814;
-//[5] btDbvt::collideTT xform
-bool                                   cfgBenchmark5_Enable            =       cfgEnable;
-static const int               cfgBenchmark5_Iterations        =       512;
-static const btScalar  cfgBenchmark5_OffsetScale       =       2;
-static const int               cfgBenchmark5_Reference         =       7379;
-//[6] btDbvt::collideTT xform,self
-bool                                   cfgBenchmark6_Enable            =       cfgEnable;
-static const int               cfgBenchmark6_Iterations        =       512;
-static const btScalar  cfgBenchmark6_OffsetScale       =       2;
-static const int               cfgBenchmark6_Reference         =       7270;
-//[7] btDbvt::collideRAY
-bool                                   cfgBenchmark7_Enable            =       cfgEnable;
-static const int               cfgBenchmark7_Passes            =       32;
-static const int               cfgBenchmark7_Iterations        =       65536;
-static const int               cfgBenchmark7_Reference         =       6307;
-//[8] insert/remove
-bool                                   cfgBenchmark8_Enable            =       cfgEnable;
-static const int               cfgBenchmark8_Passes            =       32;
-static const int               cfgBenchmark8_Iterations        =       65536;
-static const int               cfgBenchmark8_Reference         =       2105;
-//[9] updates (teleport)
-bool                                   cfgBenchmark9_Enable            =       cfgEnable;
-static const int               cfgBenchmark9_Passes            =       32;
-static const int               cfgBenchmark9_Iterations        =       65536;
-static const int               cfgBenchmark9_Reference         =       1879;
-//[10] updates (jitter)
-bool                                   cfgBenchmark10_Enable           =       cfgEnable;
-static const btScalar  cfgBenchmark10_Scale            =       cfgVolumeCenterScale/10000;
-static const int               cfgBenchmark10_Passes           =       32;
-static const int               cfgBenchmark10_Iterations       =       65536;
-static const int               cfgBenchmark10_Reference        =       1244;
-//[11] optimize (incremental)
-bool                                   cfgBenchmark11_Enable           =       cfgEnable;
-static const int               cfgBenchmark11_Passes           =       64;
-static const int               cfgBenchmark11_Iterations       =       65536;
-static const int               cfgBenchmark11_Reference        =       2510;
-//[12] btDbvtVolume notequal
-bool                                   cfgBenchmark12_Enable           =       cfgEnable;
-static const int               cfgBenchmark12_Iterations       =       32;
-static const int               cfgBenchmark12_Reference        =       3677;
-//[13] culling(OCL+fullsort)
-bool                                   cfgBenchmark13_Enable           =       cfgEnable;
-static const int               cfgBenchmark13_Iterations       =       1024;
-static const int               cfgBenchmark13_Reference        =       2231;
-//[14] culling(OCL+qsort)
-bool                                   cfgBenchmark14_Enable           =       cfgEnable;
-static const int               cfgBenchmark14_Iterations       =       8192;
-static const int               cfgBenchmark14_Reference        =       3500;
-//[15] culling(KDOP+qsort)
-bool                                   cfgBenchmark15_Enable           =       cfgEnable;
-static const int               cfgBenchmark15_Iterations       =       8192;
-static const int               cfgBenchmark15_Reference        =       1151;
-//[16] insert/remove batch
-bool                                   cfgBenchmark16_Enable           =       cfgEnable;
-static const int               cfgBenchmark16_BatchCount       =       256;
-static const int               cfgBenchmark16_Passes           =       16384;
-static const int               cfgBenchmark16_Reference        =       5138;
-//[17] select
-bool                                   cfgBenchmark17_Enable           =       cfgEnable;
-static const int               cfgBenchmark17_Iterations       =       4;
-static const int               cfgBenchmark17_Reference        =       3390;
+       //[1] btDbvtVolume intersections
+       bool                                    cfgBenchmark1_Enable            =       cfgEnable;
+       static const int                cfgBenchmark1_Iterations        =       8;
+       static const int                cfgBenchmark1_Reference         =       3499;
+       //[2] btDbvtVolume merges
+       bool                                    cfgBenchmark2_Enable            =       cfgEnable;
+       static const int                cfgBenchmark2_Iterations        =       4;
+       static const int                cfgBenchmark2_Reference         =       1945;
+       //[3] btDbvt::collideTT
+       bool                                    cfgBenchmark3_Enable            =       cfgEnable;
+       static const int                cfgBenchmark3_Iterations        =       512;
+       static const int                cfgBenchmark3_Reference         =       5485;
+       //[4] btDbvt::collideTT self
+       bool                                    cfgBenchmark4_Enable            =       cfgEnable;
+       static const int                cfgBenchmark4_Iterations        =       512;
+       static const int                cfgBenchmark4_Reference         =       2814;
+       //[5] btDbvt::collideTT xform
+       bool                                    cfgBenchmark5_Enable            =       cfgEnable;
+       static const int                cfgBenchmark5_Iterations        =       512;
+       static const btScalar   cfgBenchmark5_OffsetScale       =       2;
+       static const int                cfgBenchmark5_Reference         =       7379;
+       //[6] btDbvt::collideTT xform,self
+       bool                                    cfgBenchmark6_Enable            =       cfgEnable;
+       static const int                cfgBenchmark6_Iterations        =       512;
+       static const btScalar   cfgBenchmark6_OffsetScale       =       2;
+       static const int                cfgBenchmark6_Reference         =       7270;
+       //[7] btDbvt::rayTest
+       bool                                    cfgBenchmark7_Enable            =       cfgEnable;
+       static const int                cfgBenchmark7_Passes            =       32;
+       static const int                cfgBenchmark7_Iterations        =       65536;
+       static const int                cfgBenchmark7_Reference         =       6307;
+       //[8] insert/remove
+       bool                                    cfgBenchmark8_Enable            =       cfgEnable;
+       static const int                cfgBenchmark8_Passes            =       32;
+       static const int                cfgBenchmark8_Iterations        =       65536;
+       static const int                cfgBenchmark8_Reference         =       2105;
+       //[9] updates (teleport)
+       bool                                    cfgBenchmark9_Enable            =       cfgEnable;
+       static const int                cfgBenchmark9_Passes            =       32;
+       static const int                cfgBenchmark9_Iterations        =       65536;
+       static const int                cfgBenchmark9_Reference         =       1879;
+       //[10] updates (jitter)
+       bool                                    cfgBenchmark10_Enable           =       cfgEnable;
+       static const btScalar   cfgBenchmark10_Scale            =       cfgVolumeCenterScale/10000;
+       static const int                cfgBenchmark10_Passes           =       32;
+       static const int                cfgBenchmark10_Iterations       =       65536;
+       static const int                cfgBenchmark10_Reference        =       1244;
+       //[11] optimize (incremental)
+       bool                                    cfgBenchmark11_Enable           =       cfgEnable;
+       static const int                cfgBenchmark11_Passes           =       64;
+       static const int                cfgBenchmark11_Iterations       =       65536;
+       static const int                cfgBenchmark11_Reference        =       2510;
+       //[12] btDbvtVolume notequal
+       bool                                    cfgBenchmark12_Enable           =       cfgEnable;
+       static const int                cfgBenchmark12_Iterations       =       32;
+       static const int                cfgBenchmark12_Reference        =       3677;
+       //[13] culling(OCL+fullsort)
+       bool                                    cfgBenchmark13_Enable           =       cfgEnable;
+       static const int                cfgBenchmark13_Iterations       =       1024;
+       static const int                cfgBenchmark13_Reference        =       2231;
+       //[14] culling(OCL+qsort)
+       bool                                    cfgBenchmark14_Enable           =       cfgEnable;
+       static const int                cfgBenchmark14_Iterations       =       8192;
+       static const int                cfgBenchmark14_Reference        =       3500;
+       //[15] culling(KDOP+qsort)
+       bool                                    cfgBenchmark15_Enable           =       cfgEnable;
+       static const int                cfgBenchmark15_Iterations       =       8192;
+       static const int                cfgBenchmark15_Reference        =       1151;
+       //[16] insert/remove batch
+       bool                                    cfgBenchmark16_Enable           =       cfgEnable;
+       static const int                cfgBenchmark16_BatchCount       =       256;
+       static const int                cfgBenchmark16_Passes           =       16384;
+       static const int                cfgBenchmark16_Reference        =       5138;
+       //[17] select
+       bool                                    cfgBenchmark17_Enable           =       cfgEnable;
+       static const int                cfgBenchmark17_Iterations       =       4;
+       static const int                cfgBenchmark17_Reference        =       3390;
 
-btClock                                        wallclock;
-printf("Benchmarking dbvt...\r\n");
-printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
-printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
-printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
-printf("\tLeaves: %u\r\n",cfgLeaves);
-printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
-printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
-if(cfgBenchmark1_Enable)
+       btClock                                 wallclock;
+       printf("Benchmarking dbvt...\r\n");
+       printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
+       printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
+       printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
+       printf("\tLeaves: %u\r\n",cfgLeaves);
+       printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
+       printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
+       if(cfgBenchmark1_Enable)
        {// Benchmark 1 
-       srand(380843);
-       btAlignedObjectArray<btDbvtVolume>      volumes;
-       btAlignedObjectArray<bool>                      results;
-       volumes.resize(cfgLeaves);
-       results.resize(cfgLeaves);
-       for(int i=0;i<cfgLeaves;++i)
+               srand(380843);
+               btAlignedObjectArray<btDbvtVolume>      volumes;
+               btAlignedObjectArray<bool>                      results;
+               volumes.resize(cfgLeaves);
+               results.resize(cfgLeaves);
+               for(int i=0;i<cfgLeaves;++i)
                {
-               volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+                       volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
                }
-       printf("[1] btDbvtVolume intersections: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark1_Iterations;++i)
+               printf("[1] btDbvtVolume intersections: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark1_Iterations;++i)
                {
-               for(int j=0;j<cfgLeaves;++j)
+                       for(int j=0;j<cfgLeaves;++j)
                        {
-                       for(int k=0;k<cfgLeaves;++k)
+                               for(int k=0;k<cfgLeaves;++k)
                                {
-                               results[k]=Intersect(volumes[j],volumes[k]);
+                                       results[k]=Intersect(volumes[j],volumes[k]);
                                }
                        }
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
        }
-if(cfgBenchmark2_Enable)
+       if(cfgBenchmark2_Enable)
        {// Benchmark 2 
-       srand(380843);
-       btAlignedObjectArray<btDbvtVolume>      volumes;
-       btAlignedObjectArray<btDbvtVolume>      results;
-       volumes.resize(cfgLeaves);
-       results.resize(cfgLeaves);
-       for(int i=0;i<cfgLeaves;++i)
+               srand(380843);
+               btAlignedObjectArray<btDbvtVolume>      volumes;
+               btAlignedObjectArray<btDbvtVolume>      results;
+               volumes.resize(cfgLeaves);
+               results.resize(cfgLeaves);
+               for(int i=0;i<cfgLeaves;++i)
                {
-               volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+                       volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
                }
-       printf("[2] btDbvtVolume merges: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark2_Iterations;++i)
+               printf("[2] btDbvtVolume merges: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark2_Iterations;++i)
                {
-               for(int j=0;j<cfgLeaves;++j)
+                       for(int j=0;j<cfgLeaves;++j)
                        {
-                       for(int k=0;k<cfgLeaves;++k)
+                               for(int k=0;k<cfgLeaves;++k)
                                {
-                               Merge(volumes[j],volumes[k],results[k]);
+                                       Merge(volumes[j],volumes[k],results[k]);
                                }
                        }
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
        }
-if(cfgBenchmark3_Enable)
+       if(cfgBenchmark3_Enable)
        {// Benchmark 3 
-       srand(380843);
-       btDbvt                                          dbvt[2];
-       btDbvtBenchmark::NilPolicy      policy;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
-       dbvt[0].optimizeTopDown();
-       dbvt[1].optimizeTopDown();
-       printf("[3] btDbvt::collideTT: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark3_Iterations;++i)
+               srand(380843);
+               btDbvt                                          dbvt[2];
+               btDbvtBenchmark::NilPolicy      policy;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+               dbvt[0].optimizeTopDown();
+               dbvt[1].optimizeTopDown();
+               printf("[3] btDbvt::collideTT: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark3_Iterations;++i)
                {
-               btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
+                       btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
        }
-if(cfgBenchmark4_Enable)
+       if(cfgBenchmark4_Enable)
        {// Benchmark 4
-       srand(380843);
-       btDbvt                                          dbvt;
-       btDbvtBenchmark::NilPolicy      policy;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[4] btDbvt::collideTT self: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark4_Iterations;++i)
+               srand(380843);
+               btDbvt                                          dbvt;
+               btDbvtBenchmark::NilPolicy      policy;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[4] btDbvt::collideTT self: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark4_Iterations;++i)
                {
-               btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
+                       btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
        }
-if(cfgBenchmark5_Enable)
+       if(cfgBenchmark5_Enable)
        {// Benchmark 5 
-       srand(380843);
-       btDbvt                                                          dbvt[2];
-       btAlignedObjectArray<btTransform>       transforms;
-       btDbvtBenchmark::NilPolicy                      policy;
-       transforms.resize(cfgBenchmark5_Iterations);
-       for(int i=0;i<transforms.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt[2];
+               btAlignedObjectArray<btTransform>       transforms;
+               btDbvtBenchmark::NilPolicy                      policy;
+               transforms.resize(cfgBenchmark5_Iterations);
+               for(int i=0;i<transforms.size();++i)
                {
-               transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
+                       transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
-       dbvt[0].optimizeTopDown();
-       dbvt[1].optimizeTopDown();
-       printf("[5] btDbvt::collideTT xform: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark5_Iterations;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+               dbvt[0].optimizeTopDown();
+               dbvt[1].optimizeTopDown();
+               printf("[5] btDbvt::collideTT xform: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark5_Iterations;++i)
                {
-               btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
+                       btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
        }
-if(cfgBenchmark6_Enable)
+       if(cfgBenchmark6_Enable)
        {// Benchmark 6 
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btTransform>       transforms;
-       btDbvtBenchmark::NilPolicy                      policy;
-       transforms.resize(cfgBenchmark6_Iterations);
-       for(int i=0;i<transforms.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btTransform>       transforms;
+               btDbvtBenchmark::NilPolicy                      policy;
+               transforms.resize(cfgBenchmark6_Iterations);
+               for(int i=0;i<transforms.size();++i)
                {
-               transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
+                       transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[6] btDbvt::collideTT xform,self: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark6_Iterations;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[6] btDbvt::collideTT xform,self: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark6_Iterations;++i)
                {
-               btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);                
+                       btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);                
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
        }
-if(cfgBenchmark7_Enable)
+       if(cfgBenchmark7_Enable)
        {// Benchmark 7 
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btVector3>         rayorg;
-       btAlignedObjectArray<btVector3>         raydir;
-       btDbvtBenchmark::NilPolicy                      policy;
-       rayorg.resize(cfgBenchmark7_Iterations);
-       raydir.resize(cfgBenchmark7_Iterations);
-       for(int i=0;i<rayorg.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btVector3>         rayorg;
+               btAlignedObjectArray<btVector3>         raydir;
+               btDbvtBenchmark::NilPolicy                      policy;
+               rayorg.resize(cfgBenchmark7_Iterations);
+               raydir.resize(cfgBenchmark7_Iterations);
+               for(int i=0;i<rayorg.size();++i)
                {
-               rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
-               raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+                       rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+                       raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[7] btDbvt::collideRAY: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark7_Passes;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[7] btDbvt::rayTest: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark7_Passes;++i)
                {
-               for(int j=0;j<cfgBenchmark7_Iterations;++j)
+                       for(int j=0;j<cfgBenchmark7_Iterations;++j)
                        {
-                       btDbvt::collideRAY(dbvt.m_root,rayorg[j],raydir[j],policy);
+                               btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
                        }
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       unsigned        rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
-       printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               unsigned        rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
+               printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
        }
-if(cfgBenchmark8_Enable)
+       if(cfgBenchmark8_Enable)
        {// Benchmark 8 
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[8] insert/remove: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark8_Passes;++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[8] insert/remove: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark8_Passes;++i)
                {
-               for(int j=0;j<cfgBenchmark8_Iterations;++j)
+                       for(int j=0;j<cfgBenchmark8_Iterations;++j)
                        {
-                       dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+                               dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
                        }
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
-       printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
+               printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
        }
-if(cfgBenchmark9_Enable)
+       if(cfgBenchmark9_Enable)
        {// Benchmark 9 
-       srand(380843);
-       btDbvt                                                                          dbvt;
-       btAlignedObjectArray<const btDbvtNode*> leaves;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       dbvt.extractLeaves(dbvt.m_root,leaves);
-       printf("[9] updates (teleport): ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark9_Passes;++i)
+               srand(380843);
+               btDbvt                                                                          dbvt;
+               btAlignedObjectArray<const btDbvtNode*> leaves;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               dbvt.extractLeaves(dbvt.m_root,leaves);
+               printf("[9] updates (teleport): ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark9_Passes;++i)
                {
-               for(int j=0;j<cfgBenchmark9_Iterations;++j)
+                       for(int j=0;j<cfgBenchmark9_Iterations;++j)
                        {
-                       dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
-                                               btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
+                               dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
+                                       btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
                        }
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
-       printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
+               printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
        }
-if(cfgBenchmark10_Enable)
+       if(cfgBenchmark10_Enable)
        {// Benchmark 10        
-       srand(380843);
-       btDbvt                                                                          dbvt;
-       btAlignedObjectArray<const btDbvtNode*> leaves;
-       btAlignedObjectArray<btVector3>                         vectors;
-       vectors.resize(cfgBenchmark10_Iterations);
-       for(int i=0;i<vectors.size();++i)
+               srand(380843);
+               btDbvt                                                                          dbvt;
+               btAlignedObjectArray<const btDbvtNode*> leaves;
+               btAlignedObjectArray<btVector3>                         vectors;
+               vectors.resize(cfgBenchmark10_Iterations);
+               for(int i=0;i<vectors.size();++i)
                {
-               vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
+                       vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       dbvt.extractLeaves(dbvt.m_root,leaves);
-       printf("[10] updates (jitter): ");
-       wallclock.reset();
-       
-       for(int i=0;i<cfgBenchmark10_Passes;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               dbvt.extractLeaves(dbvt.m_root,leaves);
+               printf("[10] updates (jitter): ");
+               wallclock.reset();
+
+               for(int i=0;i<cfgBenchmark10_Passes;++i)
                {
-               for(int j=0;j<cfgBenchmark10_Iterations;++j)
+                       for(int j=0;j<cfgBenchmark10_Iterations;++j)
                        {                       
-                       const btVector3&        d=vectors[j];
-                       btDbvtNode*             l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
-                       btDbvtVolume            v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
-                       dbvt.update(l,v);
+                               const btVector3&        d=vectors[j];
+                               btDbvtNode*             l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
+                               btDbvtVolume            v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
+                               dbvt.update(l,v);
                        }
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
-       printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
+               printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
        }
-if(cfgBenchmark11_Enable)
+       if(cfgBenchmark11_Enable)
        {// Benchmark 11        
-       srand(380843);
-       btDbvt                                                                          dbvt;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[11] optimize (incremental): ");
-       wallclock.reset();      
-       for(int i=0;i<cfgBenchmark11_Passes;++i)
+               srand(380843);
+               btDbvt                                                                          dbvt;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[11] optimize (incremental): ");
+               wallclock.reset();      
+               for(int i=0;i<cfgBenchmark11_Passes;++i)
                {
-               dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
+                       dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
-       printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
+               printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
        }
-if(cfgBenchmark12_Enable)
+       if(cfgBenchmark12_Enable)
        {// Benchmark 12        
-       srand(380843);
-       btAlignedObjectArray<btDbvtVolume>      volumes;
-       btAlignedObjectArray<bool>                              results;
-       volumes.resize(cfgLeaves);
-       results.resize(cfgLeaves);
-       for(int i=0;i<cfgLeaves;++i)
+               srand(380843);
+               btAlignedObjectArray<btDbvtVolume>      volumes;
+               btAlignedObjectArray<bool>                              results;
+               volumes.resize(cfgLeaves);
+               results.resize(cfgLeaves);
+               for(int i=0;i<cfgLeaves;++i)
                {
-               volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+                       volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
                }
-       printf("[12] btDbvtVolume notequal: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark12_Iterations;++i)
+               printf("[12] btDbvtVolume notequal: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark12_Iterations;++i)
                {
-               for(int j=0;j<cfgLeaves;++j)
+                       for(int j=0;j<cfgLeaves;++j)
                        {
-                       for(int k=0;k<cfgLeaves;++k)
+                               for(int k=0;k<cfgLeaves;++k)
                                {
-                               results[k]=NotEqual(volumes[j],volumes[k]);
+                                       results[k]=NotEqual(volumes[j],volumes[k]);
                                }
                        }
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
        }
-if(cfgBenchmark13_Enable)
+       if(cfgBenchmark13_Enable)
        {// Benchmark 13        
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btVector3>         vectors;
-       btDbvtBenchmark::NilPolicy                      policy;
-       vectors.resize(cfgBenchmark13_Iterations);
-       for(int i=0;i<vectors.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btVector3>         vectors;
+               btDbvtBenchmark::NilPolicy                      policy;
+               vectors.resize(cfgBenchmark13_Iterations);
+               for(int i=0;i<vectors.size();++i)
                {
-               vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+                       vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       printf("[13] culling(OCL+fullsort): ");
-       wallclock.reset();      
-       for(int i=0;i<cfgBenchmark13_Iterations;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               printf("[13] culling(OCL+fullsort): ");
+               wallclock.reset();      
+               for(int i=0;i<cfgBenchmark13_Iterations;++i)
                {
-               static const btScalar   offset=0;
-               policy.m_depth=-SIMD_INFINITY;
-               dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
+                       static const btScalar   offset=0;
+                       policy.m_depth=-SIMD_INFINITY;
+                       dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       t=cfgBenchmark13_Iterations;
-       printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       t=cfgBenchmark13_Iterations;
+               printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
        }
-if(cfgBenchmark14_Enable)
+       if(cfgBenchmark14_Enable)
        {// Benchmark 14        
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btVector3>         vectors;
-       btDbvtBenchmark::P14                            policy;
-       vectors.resize(cfgBenchmark14_Iterations);
-       for(int i=0;i<vectors.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btVector3>         vectors;
+               btDbvtBenchmark::P14                            policy;
+               vectors.resize(cfgBenchmark14_Iterations);
+               for(int i=0;i<vectors.size();++i)
                {
-               vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+                       vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       policy.m_nodes.reserve(cfgLeaves);
-       printf("[14] culling(OCL+qsort): ");
-       wallclock.reset();      
-       for(int i=0;i<cfgBenchmark14_Iterations;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               policy.m_nodes.reserve(cfgLeaves);
+               printf("[14] culling(OCL+qsort): ");
+               wallclock.reset();      
+               for(int i=0;i<cfgBenchmark14_Iterations;++i)
                {
-               static const btScalar   offset=0;
-               policy.m_nodes.resize(0);
-               dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
-               policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
+                       static const btScalar   offset=0;
+                       policy.m_nodes.resize(0);
+                       dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
+                       policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       t=cfgBenchmark14_Iterations;
-       printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       t=cfgBenchmark14_Iterations;
+               printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
        }
-if(cfgBenchmark15_Enable)
+       if(cfgBenchmark15_Enable)
        {// Benchmark 15        
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btVector3>         vectors;
-       btDbvtBenchmark::P15                            policy;
-       vectors.resize(cfgBenchmark15_Iterations);
-       for(int i=0;i<vectors.size();++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btVector3>         vectors;
+               btDbvtBenchmark::P15                            policy;
+               vectors.resize(cfgBenchmark15_Iterations);
+               for(int i=0;i<vectors.size();++i)
                {
-               vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+                       vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
                }
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       policy.m_nodes.reserve(cfgLeaves);
-       printf("[15] culling(KDOP+qsort): ");
-       wallclock.reset();      
-       for(int i=0;i<cfgBenchmark15_Iterations;++i)
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               policy.m_nodes.reserve(cfgLeaves);
+               printf("[15] culling(KDOP+qsort): ");
+               wallclock.reset();      
+               for(int i=0;i<cfgBenchmark15_Iterations;++i)
                {
-               static const btScalar   offset=0;
-               policy.m_nodes.resize(0);
-               policy.m_axis=vectors[i];
-               dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
-               policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
+                       static const btScalar   offset=0;
+                       policy.m_nodes.resize(0);
+                       policy.m_axis=vectors[i];
+                       dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
+                       policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       t=cfgBenchmark15_Iterations;
-       printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       t=cfgBenchmark15_Iterations;
+               printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
        }
-if(cfgBenchmark16_Enable)
+       if(cfgBenchmark16_Enable)
        {// Benchmark 16        
-       srand(380843);
-       btDbvt                                                          dbvt;
-       btAlignedObjectArray<btDbvtNode*>       batch;
-       btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-       dbvt.optimizeTopDown();
-       batch.reserve(cfgBenchmark16_BatchCount);
-       printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark16_Passes;++i)
+               srand(380843);
+               btDbvt                                                          dbvt;
+               btAlignedObjectArray<btDbvtNode*>       batch;
+               btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+               dbvt.optimizeTopDown();
+               batch.reserve(cfgBenchmark16_BatchCount);
+               printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark16_Passes;++i)
                {
-               for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+                       for(int j=0;j<cfgBenchmark16_BatchCount;++j)
                        {
-                       batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+                               batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
                        }
-               for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+                       for(int j=0;j<cfgBenchmark16_BatchCount;++j)
                        {
-                       dbvt.remove(batch[j]);
+                               dbvt.remove(batch[j]);
                        }
-               batch.resize(0);
+                       batch.resize(0);
                }
-       const int       time=(int)wallclock.getTimeMilliseconds();
-       const int       ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
-       printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
+               const int       time=(int)wallclock.getTimeMilliseconds();
+               const int       ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
+               printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
        }
-if(cfgBenchmark17_Enable)
+       if(cfgBenchmark17_Enable)
        {// Benchmark 17
-       srand(380843);
-       btAlignedObjectArray<btDbvtVolume>      volumes;
-       btAlignedObjectArray<int>                       results;
-       btAlignedObjectArray<int>                       indices;
-       volumes.resize(cfgLeaves);
-       results.resize(cfgLeaves);
-       indices.resize(cfgLeaves);
-       for(int i=0;i<cfgLeaves;++i)
+               srand(380843);
+               btAlignedObjectArray<btDbvtVolume>      volumes;
+               btAlignedObjectArray<int>                       results;
+               btAlignedObjectArray<int>                       indices;
+               volumes.resize(cfgLeaves);
+               results.resize(cfgLeaves);
+               indices.resize(cfgLeaves);
+               for(int i=0;i<cfgLeaves;++i)
                {
-               indices[i]=i;
-               volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+                       indices[i]=i;
+                       volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
                }
-       for(int i=0;i<cfgLeaves;++i)
+               for(int i=0;i<cfgLeaves;++i)
                {
-               btSwap(indices[i],indices[rand()%cfgLeaves]);
+                       btSwap(indices[i],indices[rand()%cfgLeaves]);
                }
-       printf("[17] btDbvtVolume select: ");
-       wallclock.reset();
-       for(int i=0;i<cfgBenchmark17_Iterations;++i)
+               printf("[17] btDbvtVolume select: ");
+               wallclock.reset();
+               for(int i=0;i<cfgBenchmark17_Iterations;++i)
                {
-               for(int j=0;j<cfgLeaves;++j)
+                       for(int j=0;j<cfgLeaves;++j)
                        {
-                       for(int k=0;k<cfgLeaves;++k)
+                               for(int k=0;k<cfgLeaves;++k)
                                {
-                               const int idx=indices[k];
-                               results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
+                                       const int idx=indices[k];
+                                       results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
                                }
                        }
                }
-       const int time=(int)wallclock.getTimeMilliseconds();
-       printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
+               const int time=(int)wallclock.getTimeMilliseconds();
+               printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
        }
-printf("\r\n\r\n");
+       printf("\r\n\r\n");
 }
 #endif
index 21d69ac..d3cf1e7 100644 (file)
@@ -20,6 +20,7 @@ subject to the following restrictions:
 #include "LinearMath/btAlignedObjectArray.h"
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btTransform.h"
+#include "LinearMath/btAabbUtil2.h"
 
 //
 // Compile time configuration
@@ -31,11 +32,11 @@ subject to the following restrictions:
 #define DBVT_IMPL_SSE                  1       // SSE
 
 // Template implementation of ICollide
-#ifdef WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER //there is always some weird compiler that breaks SSE builds
-       #if (defined (_MSC_VER) && _MSC_VER >= 1400)
-       #define DBVT_USE_TEMPLATE               1
-       #else
-       #define DBVT_USE_TEMPLATE               0
+#ifdef WIN32
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+#define        DBVT_USE_TEMPLATE               1
+#else
+#define        DBVT_USE_TEMPLATE               0
 #endif
 #else
 #define        DBVT_USE_TEMPLATE               0
@@ -52,16 +53,11 @@ subject to the following restrictions:
 
 // Inlining
 #define DBVT_INLINE                            SIMD_FORCE_INLINE
-// Align
-#ifdef WIN32
-#define DBVT_ALIGN                             __declspec(align(16))
-#else
-#define DBVT_ALIGN
-#endif
 
 // Specific methods implementation
 
-#ifdef WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER //there is always some weird compiler that breaks SSE builds
+//SSE gives errors on a MSVC 7.1
+#ifdef BT_USE_SSE
 #define DBVT_SELECT_IMPL               DBVT_IMPL_SSE
 #define DBVT_MERGE_IMPL                        DBVT_IMPL_SSE
 #define DBVT_INT0_IMPL                 DBVT_IMPL_SSE
@@ -86,7 +82,7 @@ subject to the following restrictions:
 #define DBVT_VIRTUAL_DTOR(a)
 #define DBVT_PREFIX                                    template <typename T>
 #define DBVT_IPOLICY                           T& policy
-#define DBVT_CHECKTYPE                         static const ICollide&  typechecker=*(T*)0;
+#define DBVT_CHECKTYPE                         static const ICollide&  typechecker=*(T*)1;(void)typechecker;
 #else
 #define        DBVT_VIRTUAL_DTOR(a)            virtual ~a() {}
 #define DBVT_VIRTUAL                           virtual
@@ -133,46 +129,41 @@ subject to the following restrictions:
 /* btDbvtAabbMm                        */ 
 struct btDbvtAabbMm
 {
-DBVT_INLINE btVector3                  Center() const  { return((mi+mx)/2); }
-DBVT_INLINE btVector3                  Lengths() const { return(mx-mi); }
-DBVT_INLINE btVector3                  Extents() const { return((mx-mi)/2); }
-DBVT_INLINE const btVector3&   Mins() const    { return(mi); }
-DBVT_INLINE const btVector3&   Maxs() const    { return(mx); }
-static inline btDbvtAabbMm             FromCE(const btVector3& c,const btVector3& e);
-static inline btDbvtAabbMm             FromCR(const btVector3& c,btScalar r);
-static inline btDbvtAabbMm             FromMM(const btVector3& mi,const btVector3& mx);
-static inline btDbvtAabbMm             FromPoints(const btVector3* pts,int n);
-static inline btDbvtAabbMm             FromPoints(const btVector3** ppts,int n);
-DBVT_INLINE void                               Expand(const btVector3& e);
-DBVT_INLINE void                               SignedExpand(const btVector3& e);
-DBVT_INLINE bool                               Contain(const btDbvtAabbMm& a) const;
-DBVT_INLINE int                                        Classify(const btVector3& n,btScalar o,int s) const;
-DBVT_INLINE btScalar                   ProjectMinimum(const btVector3& v,unsigned signs) const;
-DBVT_INLINE friend bool                        Intersect(      const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b);
-DBVT_INLINE friend bool                        Intersect(      const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b,
-                                                                                       const btTransform& xform);
-DBVT_INLINE friend bool                        Intersect(      const btDbvtAabbMm& a,
-                                                                                       const btVector3& b);
-DBVT_INLINE friend bool                        Intersect(      const btDbvtAabbMm& a,
-                                                                                       const btVector3& org,
-                                                                                       const btVector3& invdir,
-                                                                                       const unsigned* signs);
-DBVT_INLINE friend btScalar            Proximity(      const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b);
-DBVT_INLINE friend int                 Select(         const btDbvtAabbMm& o,
-                                                                                       const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b);
-DBVT_INLINE friend void                        Merge(          const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b,
-                                                                                       btDbvtAabbMm& r);
-DBVT_INLINE friend bool                        NotEqual(       const btDbvtAabbMm& a,
-                                                                                       const btDbvtAabbMm& b);
+       DBVT_INLINE btVector3                   Center() const  { return((mi+mx)/2); }
+       DBVT_INLINE btVector3                   Lengths() const { return(mx-mi); }
+       DBVT_INLINE btVector3                   Extents() const { return((mx-mi)/2); }
+       DBVT_INLINE const btVector3&    Mins() const    { return(mi); }
+       DBVT_INLINE const btVector3&    Maxs() const    { return(mx); }
+       static inline btDbvtAabbMm              FromCE(const btVector3& c,const btVector3& e);
+       static inline btDbvtAabbMm              FromCR(const btVector3& c,btScalar r);
+       static inline btDbvtAabbMm              FromMM(const btVector3& mi,const btVector3& mx);
+       static inline btDbvtAabbMm              FromPoints(const btVector3* pts,int n);
+       static inline btDbvtAabbMm              FromPoints(const btVector3** ppts,int n);
+       DBVT_INLINE void                                Expand(const btVector3& e);
+       DBVT_INLINE void                                SignedExpand(const btVector3& e);
+       DBVT_INLINE bool                                Contain(const btDbvtAabbMm& a) const;
+       DBVT_INLINE int                                 Classify(const btVector3& n,btScalar o,int s) const;
+       DBVT_INLINE btScalar                    ProjectMinimum(const btVector3& v,unsigned signs) const;
+       DBVT_INLINE friend bool                 Intersect(      const btDbvtAabbMm& a,
+               const btDbvtAabbMm& b);
+       
+       DBVT_INLINE friend bool                 Intersect(      const btDbvtAabbMm& a,
+               const btVector3& b);
+
+       DBVT_INLINE friend btScalar             Proximity(      const btDbvtAabbMm& a,
+               const btDbvtAabbMm& b);
+       DBVT_INLINE friend int                  Select(         const btDbvtAabbMm& o,
+               const btDbvtAabbMm& a,
+               const btDbvtAabbMm& b);
+       DBVT_INLINE friend void                 Merge(          const btDbvtAabbMm& a,
+               const btDbvtAabbMm& b,
+               btDbvtAabbMm& r);
+       DBVT_INLINE friend bool                 NotEqual(       const btDbvtAabbMm& a,
+               const btDbvtAabbMm& b);
 private:
-DBVT_INLINE void                               AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
+       DBVT_INLINE void                                AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
 private:
-btVector3      mi,mx;
+       btVector3       mi,mx;
 };
 
 // Types       
@@ -185,88 +176,94 @@ struct    btDbvtNode
        btDbvtNode*             parent;
        DBVT_INLINE bool        isleaf() const          { return(childs[1]==0); }
        DBVT_INLINE bool        isinternal() const      { return(!isleaf()); }
-       union   {
-                       btDbvtNode*     childs[2];
-                       void*   data;
-                       int             dataAsInt;
-                       };
+       union
+       {
+               btDbvtNode*     childs[2];
+               void*   data;
+               int             dataAsInt;
+       };
 };
 
 ///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
 ///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
 ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
 struct btDbvt
-       {
+{
        /* Stack element        */ 
        struct  sStkNN
-               {
+       {
                const btDbvtNode*       a;
                const btDbvtNode*       b;
                sStkNN() {}
                sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
-               };
+       };
        struct  sStkNP
-               {
+       {
                const btDbvtNode*       node;
                int                     mask;
                sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
-               };
+       };
        struct  sStkNPS
-               {
+       {
                const btDbvtNode*       node;
                int                     mask;
                btScalar        value;
                sStkNPS() {}
                sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
-               };
+       };
        struct  sStkCLN
-               {
+       {
                const btDbvtNode*       node;
                btDbvtNode*             parent;
                sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
-               };
+       };
        // Policies/Interfaces
-                       
+
        /* ICollide     */ 
        struct  ICollide
-               {               
+       {               
                DBVT_VIRTUAL_DTOR(ICollide)
-               DBVT_VIRTUAL void       Process(const btDbvtNode*,const btDbvtNode*)            {}
+                       DBVT_VIRTUAL void       Process(const btDbvtNode*,const btDbvtNode*)            {}
                DBVT_VIRTUAL void       Process(const btDbvtNode*)                                      {}
                DBVT_VIRTUAL void       Process(const btDbvtNode* n,btScalar)                   { Process(n); }
                DBVT_VIRTUAL bool       Descent(const btDbvtNode*)                                      { return(true); }
                DBVT_VIRTUAL bool       AllLeaves(const btDbvtNode*)                                    { return(true); }
-               };
+       };
        /* IWriter      */ 
        struct  IWriter
-               {
+       {
                virtual ~IWriter() {}
                virtual void            Prepare(const btDbvtNode* root,int numnodes)=0;
                virtual void            WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
                virtual void            WriteLeaf(const btDbvtNode*,int index,int parent)=0;
-               };
+       };
        /* IClone       */ 
        struct  IClone
-               {
+       {
                virtual ~IClone()       {}
                virtual void            CloneLeaf(btDbvtNode*) {}
-               };
-               
+       };
+
        // Constants
        enum    {
-                       SIMPLE_STACKSIZE        =       64,
-                       DOUBLE_STACKSIZE        =       SIMPLE_STACKSIZE*2
-                       };
-               
+               SIMPLE_STACKSIZE        =       64,
+               DOUBLE_STACKSIZE        =       SIMPLE_STACKSIZE*2
+       };
+
        // Fields
        btDbvtNode*             m_root;
        btDbvtNode*             m_free;
        int                             m_lkhd;
        int                             m_leaves;
        unsigned                m_opath;
+
+       
+       btAlignedObjectArray<sStkNN>    m_stkStack;
+
+
        // Methods
-                                       btDbvt();
-                                       ~btDbvt();
+       btDbvt();
+       ~btDbvt();
        void                    clear();
        bool                    empty() const { return(0==m_root); }
        void                    optimizeBottomUp();
@@ -274,95 +271,118 @@ struct   btDbvt
        void                    optimizeIncremental(int passes);
        btDbvtNode*             insert(const btDbvtVolume& box,void* data);
        void                    update(btDbvtNode* leaf,int lookahead=-1);
-       void                    update(btDbvtNode* leaf,const btDbvtVolume& volume);
-       bool                    update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin);
-       bool                    update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity);
-       bool                    update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin);   
+       void                    update(btDbvtNode* leaf,btDbvtVolume& volume);
+       bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
+       bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
+       bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);  
        void                    remove(btDbvtNode* leaf);
        void                    write(IWriter* iwriter) const;
        void                    clone(btDbvt& dest,IClone* iclone=0) const;
        static int              maxdepth(const btDbvtNode* node);
        static int              countLeaves(const btDbvtNode* node);
        static void             extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
-       #if DBVT_ENABLE_BENCHMARK
+#if DBVT_ENABLE_BENCHMARK
        static void             benchmark();
-       #else
+#else
        static void             benchmark(){}
-       #endif
+#endif
        // DBVT_IPOLICY must support ICollide policy/interface
        DBVT_PREFIX
-       static void             enumNodes(      const btDbvtNode* root,
-                                                               DBVT_IPOLICY);
+               static void             enumNodes(      const btDbvtNode* root,
+               DBVT_IPOLICY);
+       DBVT_PREFIX
+               static void             enumLeaves(     const btDbvtNode* root,
+               DBVT_IPOLICY);
        DBVT_PREFIX
-       static void             enumLeaves(     const btDbvtNode* root,
-                                                               DBVT_IPOLICY);
+               void            collideTT(      const btDbvtNode* root0,
+               const btDbvtNode* root1,
+               DBVT_IPOLICY);
+
        DBVT_PREFIX
-       static void             collideTT(      const btDbvtNode* root0,
-                                                               const btDbvtNode* root1,
-                                                               DBVT_IPOLICY);
+               void            collideTTpersistentStack(       const btDbvtNode* root0,
+                 const btDbvtNode* root1,
+                 DBVT_IPOLICY);
+#if 0
        DBVT_PREFIX
-       static void             collideTT(      const btDbvtNode* root0,
-                                                               const btDbvtNode* root1,
-                                                               const btTransform& xform,
-                                                               DBVT_IPOLICY);
+               void            collideTT(      const btDbvtNode* root0,
+               const btDbvtNode* root1,
+               const btTransform& xform,
+               DBVT_IPOLICY);
        DBVT_PREFIX
-       static void             collideTT(      const btDbvtNode* root0,
-                                                               const btTransform& xform0,
-                                                               const btDbvtNode* root1,
-                                                               const btTransform& xform1,
-                                                               DBVT_IPOLICY);
+               void            collideTT(      const btDbvtNode* root0,
+               const btTransform& xform0,
+               const btDbvtNode* root1,
+               const btTransform& xform1,
+               DBVT_IPOLICY);
+#endif
+
        DBVT_PREFIX
-       static void             collideTV(      const btDbvtNode* root,
-                                                               const btDbvtVolume& volume,
-                                                               DBVT_IPOLICY);
+               void            collideTV(      const btDbvtNode* root,
+               const btDbvtVolume& volume,
+               DBVT_IPOLICY);
+       ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
+       ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
        DBVT_PREFIX
-       static void             collideRAY(     const btDbvtNode* root,
-                                                               const btVector3& origin,
-                                                               const btVector3& direction,
-                                                               DBVT_IPOLICY);
+               static void             rayTest(        const btDbvtNode* root,
+               const btVector3& rayFrom,
+               const btVector3& rayTo,
+               DBVT_IPOLICY);
+       ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
+       ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
        DBVT_PREFIX
-       static void             collideKDOP(const btDbvtNode* root,
-                                                               const btVector3* normals,
-                                                               const btScalar* offsets,
-                                                               int count,
-                                                               DBVT_IPOLICY);
+               void            rayTestInternal(        const btDbvtNode* root,
+                                                               const btVector3& rayFrom,
+                                                               const btVector3& rayTo,
+                                                               const btVector3& rayDirectionInverse,
+                                                               unsigned int signs[3],
+                                                               btScalar lambda_max,
+                                                               const btVector3& aabbMin,
+                                                               const btVector3& aabbMax,
+                                                               DBVT_IPOLICY) const;
+
        DBVT_PREFIX
-       static void             collideOCL(     const btDbvtNode* root,
-                                                               const btVector3* normals,
-                                                               const btScalar* offsets,
-                                                               const btVector3& sortaxis,
-                                                               int count,                                                              
-                                                               DBVT_IPOLICY,
-                                                               bool fullsort=true);
+               static void             collideKDOP(const btDbvtNode* root,
+               const btVector3* normals,
+               const btScalar* offsets,
+               int count,
+               DBVT_IPOLICY);
        DBVT_PREFIX
-       static void             collideTU(      const btDbvtNode* root,
-                                                               DBVT_IPOLICY);
+               static void             collideOCL(     const btDbvtNode* root,
+               const btVector3* normals,
+               const btScalar* offsets,
+               const btVector3& sortaxis,
+               int count,                                                              
+               DBVT_IPOLICY,
+               bool fullsort=true);
+       DBVT_PREFIX
+               static void             collideTU(      const btDbvtNode* root,
+               DBVT_IPOLICY);
        // Helpers      
        static DBVT_INLINE int  nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
-               {
+       {
                int     m=0;
                while(l<h)
-                       {
+               {
                        m=(l+h)>>1;
                        if(a[i[m]].value>=v) l=m+1; else h=m;
-                       }
-               return(h);
                }
+               return(h);
+       }
        static DBVT_INLINE int  allocate(       btAlignedObjectArray<int>& ifree,
-                                                                               btAlignedObjectArray<sStkNPS>& stock,
-                                                                               const sStkNPS& value)
-               {
+               btAlignedObjectArray<sStkNPS>& stock,
+               const sStkNPS& value)
+       {
                int     i;
                if(ifree.size()>0)
-                       { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
-                       else
-                       { i=stock.size();stock.push_back(value); }
+               { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
+               else
+               { i=stock.size();stock.push_back(value); }
                return(i); 
-               }
+       }
        //
-       private:
-                                       btDbvt(const btDbvt&)   {}      
-       };
+private:
+       btDbvt(const btDbvt&)   {}      
+};
 
 //
 // Inline's
@@ -371,69 +391,69 @@ struct    btDbvt
 //
 inline btDbvtAabbMm                    btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
 {
-btDbvtAabbMm box;
-box.mi=c-e;box.mx=c+e;
-return(box);
+       btDbvtAabbMm box;
+       box.mi=c-e;box.mx=c+e;
+       return(box);
 }
-       
+
 //
 inline btDbvtAabbMm                    btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
 {
-return(FromCE(c,btVector3(r,r,r)));
+       return(FromCE(c,btVector3(r,r,r)));
 }
-       
+
 //
 inline btDbvtAabbMm                    btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
 {
-btDbvtAabbMm box;
-box.mi=mi;box.mx=mx;
-return(box);
+       btDbvtAabbMm box;
+       box.mi=mi;box.mx=mx;
+       return(box);
 }
-       
+
 //
 inline btDbvtAabbMm                    btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
 {
-btDbvtAabbMm box;
-box.mi=box.mx=pts[0];
-for(int i=1;i<n;++i)
+       btDbvtAabbMm box;
+       box.mi=box.mx=pts[0];
+       for(int i=1;i<n;++i)
        {
-       box.mi.setMin(pts[i]);
-       box.mx.setMax(pts[i]);
+               box.mi.setMin(pts[i]);
+               box.mx.setMax(pts[i]);
        }
-return(box);
+       return(box);
 }
 
 //
 inline btDbvtAabbMm                    btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
 {
-btDbvtAabbMm box;
-box.mi=box.mx=*ppts[0];
-for(int i=1;i<n;++i)
+       btDbvtAabbMm box;
+       box.mi=box.mx=*ppts[0];
+       for(int i=1;i<n;++i)
        {
-       box.mi.setMin(*ppts[i]);
-       box.mx.setMax(*ppts[i]);
+               box.mi.setMin(*ppts[i]);
+               box.mx.setMax(*ppts[i]);
        }
-return(box);
+       return(box);
 }
 
 //
 DBVT_INLINE void               btDbvtAabbMm::Expand(const btVector3& e)
 {
-mi-=e;mx+=e;
+       mi-=e;mx+=e;
 }
-       
+
 //
 DBVT_INLINE void               btDbvtAabbMm::SignedExpand(const btVector3& e)
 {
-if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
-if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
-if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
+       if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
+       if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
+       if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
 }
-       
+
 //
 DBVT_INLINE bool               btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
 {
-return(        (mi.x()<=a.mi.x())&&
+       return( (mi.x()<=a.mi.x())&&
                (mi.y()<=a.mi.y())&&
                (mi.z()<=a.mi.z())&&
                (mx.x()>=a.mx.x())&&
@@ -444,64 +464,64 @@ return(   (mi.x()<=a.mi.x())&&
 //
 DBVT_INLINE int                btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
 {
-btVector3                      pi,px;
-switch(s)
+       btVector3                       pi,px;
+       switch(s)
        {
        case    (0+0+0):        px=btVector3(mi.x(),mi.y(),mi.z());
-                                               pi=btVector3(mx.x(),mx.y(),mx.z());break;
+               pi=btVector3(mx.x(),mx.y(),mx.z());break;
        case    (1+0+0):        px=btVector3(mx.x(),mi.y(),mi.z());
-                                               pi=btVector3(mi.x(),mx.y(),mx.z());break;
+               pi=btVector3(mi.x(),mx.y(),mx.z());break;
        case    (0+2+0):        px=btVector3(mi.x(),mx.y(),mi.z());
-                                               pi=btVector3(mx.x(),mi.y(),mx.z());break;
+               pi=btVector3(mx.x(),mi.y(),mx.z());break;
        case    (1+2+0):        px=btVector3(mx.x(),mx.y(),mi.z());
-                                               pi=btVector3(mi.x(),mi.y(),mx.z());break;
+               pi=btVector3(mi.x(),mi.y(),mx.z());break;
        case    (0+0+4):        px=btVector3(mi.x(),mi.y(),mx.z());
-                                               pi=btVector3(mx.x(),mx.y(),mi.z());break;
+               pi=btVector3(mx.x(),mx.y(),mi.z());break;
        case    (1+0+4):        px=btVector3(mx.x(),mi.y(),mx.z());
-                                               pi=btVector3(mi.x(),mx.y(),mi.z());break;
+               pi=btVector3(mi.x(),mx.y(),mi.z());break;
        case    (0+2+4):        px=btVector3(mi.x(),mx.y(),mx.z());
-                                               pi=btVector3(mx.x(),mi.y(),mi.z());break;
+               pi=btVector3(mx.x(),mi.y(),mi.z());break;
        case    (1+2+4):        px=btVector3(mx.x(),mx.y(),mx.z());
-                                               pi=btVector3(mi.x(),mi.y(),mi.z());break;
+               pi=btVector3(mi.x(),mi.y(),mi.z());break;
        }
-if((dot(n,px)+o)<0)            return(-1);
-if((dot(n,pi)+o)>=0)   return(+1);
-return(0);
+       if((dot(n,px)+o)<0)             return(-1);
+       if((dot(n,pi)+o)>=0)    return(+1);
+       return(0);
 }
 
 //
 DBVT_INLINE btScalar   btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
 {
-const btVector3*       b[]={&mx,&mi};
-const btVector3                p(      b[(signs>>0)&1]->x(),
-                                               b[(signs>>1)&1]->y(),
-                                               b[(signs>>2)&1]->z());
-return(dot(p,v));
+       const btVector3*        b[]={&mx,&mi};
+       const btVector3         p(      b[(signs>>0)&1]->x(),
+               b[(signs>>1)&1]->y(),
+               b[(signs>>2)&1]->z());
+       return(dot(p,v));
 }
 
 //
 DBVT_INLINE void               btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
 {
-for(int i=0;i<3;++i)
+       for(int i=0;i<3;++i)
        {
-       if(d[i]<0)
+               if(d[i]<0)
                { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
                else
                { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
        }
 }
-       
+
 //
 DBVT_INLINE bool               Intersect(      const btDbvtAabbMm& a,
-                                                                       const btDbvtAabbMm& b)
+                                                                 const btDbvtAabbMm& b)
 {
 #if    DBVT_INT0_IMPL == DBVT_IMPL_SSE
-const __m128   rt(_mm_or_ps(   _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
-                                                               _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
-const __int32* pu((const __int32*)&rt);
-return((pu[0]|pu[1]|pu[2])==0);
+       const __m128    rt(_mm_or_ps(   _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
+               _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
+       const __int32*  pu((const __int32*)&rt);
+       return((pu[0]|pu[1]|pu[2])==0);
 #else
-return(        (a.mi.x()<=b.mx.x())&&
+       return( (a.mi.x()<=b.mx.x())&&
                (a.mx.x()>=b.mi.x())&&
                (a.mi.y()<=b.mx.y())&&
                (a.mx.y()>=b.mi.y())&&
@@ -510,27 +530,13 @@ return(   (a.mi.x()<=b.mx.x())&&
 #endif
 }
 
-//
-DBVT_INLINE bool               Intersect(      const btDbvtAabbMm& a,
-                                                                       const btDbvtAabbMm& b,
-                                                                       const btTransform& xform)
-{
-const btVector3                d0=xform*b.Center()-a.Center();
-const btVector3                d1=d0*xform.getBasis();
-btScalar                       s0[2]={0,0};
-btScalar                       s1[2]={dot(xform.getOrigin(),d0),s1[0]};
-a.AddSpan(d0,s0[0],s0[1]);
-b.AddSpan(d1,s1[0],s1[1]);
-if(s0[0]>(s1[1])) return(false);
-if(s0[1]<(s1[0])) return(false);
-return(true);
-}
+
 
 //
 DBVT_INLINE bool               Intersect(      const btDbvtAabbMm& a,
-                                                                       const btVector3& b)
+                                                                 const btVector3& b)
 {
-return(        (b.x()>=a.mi.x())&&
+       return( (b.x()>=a.mi.x())&&
                (b.y()>=a.mi.y())&&
                (b.z()>=a.mi.z())&&
                (b.x()<=a.mx.x())&&
@@ -538,55 +544,40 @@ return(   (b.x()>=a.mi.x())&&
                (b.z()<=a.mx.z()));
 }
 
-//
-DBVT_INLINE bool               Intersect(      const btDbvtAabbMm& a,
-                                                                       const btVector3& org,
-                                                                       const btVector3& invdir,
-                                                                       const unsigned* signs)
-{
-#if 0
-const btVector3                b0((a.mi-org)*invdir);
-const btVector3                b1((a.mx-org)*invdir);
-const btVector3                tmin(btMin(b0[0],b1[0]),btMin(b0[1],b1[1]),btMin(b0[2],b1[2]));
-const btVector3                tmax(btMax(b0[0],b1[0]),btMax(b0[1],b1[1]),btMax(b0[2],b1[2]));
-const btScalar         tin=btMax(tmin[0],btMax(tmin[1],tmin[2]));
-const btScalar         tout=btMin(tmax[0],btMin(tmax[1],tmax[2]));
-return(tin<tout);
-#else
-const btVector3*       bounds[2]={&a.mi,&a.mx};
-btScalar                       txmin=(bounds[  signs[0]]->x()-org[0])*invdir[0];
-btScalar                       txmax=(bounds[1-signs[0]]->x()-org[0])*invdir[0];
-const btScalar         tymin=(bounds[  signs[1]]->y()-org[1])*invdir[1];
-const btScalar         tymax=(bounds[1-signs[1]]->y()-org[1])*invdir[1];
-if((txmin>tymax)||(tymin>txmax)) return(false);
-if(tymin>txmin) txmin=tymin;
-if(tymax<txmax) txmax=tymax;
-const btScalar         tzmin=(bounds[  signs[2]]->z()-org[2])*invdir[2];
-const btScalar         tzmax=(bounds[1-signs[2]]->z()-org[2])*invdir[2];
-if((txmin>tzmax)||(tzmin>txmax)) return(false);
-if(tzmin>txmin) txmin=tzmin;
-if(tzmax<txmax) txmax=tzmax;
-return(txmax>0);
-#endif
-}
-       
+
+
+
+
+//////////////////////////////////////
+
+
 //
 DBVT_INLINE btScalar   Proximity(      const btDbvtAabbMm& a,
-                                                                       const btDbvtAabbMm& b)
+                                                                 const btDbvtAabbMm& b)
 {
-const btVector3        d=(a.mi+a.mx)-(b.mi+b.mx);
-return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
+       const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
+       return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
 }
 
+
+
 //
 DBVT_INLINE int                        Select( const btDbvtAabbMm& o,
-                                                               const btDbvtAabbMm& a,
-                                                               const btDbvtAabbMm& b)
+                                                          const btDbvtAabbMm& a,
+                                                          const btDbvtAabbMm& b)
 {
 #if    DBVT_SELECT_IMPL == DBVT_IMPL_SSE
-static DBVT_ALIGN const unsigned __int32       mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
-       // TODO: the intrinsic version is 11% slower
-       #if DBVT_USE_INTRINSIC_SSE
+       static ATTRIBUTE_ALIGNED16(const unsigned __int32)      mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
+       ///@todo: the intrinsic version is 11% slower
+#if DBVT_USE_INTRINSIC_SSE
+
+       union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
+       {
+          __m128               ssereg;
+          float                floats[4];
+          int                  ints[4];
+       };
+
        __m128  omi(_mm_load_ps(o.mi));
        omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
        __m128  ami(_mm_load_ps(a.mi));
@@ -600,74 +591,78 @@ static DBVT_ALIGN const unsigned __int32  mask[]={0x7fffffff,0x7fffffff,0x7ffffff
        __m128  t0(_mm_movehl_ps(ami,ami));
        ami=_mm_add_ps(ami,t0);
        ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
-       __m128  t1(_mm_movehl_ps(bmi,bmi));
+       __m128 t1(_mm_movehl_ps(bmi,bmi));
        bmi=_mm_add_ps(bmi,t1);
        bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
-       return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1);
-       #else
-       DBVT_ALIGN __int32      r[1];
+       
+       btSSEUnion tmp;
+       tmp.ssereg = _mm_cmple_ss(bmi,ami);
+       return tmp.ints[0]&1;
+
+#else
+       ATTRIBUTE_ALIGNED16(__int32     r[1]);
        __asm
-               {
+       {
                mov             eax,o
-               mov             ecx,a
-               mov             edx,b
-               movaps  xmm0,[eax]
+                       mov             ecx,a
+                       mov             edx,b
+                       movaps  xmm0,[eax]
                movaps  xmm5,mask
-               addps   xmm0,[eax+16]   
+                       addps   xmm0,[eax+16]   
                movaps  xmm1,[ecx]
                movaps  xmm2,[edx]
                addps   xmm1,[ecx+16]
                addps   xmm2,[edx+16]
                subps   xmm1,xmm0
-               subps   xmm2,xmm0
-               andps   xmm1,xmm5
-               andps   xmm2,xmm5
-               movhlps xmm3,xmm1
-               movhlps xmm4,xmm2
-               addps   xmm1,xmm3
-               addps   xmm2,xmm4
-               pshufd  xmm3,xmm1,1
-               pshufd  xmm4,xmm2,1
-               addss   xmm1,xmm3
-               addss   xmm2,xmm4
-               cmpless xmm2,xmm1
-               movss   r,xmm2
-               }
+                       subps   xmm2,xmm0
+                       andps   xmm1,xmm5
+                       andps   xmm2,xmm5
+                       movhlps xmm3,xmm1
+                       movhlps xmm4,xmm2
+                       addps   xmm1,xmm3
+                       addps   xmm2,xmm4
+                       pshufd  xmm3,xmm1,1
+                       pshufd  xmm4,xmm2,1
+                       addss   xmm1,xmm3
+                       addss   xmm2,xmm4
+                       cmpless xmm2,xmm1
+                       movss   r,xmm2
+       }
        return(r[0]&1);
-       #endif
+#endif
 #else
-return(Proximity(o,a)<Proximity(o,b)?0:1);
+       return(Proximity(o,a)<Proximity(o,b)?0:1);
 #endif
 }
 
 //
 DBVT_INLINE void               Merge(  const btDbvtAabbMm& a,
-                                                               const btDbvtAabbMm& b,
-                                                               btDbvtAabbMm& r)
+                                                         const btDbvtAabbMm& b,
+                                                         btDbvtAabbMm& r)
 {
 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-__m128 ami(_mm_load_ps(a.mi));
-__m128 amx(_mm_load_ps(a.mx));
-__m128 bmi(_mm_load_ps(b.mi));
-__m128 bmx(_mm_load_ps(b.mx));
-ami=_mm_min_ps(ami,bmi);
-amx=_mm_max_ps(amx,bmx);
-_mm_store_ps(r.mi,ami);
-_mm_store_ps(r.mx,amx);
+       __m128  ami(_mm_load_ps(a.mi));
+       __m128  amx(_mm_load_ps(a.mx));
+       __m128  bmi(_mm_load_ps(b.mi));
+       __m128  bmx(_mm_load_ps(b.mx));
+       ami=_mm_min_ps(ami,bmi);
+       amx=_mm_max_ps(amx,bmx);
+       _mm_store_ps(r.mi,ami);
+       _mm_store_ps(r.mx,amx);
 #else
-for(int i=0;i<3;++i)
+       for(int i=0;i<3;++i)
        {
-       if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
-       if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
+               if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
+               if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
        }
 #endif
 }
 
 //
 DBVT_INLINE bool               NotEqual(       const btDbvtAabbMm& a,
-                                                                       const btDbvtAabbMm& b)
+                                                                const btDbvtAabbMm& b)
 {
-return(        (a.mi.x()!=b.mi.x())||
+       return( (a.mi.x()!=b.mi.x())||
                (a.mi.y()!=b.mi.y())||
                (a.mi.z()!=b.mi.z())||
                (a.mx.x()!=b.mx.x())||
@@ -682,235 +677,383 @@ return( (a.mi.x()!=b.mi.x())||
 //
 DBVT_PREFIX
 inline void            btDbvt::enumNodes(      const btDbvtNode* root,
-                                                                       DBVT_IPOLICY)
+                                                                 DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-policy.Process(root);
-if(root->isinternal())
+       DBVT_CHECKTYPE
+               policy.Process(root);
+       if(root->isinternal())
        {
-       enumNodes(root->childs[0],policy);
-       enumNodes(root->childs[1],policy);
+               enumNodes(root->childs[0],policy);
+               enumNodes(root->childs[1],policy);
        }
 }
 
 //
 DBVT_PREFIX
 inline void            btDbvt::enumLeaves(     const btDbvtNode* root,
-                                                                       DBVT_IPOLICY)
+                                                                  DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root->isinternal())
-       {
-       enumLeaves(root->childs[0],policy);
-       enumLeaves(root->childs[1],policy);
-       }
-       else
-       {
-       policy.Process(root);
-       }
+       DBVT_CHECKTYPE
+               if(root->isinternal())
+               {
+                       enumLeaves(root->childs[0],policy);
+                       enumLeaves(root->childs[1],policy);
+               }
+               else
+               {
+                       policy.Process(root);
+               }
 }
 
 //
 DBVT_PREFIX
 inline void            btDbvt::collideTT(      const btDbvtNode* root0,
-                                                                       const btDbvtNode* root1,
-                                                                       DBVT_IPOLICY)
+                                                                 const btDbvtNode* root1,
+                                                                 DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root0&&root1)
-       {
-       btAlignedObjectArray<sStkNN>    stack;
-       int                                                             depth=1;
-       int                                                             treshold=DOUBLE_STACKSIZE-4;
-       stack.resize(DOUBLE_STACKSIZE);
-       stack[0]=sStkNN(root0,root1);
-       do      {               
-               sStkNN  p=stack[--depth];
-               if(depth>treshold)
-                       {
-                       stack.resize(stack.size()*2);
-                       treshold=stack.size()-4;
-                       }
-               if(p.a==p.b)
-                       {
-                       if(p.a->isinternal())
+       DBVT_CHECKTYPE
+               if(root0&&root1)
+               {
+                       int                                                             depth=1;
+                       int                                                             treshold=DOUBLE_STACKSIZE-4;
+                       btAlignedObjectArray<sStkNN>    stkStack;
+                       stkStack.resize(DOUBLE_STACKSIZE);
+                       stkStack[0]=sStkNN(root0,root1);
+                       do      {               
+                               sStkNN  p=stkStack[--depth];
+                               if(depth>treshold)
                                {
-                               stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
-                               stack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
-                               stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+                                       stkStack.resize(stkStack.size()*2);
+                                       treshold=stkStack.size()-4;
                                }
-                       }
-               else if(Intersect(p.a->volume,p.b->volume))
-                       {
-                       if(p.a->isinternal())
+                               if(p.a==p.b)
                                {
-                               if(p.b->isinternal())
+                                       if(p.a->isinternal())
                                        {
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
-                                       }
-                                       else
-                                       {
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b);
+                                               stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+                                               stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+                                               stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
                                        }
                                }
-                               else
+                               else if(Intersect(p.a->volume,p.b->volume))
                                {
-                               if(p.b->isinternal())
+                                       if(p.a->isinternal())
                                        {
-                                       stack[depth++]=sStkNN(p.a,p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a,p.b->childs[1]);
+                                               if(p.b->isinternal())
+                                               {
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+                                               }
                                        }
                                        else
                                        {
-                                       policy.Process(p.a,p.b);
+                                               if(p.b->isinternal())
+                                               {
+                                                       stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       policy.Process(p.a,p.b);
+                                               }
                                        }
                                }
-                       }
-               } while(depth);
-       }
+                       } while(depth);
+               }
 }
 
-//
+
+
 DBVT_PREFIX
-inline void            btDbvt::collideTT(      const btDbvtNode* root0,
-                                                                       const btDbvtNode* root1,
-                                                                       const btTransform& xform,
-                                                                       DBVT_IPOLICY)
+inline void            btDbvt::collideTTpersistentStack(       const btDbvtNode* root0,
+                                                                 const btDbvtNode* root1,
+                                                                 DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root0&&root1)
-       {
-       btAlignedObjectArray<sStkNN>    stack;
-       int                                                             depth=1;
-       int                                                             treshold=DOUBLE_STACKSIZE-4;
-       stack.resize(DOUBLE_STACKSIZE);
-       stack[0]=sStkNN(root0,root1);
-       do      {
-               sStkNN  p=stack[--depth];
-               if(Intersect(p.a->volume,p.b->volume,xform))
-                       {
-                       if(depth>treshold)
+       DBVT_CHECKTYPE
+               if(root0&&root1)
+               {
+                       int                                                             depth=1;
+                       int                                                             treshold=DOUBLE_STACKSIZE-4;
+                       
+                       m_stkStack.resize(DOUBLE_STACKSIZE);
+                       m_stkStack[0]=sStkNN(root0,root1);
+                       do      {               
+                               sStkNN  p=m_stkStack[--depth];
+                               if(depth>treshold)
                                {
-                               stack.resize(stack.size()*2);
-                               treshold=stack.size()-4;
+                                       m_stkStack.resize(m_stkStack.size()*2);
+                                       treshold=m_stkStack.size()-4;
                                }
-                       if(p.a->isinternal())
+                               if(p.a==p.b)
                                {
-                               if(p.b->isinternal())
-                                       {                                       
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+                                       if(p.a->isinternal())
+                                       {
+                                               m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+                                               m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+                                               m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+                                       }
+                               }
+                               else if(Intersect(p.a->volume,p.b->volume))
+                               {
+                                       if(p.a->isinternal())
+                                       {
+                                               if(p.b->isinternal())
+                                               {
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+                                                       m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+                                               }
                                        }
                                        else
                                        {
-                                       stack[depth++]=sStkNN(p.a->childs[0],p.b);
-                                       stack[depth++]=sStkNN(p.a->childs[1],p.b);
+                                               if(p.b->isinternal())
+                                               {
+                                                       m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+                                                       m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       policy.Process(p.a,p.b);
+                                               }
                                        }
                                }
-                               else
+                       } while(depth);
+               }
+}
+
+#if 0
+//
+DBVT_PREFIX
+inline void            btDbvt::collideTT(      const btDbvtNode* root0,
+                                                                 const btDbvtNode* root1,
+                                                                 const btTransform& xform,
+                                                                 DBVT_IPOLICY)
+{
+       DBVT_CHECKTYPE
+               if(root0&&root1)
+               {
+                       int                                                             depth=1;
+                       int                                                             treshold=DOUBLE_STACKSIZE-4;
+                       btAlignedObjectArray<sStkNN>    stkStack;
+                       stkStack.resize(DOUBLE_STACKSIZE);
+                       stkStack[0]=sStkNN(root0,root1);
+                       do      {
+                               sStkNN  p=stkStack[--depth];
+                               if(Intersect(p.a->volume,p.b->volume,xform))
                                {
-                               if(p.b->isinternal())
+                                       if(depth>treshold)
                                        {
-                                       stack[depth++]=sStkNN(p.a,p.b->childs[0]);
-                                       stack[depth++]=sStkNN(p.a,p.b->childs[1]);
+                                               stkStack.resize(stkStack.size()*2);
+                                               treshold=stkStack.size()-4;
+                                       }
+                                       if(p.a->isinternal())
+                                       {
+                                               if(p.b->isinternal())
+                                               {                                       
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+                                                       stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+                                               }
                                        }
                                        else
                                        {
-                                       policy.Process(p.a,p.b);
+                                               if(p.b->isinternal())
+                                               {
+                                                       stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+                                                       stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+                                               }
+                                               else
+                                               {
+                                                       policy.Process(p.a,p.b);
+                                               }
                                        }
                                }
-                       }
-               } while(depth);
-       }
+                       } while(depth);
+               }
 }
-
 //
 DBVT_PREFIX
 inline void            btDbvt::collideTT(      const btDbvtNode* root0,
-                                                                       const btTransform& xform0,
-                                                                       const btDbvtNode* root1,
-                                                                       const btTransform& xform1,
-                                                                       DBVT_IPOLICY)
+                                                                 const btTransform& xform0,
+                                                                 const btDbvtNode* root1,
+                                                                 const btTransform& xform1,
+                                                                 DBVT_IPOLICY)
 {
-const btTransform      xform=xform0.inverse()*xform1;
-collideTT(root0,root1,xform,policy);
+       const btTransform       xform=xform0.inverse()*xform1;
+       collideTT(root0,root1,xform,policy);
 }
+#endif 
 
 //
 DBVT_PREFIX
 inline void            btDbvt::collideTV(      const btDbvtNode* root,
-                                                                       const btDbvtVolume& vol,
-                                                                       DBVT_IPOLICY)
+                                                                 const btDbvtVolume& vol,
+                                                                 DBVT_IPOLICY)
+{
+       DBVT_CHECKTYPE
+               if(root)
+               {
+                       ATTRIBUTE_ALIGNED16(btDbvtVolume)               volume(vol);
+                       btAlignedObjectArray<const btDbvtNode*> stack;
+                       stack.resize(0);
+                       stack.reserve(SIMPLE_STACKSIZE);
+                       stack.push_back(root);
+                       do      {
+                               const btDbvtNode*       n=stack[stack.size()-1];
+                               stack.pop_back();
+                               if(Intersect(n->volume,volume))
+                               {
+                                       if(n->isinternal())
+                                       {
+                                               stack.push_back(n->childs[0]);
+                                               stack.push_back(n->childs[1]);
+                                       }
+                                       else
+                                       {
+                                               policy.Process(n);
+                                       }
+                               }
+                       } while(stack.size()>0);
+               }
+}
+
+DBVT_PREFIX
+inline void            btDbvt::rayTestInternal(        const btDbvtNode* root,
+                                                               const btVector3& rayFrom,
+                                                               const btVector3& rayTo,
+                                                               const btVector3& rayDirectionInverse,
+                                                               unsigned int signs[3],
+                                                               btScalar lambda_max,
+                                                               const btVector3& aabbMin,
+                                                               const btVector3& aabbMax,
+                                                               DBVT_IPOLICY) const
 {
-DBVT_CHECKTYPE
-if(root)
+       DBVT_CHECKTYPE
+       if(root)
        {
-       ATTRIBUTE_ALIGNED16(btDbvtVolume)               volume(vol);
-       btAlignedObjectArray<const btDbvtNode*> stack;
-       stack.reserve(SIMPLE_STACKSIZE);
-       stack.push_back(root);
-       do      {
-               const btDbvtNode*       n=stack[stack.size()-1];
-               stack.pop_back();
-               if(Intersect(n->volume,volume))
+               btVector3 resultNormal;
+
+               int                                                             depth=1;
+               int                                                             treshold=DOUBLE_STACKSIZE-2;
+               btAlignedObjectArray<const btDbvtNode*> stack;
+               stack.resize(DOUBLE_STACKSIZE);
+               stack[0]=root;
+               btVector3 bounds[2];
+               do      
+               {
+                       const btDbvtNode*       node=stack[--depth];
+                       bounds[0] = node->volume.Mins()+aabbMin;
+                       bounds[1] = node->volume.Maxs()+aabbMax;
+                       btScalar tmin=1.f,lambda_min=0.f;
+                       unsigned int result1=false;
+                       result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+                       if(result1)
                        {
-                       if(n->isinternal())
+                               if(node->isinternal())
                                {
-                               stack.push_back(n->childs[0]);
-                               stack.push_back(n->childs[1]);
+                                       if(depth>treshold)
+                                       {
+                                               stack.resize(stack.size()*2);
+                                               treshold=stack.size()-2;
+                                       }
+                                       stack[depth++]=node->childs[0];
+                                       stack[depth++]=node->childs[1];
                                }
                                else
                                {
-                               policy.Process(n);
+                                       policy.Process(node);
                                }
                        }
-               } while(stack.size()>0);
+               } while(depth);
        }
 }
 
 //
 DBVT_PREFIX
-inline void            btDbvt::collideRAY(     const btDbvtNode* root,
-                                                                       const btVector3& origin,
-                                                                       const btVector3& direction,
-                                                                       DBVT_IPOLICY)
+inline void            btDbvt::rayTest(        const btDbvtNode* root,
+                                                               const btVector3& rayFrom,
+                                                               const btVector3& rayTo,
+                                                               DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root)
-       {
-       const btVector3 normal=direction.normalized();
-       const btVector3 invdir( 1/normal.x(),
-                                                       1/normal.y(),
-                                                       1/normal.z());
-       const unsigned  signs[]={       direction.x()<0,
-                                                               direction.y()<0,
-                                                               direction.z()<0};
-       btAlignedObjectArray<const btDbvtNode*> stack;
-       stack.reserve(SIMPLE_STACKSIZE);
-       stack.push_back(root);
-       do      {
-               const btDbvtNode*       node=stack[stack.size()-1];
-               stack.pop_back();
-               if(Intersect(node->volume,origin,invdir,signs))
-                       {
-                       if(node->isinternal())
-                               {
-                               stack.push_back(node->childs[0]);
-                               stack.push_back(node->childs[1]);
-                               }
-                               else
+       DBVT_CHECKTYPE
+               if(root)
+               {
+                       btVector3 rayDir = (rayTo-rayFrom);
+                       rayDir.normalize ();
+
+                       ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+                       btVector3 rayDirectionInverse;
+                       rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+                       rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+                       rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+                       unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+
+                       btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
+
+                       btVector3 resultNormal;
+
+                       btAlignedObjectArray<const btDbvtNode*> stack;
+
+                       int                                                             depth=1;
+                       int                                                             treshold=DOUBLE_STACKSIZE-2;
+
+                       stack.resize(DOUBLE_STACKSIZE);
+                       stack[0]=root;
+                       btVector3 bounds[2];
+                       do      {
+                               const btDbvtNode*       node=stack[--depth];
+
+                               bounds[0] = node->volume.Mins();
+                               bounds[1] = node->volume.Maxs();
+                               
+                               btScalar tmin=1.f,lambda_min=0.f;
+                               unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+
+#ifdef COMPARE_BTRAY_AABB2
+                               btScalar param=1.f;
+                               bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
+                               btAssert(result1 == result2);
+#endif //TEST_BTRAY_AABB2
+
+                               if(result1)
                                {
-                               policy.Process(node);
+                                       if(node->isinternal())
+                                       {
+                                               if(depth>treshold)
+                                               {
+                                                       stack.resize(stack.size()*2);
+                                                       treshold=stack.size()-2;
+                                               }
+                                               stack[depth++]=node->childs[0];
+                                               stack[depth++]=node->childs[1];
+                                       }
+                                       else
+                                       {
+                                               policy.Process(node);
+                                       }
                                }
-                       }
-               } while(stack.size());
-       }
+                       } while(depth);
+
+               }
 }
 
 //
@@ -921,174 +1064,174 @@ inline void            btDbvt::collideKDOP(const btDbvtNode* root,
                                                                        int count,
                                                                        DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root)
-       {
-       const int                                               inside=(1<<count)-1;
-       btAlignedObjectArray<sStkNP>    stack;
-       int                                                             signs[sizeof(unsigned)*8];
-       btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
-       for(int i=0;i<count;++i)
+       DBVT_CHECKTYPE
+               if(root)
                {
-               signs[i]=       ((normals[i].x()>=0)?1:0)+
+                       const int                                               inside=(1<<count)-1;
+                       btAlignedObjectArray<sStkNP>    stack;
+                       int                                                             signs[sizeof(unsigned)*8];
+                       btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+                       for(int i=0;i<count;++i)
+                       {
+                               signs[i]=       ((normals[i].x()>=0)?1:0)+
                                        ((normals[i].y()>=0)?2:0)+
                                        ((normals[i].z()>=0)?4:0);
-               }
-       stack.reserve(SIMPLE_STACKSIZE);
-       stack.push_back(sStkNP(root,0));
-       do      {
-               sStkNP  se=stack[stack.size()-1];
-               bool    out=false;
-               stack.pop_back();
-               for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
-                       {
-                       if(0==(se.mask&j))
+                       }
+                       stack.reserve(SIMPLE_STACKSIZE);
+                       stack.push_back(sStkNP(root,0));
+                       do      {
+                               sStkNP  se=stack[stack.size()-1];
+                               bool    out=false;
+                               stack.pop_back();
+                               for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
                                {
-                               const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
-                               switch(side)
+                                       if(0==(se.mask&j))
                                        {
-                                       case    -1:     out=true;break;
-                                       case    +1:     se.mask|=j;break;
+                                               const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+                                               switch(side)
+                                               {
+                                               case    -1:     out=true;break;
+                                               case    +1:     se.mask|=j;break;
+                                               }
                                        }
                                }
-                       }
-               if(!out)
-                       {
-                       if((se.mask!=inside)&&(se.node->isinternal()))
-                               {
-                               stack.push_back(sStkNP(se.node->childs[0],se.mask));
-                               stack.push_back(sStkNP(se.node->childs[1],se.mask));
-                               }
-                               else
+                               if(!out)
                                {
-                               if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+                                       if((se.mask!=inside)&&(se.node->isinternal()))
+                                       {
+                                               stack.push_back(sStkNP(se.node->childs[0],se.mask));
+                                               stack.push_back(sStkNP(se.node->childs[1],se.mask));
+                                       }
+                                       else
+                                       {
+                                               if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+                                       }
                                }
-                       }
-               } while(stack.size());
-       }
+                       } while(stack.size());
+               }
 }
 
 //
 DBVT_PREFIX
 inline void            btDbvt::collideOCL(     const btDbvtNode* root,
-                                                                       const btVector3* normals,
-                                                                       const btScalar* offsets,
-                                                                       const btVector3& sortaxis,
-                                                                       int count,
-                                                                       DBVT_IPOLICY,
-                                                                       bool fsort)
+                                                                  const btVector3* normals,
+                                                                  const btScalar* offsets,
+                                                                  const btVector3& sortaxis,
+                                                                  int count,
+                                                                  DBVT_IPOLICY,
+                                                                  bool fsort)
 {
-DBVT_CHECKTYPE
-if(root)
-       {
-       const unsigned                                  srtsgns=(sortaxis[0]>=0?1:0)+
-                                                                                       (sortaxis[1]>=0?2:0)+
-                                                                                       (sortaxis[2]>=0?4:0);
-       const int                                               inside=(1<<count)-1;
-       btAlignedObjectArray<sStkNPS>   stock;
-       btAlignedObjectArray<int>               ifree;
-       btAlignedObjectArray<int>               stack;
-       int                                                             signs[sizeof(unsigned)*8];
-       btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
-       for(int i=0;i<count;++i)
+       DBVT_CHECKTYPE
+               if(root)
                {
-               signs[i]=       ((normals[i].x()>=0)?1:0)+
+                       const unsigned                                  srtsgns=(sortaxis[0]>=0?1:0)+
+                               (sortaxis[1]>=0?2:0)+
+                               (sortaxis[2]>=0?4:0);
+                       const int                                               inside=(1<<count)-1;
+                       btAlignedObjectArray<sStkNPS>   stock;
+                       btAlignedObjectArray<int>               ifree;
+                       btAlignedObjectArray<int>               stack;
+                       int                                                             signs[sizeof(unsigned)*8];
+                       btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+                       for(int i=0;i<count;++i)
+                       {
+                               signs[i]=       ((normals[i].x()>=0)?1:0)+
                                        ((normals[i].y()>=0)?2:0)+
                                        ((normals[i].z()>=0)?4:0);
-               }
-       stock.reserve(SIMPLE_STACKSIZE);
-       stack.reserve(SIMPLE_STACKSIZE);
-       ifree.reserve(SIMPLE_STACKSIZE);
-       stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
-       do      {
-               const int       id=stack[stack.size()-1];
-               sStkNPS         se=stock[id];
-               stack.pop_back();ifree.push_back(id);
-               if(se.mask!=inside)
-                       {
-                       bool    out=false;
-                       for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+                       }
+                       stock.reserve(SIMPLE_STACKSIZE);
+                       stack.reserve(SIMPLE_STACKSIZE);
+                       ifree.reserve(SIMPLE_STACKSIZE);
+                       stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
+                       do      {
+                               const int       id=stack[stack.size()-1];
+                               sStkNPS         se=stock[id];
+                               stack.pop_back();ifree.push_back(id);
+                               if(se.mask!=inside)
                                {
-                               if(0==(se.mask&j))
+                                       bool    out=false;
+                                       for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
                                        {
-                                       const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
-                                       switch(side)
+                                               if(0==(se.mask&j))
                                                {
-                                               case    -1:     out=true;break;
-                                               case    +1:     se.mask|=j;break;
+                                                       const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+                                                       switch(side)
+                                                       {
+                                                       case    -1:     out=true;break;
+                                                       case    +1:     se.mask|=j;break;
+                                                       }
                                                }
                                        }
+                                       if(out) continue;
                                }
-                       if(out) continue;
-                       }
-               if(policy.Descent(se.node))
-                       {
-                       if(se.node->isinternal())
+                               if(policy.Descent(se.node))
                                {
-                               const btDbvtNode* pns[]={       se.node->childs[0],se.node->childs[1]};
-                               sStkNPS         nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
-                                                                       sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
-                               const int       q=nes[0].value<nes[1].value?1:0;                                
-                               int                     j=stack.size();
-                               if(fsort&&(j>0))
+                                       if(se.node->isinternal())
                                        {
-                                       /* Insert 0     */ 
-                                       j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
-                                       stack.push_back(0);
-                                       #if DBVT_USE_MEMMOVE
-                                       memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
-                                       #else
-                                       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));
-                                       #else
-                                       for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
-                                       #endif
-                                       stack[j]=allocate(ifree,stock,nes[1-q]);
+                                               const btDbvtNode* pns[]={       se.node->childs[0],se.node->childs[1]};
+                                               sStkNPS         nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
+                                                       sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
+                                               const int       q=nes[0].value<nes[1].value?1:0;                                
+                                               int                     j=stack.size();
+                                               if(fsort&&(j>0))
+                                               {
+                                                       /* Insert 0     */ 
+                                                       j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
+                                                       stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+                                                       memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+                                                       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));
+#else
+                                                       for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+                                                       stack[j]=allocate(ifree,stock,nes[1-q]);
+                                               }
+                                               else
+                                               {
+                                                       stack.push_back(allocate(ifree,stock,nes[q]));
+                                                       stack.push_back(allocate(ifree,stock,nes[1-q]));
+                                               }
                                        }
                                        else
                                        {
-                                       stack.push_back(allocate(ifree,stock,nes[q]));
-                                       stack.push_back(allocate(ifree,stock,nes[1-q]));
+                                               policy.Process(se.node,se.value);
                                        }
                                }
-                               else
-                               {
-                               policy.Process(se.node,se.value);
-                               }
-                       }
-               } while(stack.size());
-       }
+                       } while(stack.size());
+               }
 }
 
 //
 DBVT_PREFIX
 inline void            btDbvt::collideTU(      const btDbvtNode* root,
-                                                                       DBVT_IPOLICY)
+                                                                 DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root)
-       {
-       btAlignedObjectArray<const btDbvtNode*> stack;
-       stack.reserve(SIMPLE_STACKSIZE);
-       stack.push_back(root);
-       do      {
-               const btDbvtNode*       n=stack[stack.size()-1];
-               stack.pop_back();
-               if(policy.Descent(n))
-                       {
-                       if(n->isinternal())
-                               { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
-                               else
-                               { policy.Process(n); }
-                       }
-               } while(stack.size()>0);
-       }
+       DBVT_CHECKTYPE
+               if(root)
+               {
+                       btAlignedObjectArray<const btDbvtNode*> stack;
+                       stack.reserve(SIMPLE_STACKSIZE);
+                       stack.push_back(root);
+                       do      {
+                               const btDbvtNode*       n=stack[stack.size()-1];
+                               stack.pop_back();
+                               if(policy.Descent(n))
+                               {
+                                       if(n->isinternal())
+                                       { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
+                                       else
+                                       { policy.Process(n); }
+                               }
+                       } while(stack.size()>0);
+               }
 }
 
 //