aboutsummaryrefslogtreecommitdiff
path: root/JamHelper/Assets/JamUtils/Scripts/Utils/ColliderUtility.cs
blob: 8c8225c9dca3ea72d8a9541a2d9f3a7338dc9e30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using UnityEngine;

namespace JamUtils
{

    public static class ColliderUtility
    {
        private static readonly List<Vector3> s_Vertices = new List<Vector3>();

        private static readonly List<int> s_Triangles = new List<int>();

        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);
        }
    }

}