From 7195b54d137ba8e125f0f7a962597c3a1aef4db3 Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Tue, 10 Sep 2013 23:09:24 +0000 Subject: [PATCH] Fix Issue 712, related to NVIDIA CUDA check in CMakeLists.txt Enable btGImpact raycast optimization, thanks to C0DEFACE, see Issue 664 Cull triangle/AABB for concave/heightfield shapes, thanks to Danny Chapman fix btGetCpuCapabilities, thanks to Ian Ollman! See https://code.google.com/p/bullet/issues/detail?id=738 --- CMakeLists.txt | 2 +- Demos/RaytestDemo/RaytestDemo.cpp | 6 ++- .../CollisionDispatch/btCollisionWorld.cpp | 52 +++++++++++-------- .../btConvexConcaveCollisionAlgorithm.cpp | 7 +++ src/LinearMath/btVector3.cpp | 43 +++++++++------ 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 008c492b9..3d5f8dada 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ IF (BUILD_MULTITHREADING) ELSE(CMAKE_CL_64) SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/lib/Win32 ) ENDIF(CMAKE_CL_64) - SET(NVIDIA_OPENCL_LIBRARIES ${CMAKE_NVSDKCOMPUTE_LIBPATH}/OpenCL.lib) + SET(NVIDIA_OPENCL_LIBRARIES ${CMAKE_NVSDKCOMPUTE_LIBPATH}/OpenCL.lib) OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON) ELSE() diff --git a/Demos/RaytestDemo/RaytestDemo.cpp b/Demos/RaytestDemo/RaytestDemo.cpp index b32a1e3eb..9fc494f7a 100644 --- a/Demos/RaytestDemo/RaytestDemo.cpp +++ b/Demos/RaytestDemo/RaytestDemo.cpp @@ -20,6 +20,7 @@ subject to the following restrictions: ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/Gimpact/btGImpactShape.h" #include //printf debugging #include "GLDebugDrawer.h" @@ -220,7 +221,10 @@ void RaytestDemo::initPhysics() mesh->addTriangle(quad[0],quad[1],quad[2],true); mesh->addTriangle(quad[0],quad[2],quad[3],true); - btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true); + //btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true); + btGImpactMeshShape * trimesh = new btGImpactMeshShape(mesh); + trimesh->updateBound(); + #define NUM_SHAPES 6 btCollisionShape* colShapes[NUM_SHAPES] = { diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index cd80def10..783aa41c3 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -34,7 +34,7 @@ subject to the following restrictions: #include "LinearMath/btSerializer.h" #include "BulletCollision/CollisionShapes/btConvexPolyhedron.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" - +#include "BulletCollision/Gimpact/btGImpactShape.h" //#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION @@ -325,34 +325,26 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con } else { if (collisionShape->isConcave()) { - // BT_PROFILE("rayTestConcave"); - if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) - { - ///optimized version for btBvhTriangleMeshShape - btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; - btTransform worldTocollisionObject = colObjWorldTransform.inverse(); - btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); - btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); - //ConvexCast::CastResult + //ConvexCast::CastResult struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback { btCollisionWorld::RayResultCallback* m_resultCallback; const btCollisionObject* m_collisionObject; - btTriangleMeshShape* m_triangleMesh; + const btConcaveShape* m_triangleMesh; btTransform m_colObjWorldTransform; BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, - btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform): - //@BP Mod - btTriangleRaycastCallback(from,to, resultCallback->m_flags), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh), - m_colObjWorldTransform(colObjWorldTransform) - { - } + btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform): + //@BP Mod + btTriangleRaycastCallback(from,to, resultCallback->m_flags), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh), + m_colObjWorldTransform(colObjWorldTransform) + { + } virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) @@ -375,10 +367,28 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con }; + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); + btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); + + // BT_PROFILE("rayTestConcave"); + if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + ///optimized version for btBvhTriangleMeshShape + btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; + BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal); - } else + } + else if(collisionShape->getShapeType()==GIMPACT_SHAPE_PROXYTYPE) + { + btGImpactMeshShape* concaveShape = (btGImpactMeshShape*)collisionShape; + + BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform); + rcb.m_hitFraction = resultCallback.m_closestHitFraction; + concaveShape->processAllTrianglesRay(&rcb,rayFromLocal,rayToLocal); + }else { //generic (slower) case btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp index 920a08eff..e23f5f7a8 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -80,6 +80,11 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) { + if (!TestTriangleAgainstAabb2(triangle, m_aabbMin, m_aabbMax)) + { + return; + } + //just for debugging purposes //printf("triangle %d",m_triangleCount++); @@ -90,6 +95,8 @@ partId, int triangleIndex) //const btCollisionObject* ob = static_cast(m_triBodyWrap->getCollisionObject()); + + #if 0 ///debug drawing of the overlapping triangles diff --git a/src/LinearMath/btVector3.cpp b/src/LinearMath/btVector3.cpp index 97e90f105..0af112c75 100644 --- a/src/LinearMath/btVector3.cpp +++ b/src/LinearMath/btVector3.cpp @@ -835,39 +835,48 @@ static long _mindot_large_sel( const float *vv, const float *vec, unsigned long long (*_maxdot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _maxdot_large_sel; long (*_mindot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _mindot_large_sel; -//Apple doesn't allow to use this internal API and rejects Apps. -//thanks Apple for rejecting your own contribution :-) -//Let's always use version 'v1' -//See https://code.google.com/p/bullet/issues/detail?id=738 -#ifdef USE_DEVICE_CAPABILITIES -extern "C" {int _get_cpu_capabilities( void );} -#endif //USE_DEVICE_CAPABILITIES + +static inline uint32_t btGetCpuCapabilities( void ) +{ + static uint32_t capabilities = 0; + static bool testedCapabilities = false; + + if( 0 == testedCapabilities) + { + uint32_t hasFeature = 0; + size_t featureSize = sizeof( hasFeature ); + int err = sysctlbyname( "hw.optional.neon_hpfp", &hasFeature, &featureSize, NULL, 0 ); + + if( 0 == err && hasFeature) + capabilities |= 0x2000; + + testedCapabilities = true; + } + + return capabilities; +} + + static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) { -#ifdef USE_DEVICE_CAPABILITIES - if( _get_cpu_capabilities() & 0x2000 ) + + if( btGetCpuCapabilities() & 0x2000 ) _maxdot_large = _maxdot_large_v1; else _maxdot_large = _maxdot_large_v0; -#else - _maxdot_large = _maxdot_large_v1; -#endif return _maxdot_large(vv, vec, count, dotResult); } static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) { -#ifdef USE_DEVICE_CAPABILITIES - if( _get_cpu_capabilities() & 0x2000 ) + + if( btGetCpuCapabilities() & 0x2000 ) _mindot_large = _mindot_large_v1; else _mindot_large = _mindot_large_v0; -#else - _mindot_large = _mindot_large_v1; -#endif return _mindot_large(vv, vec, count, dotResult); }