public static CapsuleShape ToLocalOfUniformScale(CapsuleShape capsuleShape, Transform transform)
        {
            Vector3 localSegment0 = transform.InverseTransformPoint(capsuleShape.top);
            Vector3 localSegment1 = transform.InverseTransformPoint(capsuleShape.bottom);

            float difference = capsuleShape.pointsDistance / Vector3.Distance(localSegment0, localSegment1);

            return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, capsuleShape.height / difference, capsuleShape.radius / difference));
        }
Exemplo n.º 2
0
        public static AABB CreateCapsuleAABB(Vector3 origin, Vector3 direction, float height, float radius, bool normalizeParameter = true)
        {
            if (normalizeParameter)
            {
                direction.Normalize();
            }

            CapsuleShape capsulePoints = new CapsuleShape(origin, direction, height, radius);

            return(CreateCapsuleAABB(capsulePoints.top, capsulePoints.bottom, radius));
        }
        public ContactInfo ClosestPointOnSurface(Vector3 segment0, Vector3 segment1, float radius)
        {
            trianglesBufferSingleCaps.Clear();

            CapsuleShape capsule       = CapsuleShape.ToLocalOfUniformScale(new CapsuleShape(segment0, segment1, radius), transform);
            Vector3      localSegment0 = capsule.top;
            Vector3      localSegment1 = capsule.bottom;

            radius = capsule.radius;

            AABB aabb = AABB.CreateCapsuleAABB(localSegment0, localSegment1, radius + .001f);

            tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferSingleCaps, infoDebug);

            Vector3         p1, p2, p3;
            IntersectPoints near;
            IntersectPoints nearest               = new IntersectPoints();
            float           radiusSqrd            = radius * radius;
            float           shortestDistance      = float.MaxValue;
            int             shortestTriangleIndex = -1;

            HashSet <int> .Enumerator enumerator = trianglesBufferSingleCaps.GetEnumerator();
            while (enumerator.MoveNext())
            {
                tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3);

                near = Geometry.ClosestPointOnTriangleToLine(localSegment0, localSegment1, p1, p2, p3, true);

                float distance = (near.second - near.first).sqrMagnitude;
                if (PointIsBetter(distance, shortestDistance, nearest.first, nearest.second, near.first, near.second, shortestTriangleIndex, enumerator.Current, radiusSqrd))
                {
                    shortestDistance      = distance;
                    nearest               = near;
                    shortestTriangleIndex = enumerator.Current;
                }
            }

            if (nearest.second == Vector3.zero)
            {
                return(new ContactInfo());
            }
            return(new ContactInfo(transform.TransformPoint(nearest.second), transform.TransformDirection(tree.GetTriangleNormal(shortestTriangleIndex))));
        }
        public List <ContactInfo> ClosestPointsOnSurface(Vector3 segment0, Vector3 segment1, float radius, List <ContactInfo> resultsBuffer)
        {
            resultsBuffer.Clear();
            trianglesBufferMultiCaps.Clear();
            closestPointsBufferMultiCaps.Clear();

            CapsuleShape capsule       = CapsuleShape.ToLocalOfUniformScale(new CapsuleShape(segment0, segment1, radius), transform);
            Vector3      localSegment0 = capsule.top;
            Vector3      localSegment1 = capsule.bottom;

            radius = capsule.radius;

            AABB aabb = AABB.CreateCapsuleAABB(localSegment0, localSegment1, radius + .001f);             //We add a small radius increase due to float point precision issues that rarely happen.

            tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferMultiCaps, infoDebug);

            Vector3         p1, p2, p3;
            IntersectPoints nearest;
            float           radiusSqrd = radius * radius;
            float           distance   = 0;

            HashSet <int> .Enumerator enumerator = trianglesBufferMultiCaps.GetEnumerator();
            while (enumerator.MoveNext())
            {
                tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3);

                nearest = Geometry.ClosestPointOnTriangleToLine(localSegment0, localSegment1, p1, p2, p3, true);

                distance = (nearest.second - nearest.first).sqrMagnitude;
                if (distance <= radiusSqrd)
                {
                    closestPointsBufferMultiCaps.Add(new ClosestTrianglePoint(nearest.second, distance, enumerator.Current, nearest.first, this));
                }
            }

            CleanUp(closestPointsBufferMultiCaps, 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));
            }
        }
 float CapsulePointsDistance()
 {
     return(CapsuleShape.PointsDistance(capsuleHeight, capsuleRadius));
 }
Exemplo n.º 7
0
        public static IList <Collider> OverlapCapsule(Vector3 origin, Vector3 direction, float height, float radius, IList <Collider> resultBuffer, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal)
        {
            CapsuleShape points = new CapsuleShape(origin, direction, height, radius);

            return(OverlapCapsule(points.bottom, points.top, radius, resultBuffer, layerMask, queryTriggerInteraction));
        }
Exemplo n.º 8
0
        public static bool CheckCapsule(Vector3 origin, Vector3 direction, float height, float radius, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal)
        {
            CapsuleShape points = new CapsuleShape(origin, direction, height, radius);

            return(CheckCapsule(points.bottom, points.top, radius, layerMask, queryTriggerInteraction));
        }
Exemplo n.º 9
0
        public static List <SphereCollisionInfo> DetectCollisions(Vector3 origin, Vector3 directionUp, float height, float radius, int mask, IList <Component> ignoreColliders, List <SphereCollisionInfo> resultBuffer, float checkOffset = 0f, bool multipleContactsPerCollider = true)
        {
            CapsuleShape points = new CapsuleShape(origin, directionUp, height, radius, checkOffset);

            return(DetectCollisions(points.top, points.bottom, radius, mask, ignoreColliders, resultBuffer, checkOffset, multipleContactsPerCollider));
        }
Exemplo n.º 10
0
        //Below taken from free asset on unity asset store - https://www.assetstore.unity3d.com/en/#!/content/11396

        public static void DrawCapsule(Vector3 origin, Vector3 direction, float height, float radius, Color color, float duration = .001f, bool depthTest = true)
        {
            CapsuleShape points = new CapsuleShape(origin, direction, height, radius);

            DrawCapsule(points.top, points.bottom, radius, color, duration, depthTest);
        }