Example #1
0
        public static AABB CreateCapsuleAABB(Vector3 segment0, Vector3 segment1, float radius)
        {
            for (int i = 0; i < 3; i++)
            {
                if (segment0[i] < segment1[i])
                {
                    segment0[i] -= radius;
                    segment1[i] += radius;
                }
                else
                {
                    segment0[i] += radius;
                    segment1[i] -= radius;
                }
            }

            return(new AABB((segment0 + segment1) * .5f, ExtVector3.Abs(segment1 - segment0) * .5f));            //It seems the extents must be positives for our overlap tests to work...
        }
        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));
            }
        }
 public Vector3 HalfExtent()
 {
     return(ExtVector3.Abs((maxExtent - minExtent) * .5f));
 }