// Given point p, return point q on (or in) OBB b, closest to p Vector2 ClosestPtPointOBB(Vector2 point, SimpleActor.OBB box) { Vector2 d = point - box._center; // Start result at center of box; make steps from there Vector2 closestOnBox = box._center; // For each OBB axis... for (int i = 0; i < 2; i++) { // ...project d onto that axis to get the distance // along the axis of d from the box center float dist = (Vector3.Project(d, box._local_axes[i])).magnitude; // If distance farther than the box extents, clamp to the box if (dist > box._extents[i]) { dist = box._extents[i]; } if (dist < -box._extents[i]) { dist = -box._extents[i]; } // Step that distance along the axis to get world coordinate closestOnBox += dist * box._local_axes[i]; } return(closestOnBox); }
//Returns true if sphere s intersects OBB b, false otherwise. //The point p on the OBB closest to the sphere center is also returned bool TestCircleOBB(CircleObstacle obstacle, SimpleActor.OBB box, out Vector2 closestPoint) { // Find point p on OBB closest to sphere center closestPoint = ClosestPtPointOBB(obstacle.Center, box); // Sphere and OBB intersect if the (squared) distance from sphere // center to point p is less than the (squared) sphere radius Vector2 v = closestPoint - obstacle.Center; return(v.sqrMagnitude <= obstacle.Radius * obstacle.Radius); }