using System; using System.Collections.Generic; using UnityEngine; namespace JamTools { public static class ColliderUtility { private static readonly List s_Vertices = new List(); private static readonly List s_Triangles = new List(); private static Plane GetWorldTriangle(Transform collider, int index) { Vector3 position = ColliderUtility.s_Vertices[ColliderUtility.s_Triangles[3 * index]]; Vector3 position2 = ColliderUtility.s_Vertices[ColliderUtility.s_Triangles[3 * index + 1]]; Vector3 position3 = ColliderUtility.s_Vertices[ColliderUtility.s_Triangles[3 * index + 2]]; return new Plane(collider.TransformPoint(position), collider.TransformPoint(position2), collider.TransformPoint(position3)); } public static Vector3 FindClosestPoint(Collider collider, Vector3 position) { return ColliderUtility.FindClosestPoint(collider, position, false); } public static Vector3 FindClosestPoint(Collider collider, Vector3 position, bool ignoreVerticalTriangles) { MeshCollider meshCollider; if ((meshCollider = (collider as MeshCollider)) != null && !meshCollider.convex) { Mesh sharedMesh = meshCollider.sharedMesh; sharedMesh.GetVertices(ColliderUtility.s_Vertices); Plane plane = default(Plane); float num = float.PositiveInfinity; for (int i = 0; i < sharedMesh.subMeshCount; i++) { sharedMesh.GetTriangles(ColliderUtility.s_Triangles, i); int j = 0; int num2 = ColliderUtility.s_Triangles.Count / 3; while (j < num2) { Plane worldTriangle = ColliderUtility.GetWorldTriangle(meshCollider.transform, j); float num3 = Mathf.Abs(worldTriangle.GetDistanceToPoint(position)); if ((!ignoreVerticalTriangles || (!(worldTriangle.normal == Vector3.up) && !(worldTriangle.normal == Vector3.down))) && ((i == 0 && j == 0) || num3 < num)) { plane = worldTriangle; num = num3; } j++; } } return plane.ClosestPointOnPlane(position); } return collider.ClosestPoint(position); } } }