Beispiel #1
0
        public bool CollideRingWithMouse(int MouseX, int MouseY, Viewport ActiveViewport, Matrix View, Matrix Projection, Matrix World)
        {
            Vector3 NearSource = new Vector3(MouseX, MouseY, 0f);
            Vector3 FarSource  = new Vector3(MouseX, MouseY, 1f);

            Vector3 NearPoint = ActiveViewport.Unproject(NearSource, Projection, View, World);
            Vector3 FarPoint  = ActiveViewport.Unproject(FarSource, Projection, View, World);

            // Create a ray from the near clip plane to the far clip plane.
            Vector3 RayDirection = FarPoint - NearPoint;

            RayDirection.Normalize();

            Matrix RotationMatrix = Matrix.Identity;

            RotationMatrix.Forward = RayDirection;
            RotationMatrix.Right   = Vector3.Normalize(Vector3.Cross(RotationMatrix.Forward, Vector3.Up));
            RotationMatrix.Up      = Vector3.Cross(RotationMatrix.Right, RotationMatrix.Forward);
            Vector3 Forward = Vector3.Transform(Vector3.Forward, RotationMatrix);
            Vector3 Right   = Vector3.Transform(Vector3.Right, RotationMatrix);
            Vector3 Up      = Vector3.Transform(Vector3.Up, RotationMatrix);

            PolygonMesh MouseCollisionBox = CreateMouseObject(MouseX, MouseY, ActiveViewport, View, Projection, World);

            var Axis1 = ComputePerpendicularAxis(0, 24);
            var Axis2 = ComputePerpendicularAxis(24, 24);
            var Axis3 = ComputePerpendicularAxis(48, 24);
            var Axis4 = ComputePerpendicularAxis(72, 24);

            var Vertex1 = new Vector3[24];
            var Vertex2 = new Vector3[24];
            var Vertex3 = new Vector3[24];
            var Vertex4 = new Vector3[24];

            for (int V = 0; V < 24; V++)
            {
                Vertex1[V] = ArrayVertex[V].Position;
                Vertex2[V] = ArrayVertex[V + 24].Position;
                Vertex3[V] = ArrayVertex[V + 48].Position;
                Vertex4[V] = ArrayVertex[V + 72].Position;
            }

            var col1 = CollideWithQuarterRing(MouseCollisionBox, Vertex1, Axis1);
            var col2 = CollideWithQuarterRing(MouseCollisionBox, Vertex2, Axis2);
            var col3 = CollideWithQuarterRing(MouseCollisionBox, Vertex3, Axis3);
            var col4 = CollideWithQuarterRing(MouseCollisionBox, Vertex4, Axis4);

            return(col1 || col2 || col3 || col4);
        }
Beispiel #2
0
        public Object3D()
        {
            _CollisionBox = new PolygonMesh();

            PositionMatrix = Matrix.Identity;
            RotationMatrix = Matrix.Identity;
            ScaleMatrix    = Matrix.Identity;

            _Forward   = Vector3.Forward;
            _Right     = Vector3.Right;
            _Up        = Vector3.Up;
            _Position  = Vector3.Zero;
            TotalYaw   = 0;
            TotalPitch = 0;
            TotalRoll  = 0;
            TotalScale = Vector3.One;
        }
Beispiel #3
0
        public PolygonMesh.PolygonMeshCollisionResult GetClosestObject(List <Object3D> ListOther, Vector3 Speed)
        {
            PolygonMesh.PolygonMeshCollisionResult FinalCollisionResult = new PolygonMesh.PolygonMeshCollisionResult(Vector3.Zero, -1);
            Object3D FinalLayerPolygon = null;

            foreach (Object3D ActiveObject3D in ListOther)
            {
                PolygonMesh.PolygonMeshCollisionResult CollisionResult = PolygonMesh.PolygonCollisionSAT(CollisionBox, ActiveObject3D.CollisionBox, Speed);

                if (FinalCollisionResult.Distance < 0 || (CollisionResult.Distance >= 0 && CollisionResult.Distance > FinalCollisionResult.Distance))
                {
                    FinalCollisionResult = CollisionResult;
                    FinalLayerPolygon    = ActiveObject3D;
                }
            }

            return(FinalCollisionResult);
        }
Beispiel #4
0
        public static void ProjectPolygon(Vector3 Axis, PolygonMesh Polygon, out float Min, out float Max)
        {
            float DotProduct = Vector3.Dot(Axis, Polygon.ArrayVertex[0]);

            Min = DotProduct;
            Max = DotProduct;
            for (int i = 0; i < Polygon.ArrayVertex.Length; i++)
            {
                DotProduct = Vector3.Dot(Axis, Polygon.ArrayVertex[i]);
                if (DotProduct < Min)
                {
                    Min = DotProduct;
                }
                else if (DotProduct > Max)
                {
                    Max = DotProduct;
                }
            }
        }
Beispiel #5
0
        public void MoveWithMouse(int MouseX, int MouseY, int OldMouseX, int OldMouseY, Viewport ActiveViewport, Matrix View, Matrix Projection, Matrix World)
        {
            Vector3 NearSource    = new Vector3(MouseX, MouseY, 0f);
            Vector3 FarSource     = new Vector3(MouseX, MouseY, 1f);
            Vector3 NearSourceOld = new Vector3(OldMouseX, OldMouseY, 0f);

            Vector3 NearPoint    = ActiveViewport.Unproject(NearSource, Projection, View, World);
            Vector3 NearPointOld = ActiveViewport.Unproject(NearSourceOld, Projection, View, World);
            Vector3 FarPoint     = ActiveViewport.Unproject(FarSource, Projection, View, World);

            // Create a ray from the near clip plane to the far clip plane.
            Vector3 RayDirection = FarPoint - NearPoint;

            RayDirection.Normalize();

            Matrix RotationMatrix = Matrix.Identity;

            RotationMatrix.Forward = RayDirection;
            RotationMatrix.Right   = Vector3.Normalize(Vector3.Cross(RotationMatrix.Forward, Vector3.Up));
            RotationMatrix.Up      = Vector3.Cross(RotationMatrix.Right, RotationMatrix.Forward);
            Vector3 Forward = Vector3.Transform(Vector3.Forward, RotationMatrix);
            Vector3 Right   = Vector3.Transform(Vector3.Right, RotationMatrix);
            Vector3 Up      = Vector3.Transform(Vector3.Up, RotationMatrix);

            float MinRight, MaxRight;
            float MinUp, MaxUp;

            PolygonMesh.ProjectPolygon(Right, CollisionBox, out MinRight, out MaxRight);
            PolygonMesh.ProjectPolygon(Up, CollisionBox, out MinUp, out MaxUp);
            float MouseRight    = Vector3.Dot(Right, NearPoint);
            float MouseUp       = Vector3.Dot(Up, NearPoint);
            float MouseRightOld = Vector3.Dot(Right, NearPointOld);
            float MouseUpOld    = Vector3.Dot(Up, NearPointOld);

            Position += Right * (MouseRightOld - MouseRight);
            Position += Right * (MouseUpOld - MouseUp);
        }
Beispiel #6
0
 public bool CollideWith(Object3D Other)
 {
     return(PolygonMesh.PolygonCollisionSAT(CollisionBox, Other.CollisionBox, Vector3.Zero).Collided);
 }
Beispiel #7
0
        private bool CollideWithQuarterRing(PolygonMesh MouseCollision, Vector3[] CollisionVertex, Vector3[] ArrayAxis)
        {
            PolygonMesh QuarterRightCollisionBox = new PolygonMesh(CollisionVertex, ArrayAxis);

            return(PolygonMesh.PolygonCollisionSAT(MouseCollision, QuarterRightCollisionBox, Vector3.Zero).Collided);
        }
Beispiel #8
0
        public static PolygonMeshCollisionResult PolygonCollisionSAT(PolygonMesh PolygonA, PolygonMesh PolygonB, Vector3 Speed)
        {
            bool Intersection     = true;
            bool IntersectionNext = true;

            float minA = 0, maxA = 0;
            float minB = 0, maxB = 0;

            int AxisCountA = PolygonA.ArrayAxis.Length;
            int AxisCountB = PolygonB.ArrayAxis.Length;
            int EdgeCountA = PolygonA.ArrayEdge.Length;
            int EdgeCountB = PolygonB.ArrayEdge.Length;

            Vector3 Axis;
            Vector3 AxisTranslation     = Vector3.Zero;
            float   minIntervalDistance = float.MaxValue;
            float   intervalDistance;

            Vector3[] CrossProduct = new Vector3[EdgeCountA * EdgeCountB];
            for (int EdgeIndexA = EdgeCountA - 1; EdgeIndexA >= 0; --EdgeIndexA)
            {
                for (int EdgeIndexB = EdgeCountB - 1; EdgeIndexB >= 0; --EdgeIndexB)
                {
                    CrossProduct[EdgeIndexA + EdgeIndexB * EdgeCountA] = Vector3.Cross(PolygonA.ArrayEdge[EdgeIndexA], PolygonB.ArrayEdge[EdgeIndexB]);
                }
            }

            for (int AxisIndex = 0; AxisIndex < AxisCountA + AxisCountB + CrossProduct.Length; AxisIndex++)
            {
                if (AxisIndex < AxisCountA)
                {
                    Axis = PolygonA.ArrayAxis[AxisIndex];
                }
                else if (AxisIndex < AxisCountA + AxisCountB)
                {
                    Axis = PolygonB.ArrayAxis[AxisIndex - AxisCountA];
                }
                else
                {
                    Axis = CrossProduct[AxisIndex - AxisCountA - AxisCountB];
                }

                ProjectPolygon(Axis, PolygonA, out minA, out maxA);
                ProjectPolygon(Axis, PolygonB, out minB, out maxB);

                if (IntervalDistance(minA, maxA, minB, maxB) >= 0)
                {
                    Intersection = false;
                }

                float AxeVitesse = Vector3.Dot(Axis, Speed);

                if (AxeVitesse < 0)
                {
                    minA += AxeVitesse;
                }
                else
                {
                    maxA += AxeVitesse;
                }

                intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance >= 0)
                {
                    IntersectionNext = false;
                }

                if (Intersection || IntersectionNext)
                {
                    intervalDistance = Math.Abs(intervalDistance);

                    if (intervalDistance < minIntervalDistance)
                    {
                        minIntervalDistance = intervalDistance;
                        AxisTranslation     = Axis;

                        Vector3 p = PolygonA.Center - PolygonB.Center;
                        if (Vector3.Dot(p, AxisTranslation) < 0)
                        {
                            AxisTranslation = -AxisTranslation;
                        }
                    }
                }
            }
            if (IntersectionNext)
            {
                PolygonMeshCollisionResult CollisionResult = new PolygonMeshCollisionResult(AxisTranslation, minIntervalDistance);

                return(CollisionResult);
            }

            return(new PolygonMeshCollisionResult(Vector3.Zero, -1));
        }