mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:38:27 +02:00
fix sphere-cube collisions at edges (really)
This commit is contained in:
parent
1d64262067
commit
b097eed1aa
1 changed files with 20 additions and 26 deletions
|
@ -612,42 +612,36 @@ bool sphereAACube(const glm::vec3& sphereCenter, float sphereRadius, const glm::
|
||||||
if (maxBA > halfCubeSide) {
|
if (maxBA > halfCubeSide) {
|
||||||
// sphere hits cube but its center is outside cube
|
// sphere hits cube but its center is outside cube
|
||||||
|
|
||||||
// contactPoint is on surface of sphere
|
// compute contact anti-pole on cube (in cube frame)
|
||||||
glm::vec3 cubeContact = glm::abs(BA);
|
glm::vec3 cubeContact = glm::abs(BA);
|
||||||
glm::vec3 direction = cubeContact - glm::vec3(halfCubeSide);
|
|
||||||
|
|
||||||
if (direction.x < 0.0f) {
|
|
||||||
direction.x = 0.0f;
|
|
||||||
}
|
|
||||||
if (direction.y < 0.0f) {
|
|
||||||
direction.y = 0.0f;
|
|
||||||
}
|
|
||||||
if (direction.z < 0.0f) {
|
|
||||||
direction.z = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 signs = glm::sign(BA);
|
|
||||||
direction.x *= signs.x;
|
|
||||||
direction.y *= signs.y;
|
|
||||||
direction.z *= signs.z;
|
|
||||||
direction = glm::normalize(direction);
|
|
||||||
collision->_contactPoint = sphereCenter + sphereRadius * direction;
|
|
||||||
|
|
||||||
// penetration points from contact point on cube to that on sphere
|
|
||||||
if (cubeContact.x > halfCubeSide) {
|
if (cubeContact.x > halfCubeSide) {
|
||||||
cubeContact.x = halfCubeSide;
|
cubeContact.x = halfCubeSide;
|
||||||
}
|
}
|
||||||
cubeContact.x *= -signs.x;
|
|
||||||
if (cubeContact.y > halfCubeSide) {
|
if (cubeContact.y > halfCubeSide) {
|
||||||
cubeContact.y = halfCubeSide;
|
cubeContact.y = halfCubeSide;
|
||||||
}
|
}
|
||||||
cubeContact.y *= -signs.y;
|
|
||||||
if (cubeContact.z > halfCubeSide) {
|
if (cubeContact.z > halfCubeSide) {
|
||||||
cubeContact.z = halfCubeSide;
|
cubeContact.z = halfCubeSide;
|
||||||
}
|
}
|
||||||
cubeContact.z *= -signs.z;
|
glm::vec3 signs = glm::sign(BA);
|
||||||
//collision->_penetration = collision->_contactPoint - cubeCenter + cubeContact;
|
cubeContact.x *= signs.x;
|
||||||
collision->_penetration = collision->_contactPoint - (cubeCenter + cubeContact);
|
cubeContact.y *= signs.y;
|
||||||
|
cubeContact.z *= signs.z;
|
||||||
|
|
||||||
|
// compute collision details
|
||||||
|
glm::vec3 direction = BA - cubeContact;
|
||||||
|
float lengthDirection = glm::length(direction);
|
||||||
|
if (lengthDirection < EPSILON) {
|
||||||
|
// sphereCenter is touching cube surface, so we can't use the difference between those two
|
||||||
|
// points to compute the penetration direction. Instead we use the unitary components of
|
||||||
|
// cubeContact.
|
||||||
|
direction = cubeContact / halfCubeSide;
|
||||||
|
glm::modf(BA, direction);
|
||||||
|
lengthDirection = glm::length(direction);
|
||||||
|
}
|
||||||
|
direction /= lengthDirection;
|
||||||
|
collision->_contactPoint = sphereCenter + sphereRadius * direction;
|
||||||
|
collision->_penetration = sphereRadius * direction - (BA - cubeContact);
|
||||||
} else {
|
} else {
|
||||||
// sphere center is inside cube
|
// sphere center is inside cube
|
||||||
// --> push out nearest face
|
// --> push out nearest face
|
||||||
|
|
Loading…
Reference in a new issue