diff --git a/examples/CommonInterfaces/CommonDeformableBodyBase.h b/examples/CommonInterfaces/CommonDeformableBodyBase.h index 456c25bfe..4bfc379d9 100644 --- a/examples/CommonInterfaces/CommonDeformableBodyBase.h +++ b/examples/CommonInterfaces/CommonDeformableBodyBase.h @@ -14,6 +14,7 @@ #include "CommonWindowInterface.h" #include "CommonCameraInterface.h" #include "CommonMultiBodyBase.h" +#include "BulletSoftBody/btSoftBody.h" struct CommonDeformableBodyBase : public CommonMultiBodyBase { @@ -38,12 +39,49 @@ struct CommonDeformableBodyBase : public CommonMultiBodyBase { return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld; } - + + struct ClosestRayResultCallbackWithInfo : public btCollisionWorld::ClosestRayResultCallback + { + ClosestRayResultCallbackWithInfo(const btVector3& rayFromWorld, const btVector3& rayToWorld) + : ClosestRayResultCallback(rayFromWorld, rayToWorld) + { + } + int m_faceId; + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + { + //caller already does the filter on the m_closestHitFraction + btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + m_collisionObject = rayResult.m_collisionObject; + if (rayResult.m_localShapeInfo) + { + m_faceId = rayResult.m_localShapeInfo->m_triangleIndex; + } + else + { + m_faceId = -1; + } + if (normalInWorldSpace) + { + m_hitNormalWorld = rayResult.m_hitNormalLocal; + } + else + { + ///need to transform normal into worldspace + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; + } + m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); + return rayResult.m_hitFraction; + } + }; + virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { if (getDeformableDynamicsWorld() == 0) return false; - btCollisionWorld::ClosestRayResultCallbackWithInfo rayCallback(rayFromWorld, rayToWorld); + ClosestRayResultCallbackWithInfo rayCallback(rayFromWorld, rayToWorld); getDeformableDynamicsWorld()->rayTest(rayFromWorld, rayToWorld, rayCallback); if (rayCallback.hasHit()) { @@ -68,13 +106,16 @@ struct CommonDeformableBodyBase : public CommonMultiBodyBase } else if (psb) { - int face_id = rayCallback.m_localShapeInfo->m_triangleIndex; - m_pickedSoftBody = psb; - psb->setActivationState(DISABLE_DEACTIVATION); - const btSoftBody::Face& f = psb->m_faces[face_id]; - btDeformableMousePickingForce* mouse_force = new btDeformableMousePickingForce(100, 0.2, f, m_hitPos, m_maxPickingForce); - m_mouseForce = mouse_force; - getDeformableDynamicsWorld()->addForce(psb, mouse_force); + int face_id = rayCallback.m_faceId; + if (face_id >= 0 && face_id < psb->m_faces.size()) + { + m_pickedSoftBody = psb; + psb->setActivationState(DISABLE_DEACTIVATION); + const btSoftBody::Face& f = psb->m_faces[face_id]; + btDeformableMousePickingForce* mouse_force = new btDeformableMousePickingForce(100, 0.2, f, m_hitPos, m_maxPickingForce); + m_mouseForce = mouse_force; + getDeformableDynamicsWorld()->addForce(psb, mouse_force); + } } else { diff --git a/examples/CommonInterfaces/CommonRigidBodyBase.h b/examples/CommonInterfaces/CommonRigidBodyBase.h index daaae2ba4..98352bcd3 100644 --- a/examples/CommonInterfaces/CommonRigidBodyBase.h +++ b/examples/CommonInterfaces/CommonRigidBodyBase.h @@ -7,7 +7,6 @@ #include "CommonGUIHelperInterface.h" #include "CommonRenderInterface.h" #include "CommonCameraInterface.h" -#include "BulletSoftBody/btSoftBody.h" #include "CommonGraphicsAppInterface.h" #include "CommonWindowInterface.h" #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" @@ -343,21 +342,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface p2p->m_setting.m_tau = 0.001f; } } - btSoftBody* psb = (btSoftBody*)btSoftBody::upcast(rayCallback.m_collisionObject); - if (psb) - { - m_savedState = psb->getActivationState(); - m_pickedBody->setActivationState(DISABLE_DEACTIVATION); - //printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ()); - btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, localPivot); - m_dynamicsWorld->addConstraint(p2p, true); - m_pickedConstraint = p2p; - btScalar mousePickClamping = 30.f; - p2p->m_setting.m_impulseClamp = mousePickClamping; - //very weak constraint for picking - p2p->m_setting.m_tau = 0.001f; - } // pickObject(pickPos, rayCallback.m_collisionObject); m_oldPickingPos = rayToWorld; diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h index 5f3e8c70a..fd0e5b9bb 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -263,36 +263,6 @@ public: return rayResult.m_hitFraction; } }; - - struct ClosestRayResultCallbackWithInfo : public ClosestRayResultCallback - { - ClosestRayResultCallbackWithInfo(const btVector3& rayFromWorld, const btVector3& rayToWorld) - : ClosestRayResultCallback(rayFromWorld, rayToWorld) - { - } - LocalShapeInfo* m_localShapeInfo; - - virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) - { - //caller already does the filter on the m_closestHitFraction - btAssert(rayResult.m_hitFraction <= m_closestHitFraction); - - m_closestHitFraction = rayResult.m_hitFraction; - m_collisionObject = rayResult.m_collisionObject; - m_localShapeInfo = rayResult.m_localShapeInfo; - if (normalInWorldSpace) - { - m_hitNormalWorld = rayResult.m_hitNormalLocal; - } - else - { - ///need to transform normal into worldspace - m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; - } - m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); - return rayResult.m_hitFraction; - } - }; struct AllHitsRayResultCallback : public RayResultCallback {