public ContactInfo ClosestPointOnSurface(Vector3 point, float radius) { trianglesBufferSingleSphere.Clear(); Vector3 localPoint = transform.InverseTransformPoint(point); radius /= ExtVector3.Minimum(ExtVector3.Abs(transform.lossyScale)); AABB aabb = AABB.CreateSphereAABB(localPoint, radius + .001f); tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferSingleSphere, infoDebug); Vector3 shortestPoint = Vector3.zero; Vector3 p1, p2, p3, nearest; float radiusSqrd = radius * radius; float shortestDistance = float.MaxValue; int shortestTriangleIndex = -1; HashSet <int> .Enumerator enumerator = trianglesBufferSingleSphere.GetEnumerator(); while (enumerator.MoveNext()) { tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3); nearest = Geometry.ClosestPointOnTriangleToPoint(p1, p2, p3, localPoint); float distance = (localPoint - nearest).sqrMagnitude; if (PointIsBetter(distance, shortestDistance, localPoint, shortestPoint, localPoint, nearest, shortestTriangleIndex, enumerator.Current, radiusSqrd)) { shortestDistance = distance; shortestPoint = nearest; shortestTriangleIndex = enumerator.Current; } } if (shortestPoint == Vector3.zero) { return(new ContactInfo()); } return(new ContactInfo(transform.TransformPoint(shortestPoint), transform.TransformDirection(tree.GetTriangleNormal(shortestTriangleIndex)))); }
public List <ContactInfo> ClosestPointsOnSurface(Vector3 point, float radius, List <ContactInfo> resultsBuffer) { resultsBuffer.Clear(); trianglesBufferMultiSphere.Clear(); closestPointsBufferMultiSphere.Clear(); Vector3 localPoint = transform.InverseTransformPoint(point); radius /= ExtVector3.Minimum(ExtVector3.Abs(transform.lossyScale)); AABB aabb = AABB.CreateSphereAABB(localPoint, radius + .001f); tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferMultiSphere, infoDebug); Vector3 p1, p2, p3, nearest; float radiusSqrd = radius * radius; float distance = 0; HashSet <int> .Enumerator enumerator = trianglesBufferMultiSphere.GetEnumerator(); while (enumerator.MoveNext()) { tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3); nearest = Geometry.ClosestPointOnTriangleToPoint(p1, p2, p3, localPoint); distance = (nearest - localPoint).sqrMagnitude; if (distance <= radiusSqrd) { closestPointsBufferMultiSphere.Add(new ClosestTrianglePoint(nearest, distance, enumerator.Current, localPoint, this)); } } CleanUp(closestPointsBufferMultiSphere, resultsBuffer); return(resultsBuffer); }
public static CapsuleShape ToLocalOfUniformScale(CapsuleShape capsuleShape, Transform transform) { Vector3 localSegment0 = transform.InverseTransformPoint(capsuleShape.top); Vector3 localSegment1 = transform.InverseTransformPoint(capsuleShape.bottom); float distance = Vector3.Distance(localSegment0, localSegment1); float difference = capsuleShape.pointsDistance / distance; //If distance is zero, then the capsule is probably like a sphere. //Not sure if we should just always do it the way that can handle zero. if (Mathf.Approximately(distance, 0f) || Mathf.Approximately(difference, 0f)) { float minimumScale = ExtVector3.Minimum(ExtVector3.Abs(transform.lossyScale)); float height = capsuleShape.height / minimumScale; float radius = capsuleShape.radius / minimumScale; return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, height, radius)); } else { return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, capsuleShape.height / difference, capsuleShape.radius / difference)); } }