public void FrustumExtractionTests()
        {
            {
                Matrix4X4 perspectiveMatrix = Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.Tau / 4, 1, 3, 507);
                Frustum   frustum           = Frustum.FrustumFromProjectionMatrix(perspectiveMatrix);

                // left
                Assert.IsTrue(frustum.Planes[0].Normal.Equals(new Vector3(1, 0, -1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[0].DistanceFromOrigin, 0, .0001);
                // right
                Assert.IsTrue(frustum.Planes[1].Normal.Equals(new Vector3(-1, 0, -1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[1].DistanceFromOrigin, 0, .0001);
                // bottom
                Assert.IsTrue(frustum.Planes[2].Normal.Equals(new Vector3(0, 1, -1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[2].DistanceFromOrigin, 0, .0001);
                // top
                Assert.IsTrue(frustum.Planes[3].Normal.Equals(new Vector3(0, -1, -1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[3].DistanceFromOrigin, 0, .0001);
                // near
                Assert.IsTrue(frustum.Planes[4].Normal.Equals(new Vector3(0, 0, -1), .0001));
                Assert.AreEqual(frustum.Planes[4].DistanceFromOrigin, 3, .0001);
                // far
                Assert.IsTrue(frustum.Planes[5].Normal.Equals(new Vector3(0, 0, 1), .0001));
                Assert.AreEqual(frustum.Planes[5].DistanceFromOrigin, -507, .0001);
            }
        }
예제 #2
0
 public void CalculateProjectionMatrix()
 {
     projectionMatrix = Matrix4X4.Identity;
     if (Width > 0 && Height > 0)
     {
         Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), Width / Height, 0.1f, 100.0f, out projectionMatrix);
         inverseProjectionMatrix = Matrix4X4.Invert(ProjectionMatrix);
     }
 }
예제 #3
0
        public Matrix4X4 GetProjectionMatrix()
        {
            Matrix4X4 projectionMatrix = Matrix4X4.Identity;

            if (Width > 0 && Height > 0)
            {
                Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), Width / Height, 0.1f, 100.0f, out projectionMatrix);
            }

            return(projectionMatrix);
        }
예제 #4
0
        void SetTransforms(double width, double height)
        {
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Matrix4X4 viewMatrix = Matrix4X4.Identity;

            Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), width / height, 0.1f, 100.0f, out viewMatrix);
            Gl.glLoadMatrixd(viewMatrix.GetAsDoubleArray());

            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position);
        }
        public void FrustumTransformTests()
        {
            {
                Frustum frustum = new Frustum(
                    new Plane(new Vector3(1, 0, 0), -20),
                    new Plane(new Vector3(-1, 0, 0), -20),
                    new Plane(new Vector3(0, 1, 0), -20),
                    new Plane(new Vector3(0, -1, 0), -20),
                    new Plane(new Vector3(0, 0, 1), -20),
                    new Plane(new Vector3(0, 0, -1), -20));

                Vector3Tests.TestFrustumClipLine(frustum, new Vector3(-5, 0, 0), new Vector3(5, 0, 0), true, new Vector3(-5, 0, 0), new Vector3(5, 0, 0));
                Vector3Tests.TestFrustumClipLine(frustum, new Vector3(-50, 0, 0), new Vector3(-21, 0, 0), false, null, null);
                Vector3Tests.TestFrustumClipLine(frustum, new Vector3(-50, 0, 0), new Vector3(-19, 0, 0), true, new Vector3(-20, 0, 0), new Vector3(-19, 0, 0));

                // moved right
                {
                    Frustum movedRightFrustum = Frustum.Transform(frustum, Matrix4X4.CreateTranslation(10, 0, 0));
                    Assert.IsTrue(movedRightFrustum.Planes[0] == new Plane(new Vector3(1, 0, 0), -10));
                    Assert.IsTrue(movedRightFrustum.Planes[1] == new Plane(new Vector3(-1, 0, 0), -30));
                    Assert.IsTrue(movedRightFrustum.Planes[2] == frustum.Planes[2]);
                    Assert.IsTrue(movedRightFrustum.Planes[3] == frustum.Planes[3]);
                    Assert.IsTrue(movedRightFrustum.Planes[4] == frustum.Planes[4]);
                    Assert.IsTrue(movedRightFrustum.Planes[5] == frustum.Planes[5]);

                    Vector3Tests.TestFrustumClipLine(movedRightFrustum, new Vector3(-5, 0, 0), new Vector3(5, 0, 0), true, new Vector3(-5, 0, 0), new Vector3(5, 0, 0));
                    Vector3Tests.TestFrustumClipLine(movedRightFrustum, new Vector3(-50, 0, 0), new Vector3(-11, 0, 0), false, null, null);
                    Vector3Tests.TestFrustumClipLine(movedRightFrustum, new Vector3(-50, 0, 0), new Vector3(-9, 0, 0), true, new Vector3(-10, 0, 0), new Vector3(-9, 0, 0));
                }

                // rotated right
                {
                    Frustum   movedRightFrustum = Frustum.Transform(frustum, Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(45)));
                    Matrix4X4 testMatrix        = Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(45));
                    Plane     control           = new Plane(Vector3Ex.TransformNormal(frustum.Planes[0].Normal, testMatrix), frustum.Planes[0].DistanceFromOrigin);
                    Assert.IsTrue(movedRightFrustum.Planes[0].Equals(control, .001, .01));
                    Assert.IsTrue(movedRightFrustum.Planes[1].Equals(new Plane(Vector3Ex.TransformNormal(frustum.Planes[1].Normal, testMatrix), frustum.Planes[1].DistanceFromOrigin)));
                    Assert.IsTrue(movedRightFrustum.Planes[2].Equals(frustum.Planes[2]));
                    Assert.IsTrue(movedRightFrustum.Planes[3].Equals(frustum.Planes[3]));
                    Assert.IsTrue(movedRightFrustum.Planes[4].Equals(new Plane(Vector3Ex.TransformNormal(frustum.Planes[4].Normal, testMatrix), frustum.Planes[4].DistanceFromOrigin)));
                    Assert.IsTrue(movedRightFrustum.Planes[5].Equals(new Plane(Vector3Ex.TransformNormal(frustum.Planes[5].Normal, testMatrix), frustum.Planes[5].DistanceFromOrigin)));
                }
            }

            // rotate about y 180 degrees
            {
                Matrix4X4 perspectiveMatrix  = Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.Tau / 4, 1, 3, 507);
                Frustum   perspectiveFrustum = Frustum.FrustumFromProjectionMatrix(perspectiveMatrix);

                Vector3Tests.TestFrustumClipLine(perspectiveFrustum, new Vector3(-10, 0, -5), new Vector3(0, 0, -5), true, new Vector3(-5, 0, -5), new Vector3(0, 0, -5));
                Vector3Tests.TestFrustumClipLine(perspectiveFrustum, new Vector3(-50, 0, -5), new Vector3(-21, 0, -5), false, null, null);
                Vector3Tests.TestFrustumClipLine(perspectiveFrustum, new Vector3(-50, 0, -20), new Vector3(-19, 0, -20), true, new Vector3(-20, 0, -20), new Vector3(-19, 0, -20));

                var frustum = Frustum.Transform(perspectiveFrustum, Matrix4X4.CreateRotationY(MathHelper.Tau / 2));

                // left
                Assert.IsTrue(frustum.Planes[0].Normal.Equals(new Vector3(-1, 0, 1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[0].DistanceFromOrigin, 0, .0001);
                // right
                Assert.IsTrue(frustum.Planes[1].Normal.Equals(new Vector3(1, 0, 1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[1].DistanceFromOrigin, 0, .0001);
                // bottom
                Assert.IsTrue(frustum.Planes[2].Normal.Equals(new Vector3(0, 1, 1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[2].DistanceFromOrigin, 0, .0001);
                // top
                Assert.IsTrue(frustum.Planes[3].Normal.Equals(new Vector3(0, -1, 1).GetNormal(), .0001));
                Assert.AreEqual(frustum.Planes[3].DistanceFromOrigin, 0, .0001);
                // near
                Assert.IsTrue(frustum.Planes[4].Normal.Equals(new Vector3(0, 0, 1), .0001));
                Assert.AreEqual(frustum.Planes[4].DistanceFromOrigin, 3, .0001);
                // far
                Assert.IsTrue(frustum.Planes[5].Normal.Equals(new Vector3(0, 0, -1), .0001));
                Assert.AreEqual(frustum.Planes[5].DistanceFromOrigin, -507, .0001);
            }

            // translate 10 down z
            {
                double    zMove             = 10;
                Matrix4X4 perspectiveMatrix = Matrix4X4.CreatePerspectiveFieldOfView(MathHelper.Tau / 4, 1, 3, 507);
                Frustum   frustum           = Frustum.FrustumFromProjectionMatrix(perspectiveMatrix);
                frustum = Frustum.Transform(frustum, Matrix4X4.CreateTranslation(0, 0, -10));

                double expectedPlaneOffset = Math.Sqrt(2 * (zMove / 2) * (zMove / 2));
                // left
                Assert.IsTrue(frustum.Planes[0].Normal.Equals(new Vector3(1, 0, -1).GetNormal(), .0001));
                Assert.AreEqual(expectedPlaneOffset, frustum.Planes[0].DistanceFromOrigin, .0001);
                // right
                Assert.IsTrue(frustum.Planes[1].Normal.Equals(new Vector3(-1, 0, -1).GetNormal(), .0001));
                Assert.AreEqual(expectedPlaneOffset, frustum.Planes[1].DistanceFromOrigin, .0001);
                // bottom
                Assert.IsTrue(frustum.Planes[2].Normal.Equals(new Vector3(0, 1, -1).GetNormal(), .0001));
                Assert.AreEqual(expectedPlaneOffset, frustum.Planes[2].DistanceFromOrigin, .0001);
                // top
                Assert.IsTrue(frustum.Planes[3].Normal.Equals(new Vector3(0, -1, -1).GetNormal(), .0001));
                Assert.AreEqual(expectedPlaneOffset, frustum.Planes[3].DistanceFromOrigin, .0001);
                // near
                Assert.IsTrue(frustum.Planes[4].Normal.Equals(new Vector3(0, 0, -1), .0001));
                Assert.AreEqual(frustum.Planes[4].DistanceFromOrigin, 3 + zMove, .0001);
                // far
                Assert.IsTrue(frustum.Planes[5].Normal.Equals(new Vector3(0, 0, 1), .0001));
                Assert.AreEqual(frustum.Planes[5].DistanceFromOrigin, -507 - zMove, .0001);
            }
        }