Detect() public static method

Checks two shapes for collisions.
public static Detect ( ISupportMappable support1, ISupportMappable support2, Jitter.LinearMath.JMatrix &orientation1, Jitter.LinearMath.JMatrix &orientation2, Jitter.LinearMath.JVector &position1, Jitter.LinearMath.JVector &position2, Jitter.LinearMath.JVector &point, Jitter.LinearMath.JVector &normal, float &penetration ) : bool
support1 ISupportMappable The SupportMappable implementation of the first shape to test.
support2 ISupportMappable The SupportMappable implementation of the seconds shape to test.
orientation1 Jitter.LinearMath.JMatrix The orientation of the first shape.
orientation2 Jitter.LinearMath.JMatrix The orientation of the second shape.
position1 Jitter.LinearMath.JVector The position of the first shape.
position2 Jitter.LinearMath.JVector The position of the second shape
point Jitter.LinearMath.JVector The pointin world coordinates, where collision occur.
normal Jitter.LinearMath.JVector The normal pointing from body2 to body1.
penetration float Estimated penetration depth of the collision.
return bool
        private void DetectSoftSoft(SoftBody body1, SoftBody body2)
        {
            List <int> my    = potentialTriangleLists.GetNew();
            List <int> other = potentialTriangleLists.GetNew();

            body1.dynamicTree.Query(other, my, body2.dynamicTree);

            for (int i = 0; i < other.Count; i++)
            {
                SoftBody.Triangle myTriangle    = body1.dynamicTree.GetUserData(my[i]);
                SoftBody.Triangle otherTriangle = body2.dynamicTree.GetUserData(other[i]);

                JVector point, normal;
                float   penetration;
                bool    result;

                result = XenoCollide.Detect(myTriangle, otherTriangle, ref JMatrix.InternalIdentity, ref JMatrix.InternalIdentity,
                                            ref JVector.InternalZero, ref JVector.InternalZero, out point, out normal, out penetration);

                if (result)
                {
                    int minIndexMy    = FindNearestTrianglePoint(body1, my[i], ref point);
                    int minIndexOther = FindNearestTrianglePoint(body2, other[i], ref point);


                    RaiseCollisionDetected(body1.VertexBodies[minIndexMy],
                                           body2.VertexBodies[minIndexOther], ref point, ref point, ref normal, penetration);
                }
            }

            my.Clear(); other.Clear();
            potentialTriangleLists.GiveBack(my);
            potentialTriangleLists.GiveBack(other);
        }
        private void DetectSoftRigid(RigidBody rigidBody, SoftBody softBody)
        {
            if (rigidBody.Shape is Multishape)
            {
                Multishape ms = (rigidBody.Shape as Multishape);
                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = softBody.BoundingBox;
                transformedBoundingBox.InverseTransform(ref rigidBody.position, ref rigidBody.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                List <int> detected = potentialTriangleLists.GetNew();
                softBody.dynamicTree.Query(detected, ref rigidBody.boundingBox);

                foreach (int i in detected)
                {
                    SoftBody.Triangle t = softBody.dynamicTree.GetUserData(i);

                    JVector point, normal;
                    float   penetration;
                    bool    result;

                    for (int e = 0; e < msLength; e++)
                    {
                        ms.SetCurrentShape(e);

                        result = XenoCollide.Detect(ms, t, ref rigidBody.orientation, ref JMatrix.InternalIdentity,
                                                    ref rigidBody.position, ref JVector.InternalZero, out point, out normal, out penetration);

                        if (result)
                        {
                            int minIndex = FindNearestTrianglePoint(softBody, i, ref point);

                            if (this.RaisePassedNarrowphase(rigidBody, softBody.points[minIndex],
                                                            ref point, ref normal, penetration))
                            {
                                RaiseCollisionDetected(rigidBody,
                                                       softBody.points[minIndex], ref point, ref point, ref normal, penetration);
                            }
                        }
                    }
                }

                detected.Clear(); potentialTriangleLists.GiveBack(detected);
                ms.ReturnWorkingClone();
            }
            else
            {
                List <int> detected = potentialTriangleLists.GetNew();
                softBody.dynamicTree.Query(detected, ref rigidBody.boundingBox);

                foreach (int i in detected)
                {
                    SoftBody.Triangle t = softBody.dynamicTree.GetUserData(i);

                    JVector point, normal;
                    float   penetration;
                    bool    result;

                    result = XenoCollide.Detect(rigidBody.Shape, t, ref rigidBody.orientation, ref JMatrix.InternalIdentity,
                                                ref rigidBody.position, ref JVector.InternalZero, out point, out normal, out penetration);

                    if (result)
                    {
                        int minIndex = FindNearestTrianglePoint(softBody, i, ref point);

                        if (this.RaisePassedNarrowphase(rigidBody, softBody.points[minIndex],
                                                        ref point, ref normal, penetration))
                        {
                            RaiseCollisionDetected(rigidBody,
                                                   softBody.points[minIndex], ref point, ref point, ref normal, penetration);
                        }
                    }
                }

                detected.Clear();
                potentialTriangleLists.GiveBack(detected);
            }
        }
        private void DetectRigidRigid(RigidBody body1, RigidBody body2)
        {
            bool b1IsMulti = (body1.Shape is Multishape);
            bool b2IsMulti = (body2.Shape is Multishape);

            JVector point, normal;
            float   penetration;

            if (!b1IsMulti && !b2IsMulti)
            {
                if (XenoCollide.Detect(body1.Shape, body2.Shape, ref body1.orientation,
                                       ref body2.orientation, ref body1.position, ref body2.position,
                                       out point, out normal, out penetration))
                {
                    if (this.RaisePassedNarrowphase(body1, body2, ref point, ref normal, penetration))
                    {
                        JVector point1, point2;
                        FindSupportPoints(body1, body2, body1.Shape, body2.Shape, ref point, ref normal, out point1, out point2);
                        RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                    }
                }
            }
            else if (b1IsMulti && b2IsMulti)
            {
                Multishape ms1 = (body1.Shape as Multishape);
                Multishape ms2 = (body2.Shape as Multishape);

                ms1 = ms1.RequestWorkingClone();
                ms2 = ms2.RequestWorkingClone();

                JBBox transformedBoundingBox = body2.boundingBox;
                transformedBoundingBox.InverseTransform(ref body1.position, ref body1.orientation);

                int ms1Length = ms1.Prepare(ref transformedBoundingBox);

                transformedBoundingBox = body1.boundingBox;
                transformedBoundingBox.InverseTransform(ref body2.position, ref body2.orientation);

                int ms2Length = ms2.Prepare(ref transformedBoundingBox);

                if (ms1Length == 0 || ms2Length == 0)
                {
                    ms1.ReturnWorkingClone();
                    ms2.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < ms1Length; i++)
                {
                    ms1.SetCurrentShape(i);

                    for (int e = 0; e < ms2Length; e++)
                    {
                        ms2.SetCurrentShape(e);

                        if (XenoCollide.Detect(ms1, ms2, ref body1.orientation,
                                               ref body2.orientation, ref body1.position, ref body2.position,
                                               out point, out normal, out penetration))
                        {
                            if (this.RaisePassedNarrowphase(body1, body2, ref point, ref normal, penetration))
                            {
                                JVector point1, point2;
                                FindSupportPoints(body1, body2, ms1, ms2, ref point, ref normal, out point1, out point2);
                                RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                            }
                        }
                    }
                }

                ms1.ReturnWorkingClone();
                ms2.ReturnWorkingClone();
            }
            else
            {
                RigidBody b1, b2;

                if (body2.Shape is Multishape)
                {
                    b1 = body2; b2 = body1;
                }
                else
                {
                    b2 = body2; b1 = body1;
                }

                Multishape ms = (b1.Shape as Multishape);

                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = b2.boundingBox;
                transformedBoundingBox.InverseTransform(ref b1.position, ref b1.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                if (msLength == 0)
                {
                    ms.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < msLength; i++)
                {
                    ms.SetCurrentShape(i);

                    if (XenoCollide.Detect(ms, b2.Shape, ref b1.orientation,
                                           ref b2.orientation, ref b1.position, ref b2.position,
                                           out point, out normal, out penetration))
                    {
                        if (this.RaisePassedNarrowphase(b1, b2, ref point, ref normal, penetration))
                        {
                            JVector point1, point2;
                            FindSupportPoints(b1, b2, ms, b2.Shape, ref point, ref normal, out point1, out point2);

                            if (useTerrainNormal && ms is TerrainShape)
                            {
                                (ms as TerrainShape).CollisionNormal(out normal);
                                JVector.Transform(ref normal, ref b1.orientation, out normal);
                            }
                            else if (useTriangleMeshNormal && ms is TriangleMeshShape)
                            {
                                (ms as TriangleMeshShape).CollisionNormal(out normal);
                                JVector.Transform(ref normal, ref b1.orientation, out normal);
                            }

                            RaiseCollisionDetected(b1, b2, ref point1, ref point2, ref normal, penetration);
                        }
                    }
                }

                ms.ReturnWorkingClone();
            }
        }
        private void DetectRigidRigid(RigidBody body1, RigidBody body2)
        {
            bool b1IsMulti = (body1.Shape is Multishape);
            bool b2IsMulti = (body2.Shape is Multishape);

            bool speculative = speculativeContacts ||
                               (body1.EnableSpeculativeContacts || body2.EnableSpeculativeContacts);

            JVector point, normal;
            float   penetration;

            if (!b1IsMulti && !b2IsMulti)
            {
                if (XenoCollide.Detect(body1.Shape, body2.Shape, ref body1.orientation,
                                       ref body2.orientation, ref body1.position, ref body2.position,
                                       out point, out normal, out penetration))
                {
                    JVector point1, point2;
                    FindSupportPoints(body1, body2, body1.Shape, body2.Shape, ref point, ref normal, out point1, out point2);
                    RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                }
                else if (speculative)
                {
                    JVector hit1, hit2;

                    if (GJKCollide.ClosestPoints(body1.Shape, body2.Shape, ref body1.orientation, ref body2.orientation,
                                                 ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                    {
                        JVector delta = hit2 - hit1;

                        if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                        {
                            penetration = delta * normal;

                            if (penetration < 0.0f)
                            {
                                RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                            }
                        }
                    }
                }
            }
            else if (b1IsMulti && b2IsMulti)
            {
                Multishape ms1 = (body1.Shape as Multishape);
                Multishape ms2 = (body2.Shape as Multishape);

                ms1 = ms1.RequestWorkingClone();
                ms2 = ms2.RequestWorkingClone();

                JBBox transformedBoundingBox = body2.boundingBox;
                transformedBoundingBox.InverseTransform(ref body1.position, ref body1.orientation);

                int ms1Length = ms1.Prepare(ref transformedBoundingBox);

                transformedBoundingBox = body1.boundingBox;
                transformedBoundingBox.InverseTransform(ref body2.position, ref body2.orientation);

                int ms2Length = ms2.Prepare(ref transformedBoundingBox);

                if (ms1Length == 0 || ms2Length == 0)
                {
                    ms1.ReturnWorkingClone();
                    ms2.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < ms1Length; i++)
                {
                    ms1.SetCurrentShape(i);

                    for (int e = 0; e < ms2Length; e++)
                    {
                        ms2.SetCurrentShape(e);

                        if (XenoCollide.Detect(ms1, ms2, ref body1.orientation,
                                               ref body2.orientation, ref body1.position, ref body2.position,
                                               out point, out normal, out penetration))
                        {
                            JVector point1, point2;
                            FindSupportPoints(body1, body2, ms1, ms2, ref point, ref normal, out point1, out point2);
                            RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                        }
                        else if (speculative)
                        {
                            JVector hit1, hit2;

                            if (GJKCollide.ClosestPoints(ms1, ms2, ref body1.orientation, ref body2.orientation,
                                                         ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                            {
                                JVector delta = hit2 - hit1;

                                if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                                {
                                    penetration = delta * normal;

                                    if (penetration < 0.0f)
                                    {
                                        RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                                    }
                                }
                            }
                        }
                    }
                }

                ms1.ReturnWorkingClone();
                ms2.ReturnWorkingClone();
            }
            else
            {
                RigidBody b1, b2;

                if (body2.Shape is Multishape)
                {
                    b1 = body2; b2 = body1;
                }
                else
                {
                    b2 = body2; b1 = body1;
                }

                Multishape ms = (b1.Shape as Multishape);

                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = b2.boundingBox;
                transformedBoundingBox.InverseTransform(ref b1.position, ref b1.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                if (msLength == 0)
                {
                    ms.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < msLength; i++)
                {
                    ms.SetCurrentShape(i);

                    if (XenoCollide.Detect(ms, b2.Shape, ref b1.orientation,
                                           ref b2.orientation, ref b1.position, ref b2.position,
                                           out point, out normal, out penetration))
                    {
                        JVector point1, point2;
                        FindSupportPoints(b1, b2, ms, b2.Shape, ref point, ref normal, out point1, out point2);

                        if (useTerrainNormal && ms is TerrainShape)
                        {
                            (ms as TerrainShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }
                        else if (useTriangleMeshNormal && ms is TriangleMeshShape)
                        {
                            (ms as TriangleMeshShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }

                        RaiseCollisionDetected(b1, b2, ref point1, ref point2, ref normal, penetration);
                    }
                    else if (speculative)
                    {
                        JVector hit1, hit2;

                        if (GJKCollide.ClosestPoints(ms, b2.Shape, ref b1.orientation, ref b2.orientation,
                                                     ref b1.position, ref b2.position, out hit1, out hit2, out normal))
                        {
                            JVector delta = hit2 - hit1;

                            if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                            {
                                penetration = delta * normal;

                                if (penetration < 0.0f)
                                {
                                    RaiseCollisionDetected(b1, b2, ref hit1, ref hit2, ref normal, penetration);
                                }
                            }
                        }
                    }
                }

                ms.ReturnWorkingClone();
            }
        }
Beispiel #5
0
        private void DetectRigidRigid(RigidBody body1, RigidBody body2)
        {
            // CUSTOM: Added custom detection callbacks (primarily to accommodate actor movement on surfaces).
            var callback1 = body1.ShouldGenerateContact;
            var callback2 = body2.ShouldGenerateContact;

            bool b1IsMulti = (body1.Shape is Multishape);
            bool b2IsMulti = (body2.Shape is Multishape);

            bool speculative = speculativeContacts ||
                               (body1.AreSpeculativeContactsEnabled || body2.AreSpeculativeContactsEnabled);

            JVector point, normal;
            float   penetration;

            if (!b1IsMulti && !b2IsMulti)
            {
                // CUSTOM: Added these callbacks (two rigid bodies).
                if ((callback1 != null && !callback1(body2, null)) || (callback2 != null && !callback2(body1, null)))
                {
                    return;
                }

                if (XenoCollide.Detect(body1.Shape, body2.Shape, ref body1.orientation,
                                       ref body2.orientation, ref body1.position, ref body2.position,
                                       out point, out normal, out penetration))
                {
                    JVector point1, point2;
                    FindSupportPoints(body1, body2, body1.Shape, body2.Shape, ref point, ref normal, out point1, out point2);
                    RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                }
                else if (speculative)
                {
                    JVector hit1, hit2;

                    if (GJKCollide.ClosestPoints(body1.Shape, body2.Shape, ref body1.orientation, ref body2.orientation,
                                                 ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                    {
                        JVector delta = hit2 - hit1;

                        if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                        {
                            penetration = delta * normal;

                            if (penetration < 0.0f)
                            {
                                RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                            }
                        }
                    }
                }
            }
            else if (b1IsMulti && b2IsMulti)
            {
                Multishape ms1 = (body1.Shape as Multishape);
                Multishape ms2 = (body2.Shape as Multishape);

                ms1 = ms1.RequestWorkingClone();
                ms2 = ms2.RequestWorkingClone();

                JBBox transformedBoundingBox = body2.boundingBox;
                transformedBoundingBox.InverseTransform(ref body1.position, ref body1.orientation);

                int ms1Length = ms1.Prepare(ref transformedBoundingBox);

                transformedBoundingBox = body1.boundingBox;
                transformedBoundingBox.InverseTransform(ref body2.position, ref body2.orientation);

                int ms2Length = ms2.Prepare(ref transformedBoundingBox);

                if (ms1Length == 0 || ms2Length == 0)
                {
                    ms1.ReturnWorkingClone();
                    ms2.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < ms1Length; i++)
                {
                    ms1.SetCurrentShape(i);

                    for (int e = 0; e < ms2Length; e++)
                    {
                        ms2.SetCurrentShape(e);

                        if (XenoCollide.Detect(ms1, ms2, ref body1.orientation,
                                               ref body2.orientation, ref body1.position, ref body2.position,
                                               out point, out normal, out penetration))
                        {
                            JVector point1, point2;
                            FindSupportPoints(body1, body2, ms1, ms2, ref point, ref normal, out point1, out point2);
                            RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                        }
                        else if (speculative)
                        {
                            JVector hit1, hit2;

                            if (GJKCollide.ClosestPoints(ms1, ms2, ref body1.orientation, ref body2.orientation,
                                                         ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                            {
                                JVector delta = hit2 - hit1;

                                if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                                {
                                    penetration = delta * normal;

                                    if (penetration < 0.0f)
                                    {
                                        RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                                    }
                                }
                            }
                        }
                    }
                }

                ms1.ReturnWorkingClone();
                ms2.ReturnWorkingClone();
            }
            else
            {
                RigidBody b1, b2;

                if (body2.Shape is Multishape)
                {
                    // CUSTOM: Swapped callbacks here as well.
                    b1 = body2;
                    b2 = body1;

                    // A proper swap here (using a temporary variable) isn't necessary since, by this point, the other
                    // callback (attached to the static body) is intentionally not used.
                    callback2 = callback1;
                }
                else
                {
                    b2 = body2;
                    b1 = body1;
                }

                Multishape ms = (b1.Shape as Multishape);

                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = b2.boundingBox;
                transformedBoundingBox.InverseTransform(ref b1.position, ref b1.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                if (msLength == 0)
                {
                    ms.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < msLength; i++)
                {
                    ms.SetCurrentShape(i);

                    // CUSTOM: Added this callback (to allow specific triangle collisions to be ignored).
                    bool shouldCollideWith = ms is TriangleMeshShape tMesh && (callback2 == null ||
                                                                               callback2(b1, tMesh.CurrentTriangle));

                    if (shouldCollideWith && XenoCollide.Detect(ms, b2.Shape, ref b1.orientation,
                                                                ref b2.orientation, ref b1.position, ref b2.position,
                                                                out point, out normal, out penetration))
                    {
                        JVector[] triangle = null;
                        FindSupportPoints(b1, b2, ms, b2.Shape, ref point, ref normal, out var point1, out var point2);

                        if (useTerrainNormal && ms is TerrainShape)
                        {
                            (ms as TerrainShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }
                        else if (useTriangleMeshNormal)
                        {
                            tMesh    = ms as TriangleMeshShape;
                            triangle = tMesh.CurrentTriangle;
                            tMesh.CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }

                        RaiseCollisionDetected(b1, b2, ref point1, ref point2, ref normal, triangle, penetration);
                    }
                    else if (speculative)
                    {
                        JVector hit1, hit2;

                        if (GJKCollide.ClosestPoints(ms, b2.Shape, ref b1.orientation, ref b2.orientation,
                                                     ref b1.position, ref b2.position, out hit1, out hit2, out normal))
                        {
                            JVector delta = hit2 - hit1;

                            if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                            {
                                penetration = delta * normal;

                                if (penetration < 0.0f)
                                {
                                    RaiseCollisionDetected(b1, b2, ref hit1, ref hit2, ref normal, penetration);
                                }
                            }
                        }
                    }
                }

                ms.ReturnWorkingClone();
            }
        }