//  Find and return closer intersection of these two. If intersection is null then it's not really an intersection.
 public static MyIntersectionResultLineTriangleEx? GetCloserIntersection(ref MyIntersectionResultLineTriangleEx? a, ref MyIntersectionResultLineTriangleEx? b)
 {
     if (((a == null) && (b != null)) ||
         ((a != null) && (b != null) && (b.Value.Triangle.Distance < a.Value.Triangle.Distance)))
     {
         //  If only "b" contains valid intersection, or when it's closer than "a"
         return b;
     }
     else
     {
         //  This will be returned also when ((a == null) && (b == null))
         return a;
     }
 }
 //  Find if distance between two intersections is less than "tolerance distance".
 public static bool IsDistanceLessThanTolerance(ref MyIntersectionResultLineTriangleEx? a, ref MyIntersectionResultLineTriangleEx? b,
     float distanceTolerance)
 {
     if (((a == null) && (b != null)) ||
         ((a != null) && (b != null) && (Math.Abs(b.Value.Triangle.Distance - a.Value.Triangle.Distance) <= distanceTolerance)))
     {
         return true;
     }
     else
     {
         //  This will be returned also when ((a == null) && (b == null))
         return false;
     }
 }
Пример #3
0
        /// <summary>
        /// Returns closest hit from line start position.
        /// </summary>
        public bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? t, out bool hitHead)
        {
            // TODO: This now uses caspule of physics rigid body on the character, it needs to be changed to ragdoll
            //       Currently this approach will be used to support Characters with different skeleton than humanoid

            t = null;
            hitHead = false;

            if (!m_characterBoneCapsulesReady) UpdateCapsuleBones();
            if (!m_characterBoneCapsulesReady) return false;

            double closestDistanceToHit = double.MaxValue;
            int hitCapsule = -1;

            m_hitCapsule = null;
            m_hitInfo = null;

            Vector3D hitPosition = Vector3D.Zero;
            Vector3D hitPosition2 = Vector3D.Zero;
            Vector3 hitNormal = Vector3.Zero;
            Vector3 hitNormal2 = Vector3.Zero;

            for (int i = 0; i < m_bodyCapsules.Length; i++)
            {
                CapsuleD capsule = m_bodyCapsules[i];
                //if (capsule.IsIntersected(line, out hitVector, out hitVector2, out hitVector3))
                if (capsule.Intersect(line, ref hitPosition, ref hitPosition2, ref hitNormal, ref hitNormal2))
                {
                    double distanceToHit = Vector3.Distance(hitPosition, line.From);
                    if (distanceToHit >= closestDistanceToHit)
                        continue;

                    closestDistanceToHit = distanceToHit;

                    hitCapsule = i;

                    MyTriangle_Vertexes vertexes = new MyTriangle_Vertexes();
                    //TODO: Make correct alg. to make triangle from capsule intersection
                    vertexes.Vertex0 = hitPosition + line.Direction * 0.5f;
                    vertexes.Vertex1 = hitPosition + hitNormal * 0.5f;
                    vertexes.Vertex2 = hitPosition - hitNormal * 0.8f;

                    t = new VRage.Game.Models.MyIntersectionResultLineTriangleEx(
                        new VRage.Game.Models.MyIntersectionResultLineTriangle(
                        ref vertexes,
                        ref hitNormal,
                        Vector3.Distance(hitPosition, line.From)),
                        this, ref line,
                        (Vector3D)hitPosition,
                        hitNormal);
                }
            }

            if (t != null)
            {
                hitHead = hitCapsule == 0 && m_bodyCapsules.Length > 1;

                m_hitCapsule = m_bodyCapsules[hitCapsule];
                m_hitInfo = t;

                if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
                {
                    CapsuleD capsule = m_bodyCapsules[hitCapsule];
                    MyRenderProxy.DebugDrawCapsule(capsule.P0, capsule.P1, capsule.Radius, Color.Red, false, false);
                    MyRenderProxy.DebugDrawSphere(hitPosition, 0.1f, Color.White, 1f, false);
                }

                return true;
            }

            return false;
        }