mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 22:22:54 +02:00
Merge pull request #13707 from AndrewMeadows/fix-ccd
more correct continuous collision detection for thin objects
This commit is contained in:
commit
df917688b6
1 changed files with 21 additions and 20 deletions
|
@ -155,26 +155,25 @@ void ObjectMotionState::setMotionType(PhysicsMotionType motionType) {
|
||||||
// Update the Continuous Collision Detection (CCD) configuration settings of our RigidBody so that
|
// 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.
|
// CCD will be enabled automatically when its speed surpasses a certain threshold.
|
||||||
void ObjectMotionState::updateCCDConfiguration() {
|
void ObjectMotionState::updateCCDConfiguration() {
|
||||||
if (_body) {
|
assert(_body);
|
||||||
if (_shape) {
|
if (_shape && _shape->getShapeType() != TRIANGLE_MESH_SHAPE_PROXYTYPE) {
|
||||||
// If this object moves faster than its bounding radius * RADIUS_MOTION_THRESHOLD_MULTIPLIER,
|
// find minumum dimension of shape
|
||||||
// CCD will be enabled for this object.
|
btVector3 aabbMin, aabbMax;
|
||||||
const auto RADIUS_MOTION_THRESHOLD_MULTIPLIER = 0.5f;
|
btTransform transform;
|
||||||
|
transform.setIdentity();
|
||||||
btVector3 center;
|
_shape->getAabb(transform, aabbMin, aabbMax);
|
||||||
btScalar radius;
|
aabbMin = aabbMax - aabbMin;
|
||||||
_shape->getBoundingSphere(center, radius);
|
btScalar radius = *((btScalar*)(aabbMin) + aabbMin.minAxis());
|
||||||
_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.
|
|
||||||
|
|
||||||
|
// use the minimum dimension as the radius of the CCD proxy sphere
|
||||||
_body->setCcdSweptSphereRadius(radius);
|
_body->setCcdSweptSphereRadius(radius);
|
||||||
|
|
||||||
|
// also use the radius as the motion threshold for enabling CCD
|
||||||
|
_body->setCcdMotionThreshold(radius);
|
||||||
} else {
|
} else {
|
||||||
// Disable CCD
|
// disable CCD
|
||||||
_body->setCcdMotionThreshold(0);
|
_body->setCcdSweptSphereRadius(0.0f);
|
||||||
}
|
_body->setCcdMotionThreshold(0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +187,9 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
|
||||||
if (_body) {
|
if (_body) {
|
||||||
_body->setUserPointer(this);
|
_body->setUserPointer(this);
|
||||||
assert(_body->getCollisionShape() == _shape);
|
assert(_body->getCollisionShape() == _shape);
|
||||||
}
|
|
||||||
updateCCDConfiguration();
|
updateCCDConfiguration();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMotionState::setShape(const btCollisionShape* shape) {
|
void ObjectMotionState::setShape(const btCollisionShape* shape) {
|
||||||
|
@ -199,6 +198,9 @@ void ObjectMotionState::setShape(const btCollisionShape* shape) {
|
||||||
getShapeManager()->releaseShape(_shape);
|
getShapeManager()->releaseShape(_shape);
|
||||||
}
|
}
|
||||||
_shape = shape;
|
_shape = shape;
|
||||||
|
if (_body) {
|
||||||
|
updateCCDConfiguration();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +314,6 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine*
|
||||||
} else {
|
} else {
|
||||||
_body->setCollisionShape(const_cast<btCollisionShape*>(newShape));
|
_body->setCollisionShape(const_cast<btCollisionShape*>(newShape));
|
||||||
setShape(newShape);
|
setShape(newShape);
|
||||||
updateCCDConfiguration();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
|
|
Loading…
Reference in a new issue