diff --git a/cmake/externals/bullet/CMakeLists.txt b/cmake/externals/bullet/CMakeLists.txt index efe5b694fa..ff0eb22241 100644 --- a/cmake/externals/bullet/CMakeLists.txt +++ b/cmake/externals/bullet/CMakeLists.txt @@ -18,8 +18,8 @@ if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} # URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip - URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-r2704.zip - URL_MD5 f5e8914fc9064ad32e0d62d19d33d977 + URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-ccd-fix.zip + URL_MD5 d95b07eb120de7dd7786361c0b5a8d9f CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 -DUSE_DX11=0 LOG_DOWNLOAD 1 LOG_CONFIGURE 1 @@ -30,8 +30,8 @@ else () ExternalProject_Add( ${EXTERNAL_NAME} #URL http://bullet.googlecode.com/files/bullet-2.82-r2704.tgz - URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-r2704.tgz - URL_MD5 70b3c8d202dee91a0854b4cbc88173e8 + URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-ccd-fix.tgz + URL_MD5 fb140a4983b4109aa1c825a162aa8d64 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 LOG_DOWNLOAD 1 LOG_CONFIGURE 1 @@ -80,4 +80,4 @@ endif () if (DEFINED ${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_RELEASE) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include/bullet CACHE PATH "Path to bullet include directory") -endif () \ No newline at end of file +endif () diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index c39f47eaf8..aa9f7852c8 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -123,6 +123,31 @@ void ObjectMotionState::setMotionType(MotionType motionType) { _motionType = motionType; } +// Update the Continuous Collision Detection (CCD) configuration settings of our RigidBody so that +// CCD will be enabled automatically when its speed surpasses a certain threshold. +void ObjectMotionState::updateCCDConfiguration() { + if (_body) { + if (_shape) { + // If this object moves faster than its bounding radius * RADIUS_MOTION_THRESHOLD_MULTIPLIER, + // CCD will be enabled for this object. + const auto RADIUS_MOTION_THRESHOLD_MULTIPLIER = 0.5f; + + btVector3 center; + btScalar radius; + _shape->getBoundingSphere(center, radius); + _body->setCcdMotionThreshold(radius * RADIUS_MOTION_THRESHOLD_MULTIPLIER); + + // TODO: Ideally the swept sphere radius would be contained by the object. Using the bounding sphere + // radius works well for spherical objects, but may cause issues with other shapes. For arbitrary + // objects we may want to consider a different approach, such as grouping rigid bodies together. + _body->setCcdSweptSphereRadius(radius); + } else { + // Disable CCD + _body->setCcdMotionThreshold(0); + } + } +} + void ObjectMotionState::setRigidBody(btRigidBody* body) { // give the body a (void*) back-pointer to this ObjectMotionState if (_body != body) { @@ -133,6 +158,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) { if (_body) { _body->setUserPointer(this); } + updateCCDConfiguration(); } } @@ -232,6 +258,8 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* if (_shape != newShape) { _shape = newShape; _body->setCollisionShape(_shape); + + updateCCDConfiguration(); } else { // huh... the shape didn't actually change, so we clear the DIRTY_SHAPE flag flags &= ~Simulation::DIRTY_SHAPE; diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 7d5c727d6d..8f97b25dcc 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -151,6 +151,7 @@ protected: virtual bool isReadyToComputeShape() = 0; virtual btCollisionShape* computeNewShape() = 0; void setMotionType(MotionType motionType); + void updateCCDConfiguration(); // clearObjectBackPointer() overrrides should call the base method, then actually clear the object back pointer. virtual void clearObjectBackPointer() { _type = MOTIONSTATE_TYPE_INVALID; }