diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 7ffe4edfde..5a756b8e71 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -116,6 +116,25 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu return false; } +bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + glm::vec3& penetration) { + glm::vec3 localCenter = sphereCenter - diskCenter; + float verticalDistance = glm::dot(localCenter, diskNormal); + if (abs(verticalDistance) < sphereRadius) { + // sphere hits the plane, but does it hit the disk? + // Note: this algorithm ignores edge hits. + glm::vec3 verticalOffset = verticalDistance * diskNormal; + if (glm::length(localCenter - verticalOffset) < diskRadius) { + penetration = (sphereRadius - abs(verticalDistance)) * diskNormal; + if (verticalDistance < 0.f) { + penetration *= -1.f; + } + } + } + return false; +} + bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration) { if (findSphereCapsulePenetration(sphereCenter, sphereRadius, diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 2b782b43ae..59ad055445 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -47,6 +47,17 @@ bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, float spher bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec4& plane, glm::vec3& penetration); +/// Computes the penetration between a sphere and a disk. +/// \param sphereCenter center of sphere +/// \param sphereRadius radius of sphere +/// \param diskCenter center of disk +/// \param diskRadius radius of disk +/// \param diskNormal normal of disk plan +/// \return true if sphere touches disk (does not handle collisions with disk edge) +bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + glm::vec3& penetration); + bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration);