コード例 #1
0
        private bool Disjoint(out float d, Vector3 axis, MyBox box, MyTriangle triangle, float collTolerance)
        {
            float min0, max0, min1, max1;

            box.GetSpan(out min0, out max0, axis);
            triangle.GetSpan(out min1, out max1, axis);

            if (min0 > (max1 + collTolerance + MyPhysicsConfig.Epsilon) ||
                min1 > (max0 + collTolerance + MyPhysicsConfig.Epsilon))
            {
                d = 0.0f;
                return(true);
            }

            if ((max0 > max1) && (min1 > min0))
            {
                // triangleVertexes is inside - choose the min dist to move it out
                d = System.Math.Min(max0 - min1, max1 - min0);
            }
            else if ((max1 > max0) && (min0 > min1))
            {
                // box is inside - choose the min dist to move it out
                d = System.Math.Min(max1 - min0, max0 - min1);
            }
            else
            {
                // objects overlap
                d  = (max0 < max1) ? max0 : max1;
                d -= (min0 > min1) ? min0 : min1;
            }

            return(false);
        }
コード例 #2
0
        private float Disjoint(out bool b, Vector3 axis, MyBox box, MyTriangle triangle, float collTolerance)
        {
            float ret;

            b = Disjoint(out ret, axis, box, triangle, collTolerance);
            return(ret);
        }
コード例 #3
0
        private int GetBoxTriangleIntersectionPoints(List <Vector3> pts, MyBox box, MyTriangle triangle, float combinationDistance)
        {
            // first intersect each edge of the box with the triangleVertexes
            MyBox.Edge[] edges;
            box.GetEdges(out edges);
            Vector3[] boxPts;
            box.GetCornerPoints(out boxPts);

            float tS;
            float tv1, tv2;

            int iEdge;

            for (iEdge = 0; iEdge < 12; ++iEdge)
            {
                MyBox.Edge edge = edges[iEdge];
                MySegment  seg  = new MySegment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]);
                if (SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle))
                {
                    AddPoint(pts, seg.GetPoint(tS), combinationDistance * combinationDistance);
                }
            }

            Vector3 pos, n;

            // now each edge of the triangleVertexes with the box
            for (iEdge = 0; iEdge < 3; ++iEdge)
            {
                Vector3   pt0 = triangle.GetPoint(iEdge);
                Vector3   pt1 = triangle.GetPoint((iEdge + 1) % 3);
                MySegment s1  = new MySegment(pt0, pt1 - pt0);
                MySegment s2  = new MySegment(pt1, pt0 - pt1);
                if (box.SegmentIntersect(out tS, out pos, out n, s1))
                {
                    AddPoint(pts, pos, combinationDistance * combinationDistance);
                }
                if (box.SegmentIntersect(out tS, out pos, out n, s2))
                {
                    AddPoint(pts, pos, combinationDistance * combinationDistance);
                }
            }

            return(pts.Count);
        }
コード例 #4
0
        private bool SegmentTriangleIntersection(out float tS, out float tT0, out float tT1, MySegment seg, MyTriangle triangle)
        {
            /// the parameters - if hit then they get copied into the args
            float u, v, t;

            tS  = 0;
            tT0 = 0;
            tT1 = 0;

            Vector3 e1 = triangle.Edge0;
            Vector3 e2 = triangle.Edge1;
            Vector3 p  = Vector3.Cross(seg.Delta, e2);
            float   a  = Vector3.Dot(e1, p);

            if (a > -MyPhysicsConfig.Epsilon && a < MyPhysicsConfig.Epsilon)
            {
                return(false);
            }
            float   f = 1.0f / a;
            Vector3 s = seg.Origin - triangle.Origin;

            u = f * Vector3.Dot(s, p);
            if (u < 0.0f || u > 1.0f)
            {
                return(false);
            }
            Vector3 q = Vector3.Cross(s, e1);

            v = f * Vector3.Dot(seg.Delta, q);
            if (v < 0.0f || (u + v) > 1.0f)
            {
                return(false);
            }
            t = f * Vector3.Dot(e2, q);
            if (t < 0.0f || t > 1.0f)
            {
                return(false);
            }

            tS  = t;
            tT0 = u;
            tT1 = v;
            //if (tS != 0) tS = t;
            //if (tT0 != 0) tT0 = u;
            //if (tT1 != 0) tT1 = v;
            return(true);
        }
コード例 #5
0
        private bool DoOverlapBoxTriangleTest(MyBox oldBox, MyBox newBox, MyTriangle_Vertex_Normal triangle, MyPlane plane, float collTolerance,
                                              ref Matrix transformMatrix, ref Vector3 oldBoxPos, ref Vector3 newBoxPos, List <MyCollisionPointStruct> collPoints)
        {
            Matrix dirs0 = newBox.Orientation;

            dirs0.Translation = Vector3.Zero;

            #region Triangle
            Vector3 triVec0 = triangle.Vertexes.Vertex0;
            Vector3 triVec1 = triangle.Vertexes.Vertex1;
            Vector3 triVec2 = triangle.Vertexes.Vertex2;
            //mesh.GetVertex(triangle.GetVertexIndex(0), out triVec0);
            //mesh.GetVertex(triangle.GetVertexIndex(1), out triVec1);
            //mesh.GetVertex(triangle.GetVertexIndex(2), out triVec2);

            // Deano move tri into world space
            //Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            MyTriangle tri = new MyTriangle(ref triVec0, ref triVec1, ref triVec2);
            #endregion


            #region triEdge0
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region triEdge1
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region triEdge2
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion


            if (triEdge0.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge1.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge2.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }


            /*
             * triEdge0 = MyMwcUtils.Normalize(triEdge0);
             * triEdge1 = MyMwcUtils.Normalize(triEdge1);
             * triEdge2 = MyMwcUtils.Normalize(triEdge2);
             */
            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            //Vector3 triNormal = triangle.Plane.Normal;
            Vector3 triNormal = plane.Normal;
            Vector3.TransformNormal(ref triNormal, ref transformMatrix, out triNormal);



            // the 15 potential separating axes (comment by Marek Rosa: note says 15 but code uses 13... I don't know why, mistake in the note??)
            const int        NUM_AXES = 13;
            MyVector3Array13 axes     = new MyVector3Array13();

            axes[0]  = triNormal;
            axes[1]  = dirs0.Right;
            axes[2]  = dirs0.Up;
            axes[3]  = dirs0.Backward;
            axes[4]  = Vector3.Cross(axes[1], triEdge0);
            axes[5]  = Vector3.Cross(axes[1], triEdge1);
            axes[6]  = Vector3.Cross(axes[1], triEdge2);
            axes[7]  = Vector3.Cross(axes[2], triEdge0);
            axes[8]  = Vector3.Cross(axes[2], triEdge1);
            axes[9]  = Vector3.Cross(axes[2], triEdge2);
            axes[10] = Vector3.Cross(axes[3], triEdge0);
            axes[11] = Vector3.Cross(axes[3], triEdge1);
            axes[12] = Vector3.Cross(axes[3], triEdge2);

            // the overlap depths along each axis
            MyFloatArray13 overlapDepths = new MyFloatArray13();

            // see if the boxes are separate along any axis, and if not keep a
            // record of the depths along each axis
            int i;
            for (i = 0; i < NUM_AXES; ++i)
            {
                overlapDepths[i] = 1.0f;

                bool b;
                overlapDepths[i] = Disjoint(out b, axes[i], newBox, tri, collTolerance);
                if (b)
                {
                    return(false);
                }
            }

            // The box overlap, find the separation depth closest to 0.
            float minDepth = float.MaxValue;
            int   minAxis  = -1;

            for (i = 0; i < NUM_AXES; ++i)
            {
                // If we can't normalise the axis, skip it
                float l2 = axes[i].LengthSquared();
                if (l2 < MyPhysicsConfig.Epsilon)
                {
                    continue;
                }

                // Normalise the separation axis and the depth
                float invl = 1.0f / (float)System.Math.Sqrt(l2);
                axes[i]          *= invl;
                overlapDepths[i] *= invl;

                // If this axis is the minimum, select it
                if (overlapDepths[i] < minDepth)
                {
                    minDepth = overlapDepths[i];
                    minAxis  = i;
                }
            }

            if (minAxis == -1)
            {
                return(false);
            }


            // Make sure the axis is facing towards the 0th box.
            // if not, invert it
            Vector3 D     = newBox.GetCentre() - tri.Centre;
            Vector3 N     = axes[minAxis];
            float   depth = overlapDepths[minAxis];

            if (Vector3.Dot(D, N) > 0.0f)
            {
                N *= -1;
            }

            Vector3 boxOldPos = oldBoxPos;                   //(info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = newBoxPos;                   // (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos   = transformMatrix.Translation; // (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            m_pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(m_pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region delta
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region oldDepth
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion


            // report collisions

            int numPts = m_pts.Count;
            if (numPts > 0)
            {
                for (i = 0; i < numPts; ++i)
                {
                    collPoints.Add(new MyCollisionPointStruct(-oldDepth, new MySmallCollPointInfo(m_pts[i] - boxNewPos, m_pts[i] - meshPos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, N, -oldDepth, m_pts[i])));
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #6
0
        private bool DoOverlapBoxTriangleStaticTest(MyBox oldBox, MyBox newBox,
                                                    MyTriangle_Vertex_Normal triangle, MyPlane plane, float collTolerance,
                                                    ref Matrix transformMatrix, ref Vector3 oldBoxPos, ref Vector3 newBoxPos)
        {
            Matrix dirs0 = newBox.Orientation;

            dirs0.Translation = Vector3.Zero;

            #region REFERENCE: Triangle tri = new Triangle(mesh.GetVertex(triangleVertexes.GetVertexIndex(0)),mesh.GetVertex(triangleVertexes.GetVertexIndex(1)),mesh.GetVertex(triangleVertexes.GetVertexIndex(2)));
            Vector3 triVec0 = triangle.Vertexes.Vertex0;
            Vector3 triVec1 = triangle.Vertexes.Vertex1;
            Vector3 triVec2 = triangle.Vertexes.Vertex2;

            // Deano move tri into world space
            //Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            MyTriangle tri = new MyTriangle(ref triVec0, ref triVec1, ref triVec2);
            #endregion

            #region REFERENCE Vector3 triEdge0 = (tri.GetPoint(1) - tri.GetPoint(0));
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region REFERENCE Vector3 triEdge1 = (tri.GetPoint(2) - tri.GetPoint(1));
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region REFERENCE Vector3 triEdge2 = (tri.GetPoint(0) - tri.GetPoint(2));
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion

            if (triEdge0.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge1.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge2.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }

            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            //Vector3 triNormal = triangle.Plane.Normal;
            Vector3 triNormal = plane.Normal;
            Vector3.TransformNormal(ref triNormal, ref transformMatrix, out triNormal);

            // the 15 potential separating axes
            const int numAxes = 13;
            Vector3[] axes    = new Vector3[numAxes];

            axes[0] = triNormal;
            axes[1] = dirs0.Right;
            axes[2] = dirs0.Up;
            axes[3] = dirs0.Backward;
            Vector3.Cross(ref axes[1], ref triEdge0, out axes[4]);
            Vector3.Cross(ref axes[1], ref triEdge1, out axes[5]);
            Vector3.Cross(ref axes[1], ref triEdge2, out axes[6]);
            Vector3.Cross(ref axes[2], ref triEdge0, out axes[7]);
            Vector3.Cross(ref axes[2], ref triEdge1, out axes[8]);
            Vector3.Cross(ref axes[2], ref triEdge2, out axes[9]);
            Vector3.Cross(ref axes[3], ref triEdge0, out axes[10]);
            Vector3.Cross(ref axes[3], ref triEdge1, out axes[11]);
            Vector3.Cross(ref axes[3], ref triEdge2, out axes[12]);

            // the overlap depths along each axis
            float[] overlapDepths = new float[numAxes];

            // see if the boxes are separate along any axis, and if not keep a
            // record of the depths along each axis
            int i;
            for (i = 0; i < numAxes; ++i)
            {
                overlapDepths[i] = 1.0f;
                if (Disjoint(out overlapDepths[i], axes[i], newBox, tri, collTolerance))
                {
                    return(false);
                }
            }

            // The box overlap, find the separation depth closest to 0.
            float minDepth = float.MaxValue;
            int   minAxis  = -1;

            for (i = 0; i < numAxes; ++i)
            {
                // If we can't normalise the axis, skip it
                float l2 = axes[i].LengthSquared();
                if (l2 < MyPhysicsConfig.Epsilon)
                {
                    continue;
                }

                // Normalise the separation axis and the depth
                float invl = 1.0f / (float)System.Math.Sqrt(l2);
                axes[i]          *= invl;
                overlapDepths[i] *= invl;

                // If this axis is the minimum, select it
                if (overlapDepths[i] < minDepth)
                {
                    minDepth = overlapDepths[i];
                    minAxis  = i;
                }
            }

            if (minAxis == -1)
            {
                return(false);
            }

            // Make sure the axis is facing towards the 0th box.
            // if not, invert it
            Vector3 D     = newBox.GetCentre() - tri.Centre;
            Vector3 N     = axes[minAxis];
            float   depth = overlapDepths[minAxis];

            if (Vector3.Dot(D, N) > 0.0f)
            {
                N *= -1;
            }

            Vector3 boxOldPos = oldBoxPos;                   //(info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = newBoxPos;                   // (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos   = transformMatrix.Translation; // (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            List <Vector3> pts = new List <Vector3>();
            //pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region delta
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region oldDepth
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion

            // report collisions
            int numPts = pts.Count;

            if (numPts > 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }