Пример #1
0
        public unsafe void TestGetRecalculatedProjMatrix()
        {
            Window        testWindow = new Window("TestWindow", 800U, 600U);
            SceneViewport vp         = testWindow.AddViewport(ViewportAnchoring.BottomLeft, Vector2.ZERO, Vector2.ONE, 0.1f, 1000f);
            SceneViewport vp2        = testWindow.AddViewport(ViewportAnchoring.BottomLeft, Vector2.ZERO, Vector2.ONE, 10f, 500f);
            Camera        c          = new Camera();

            c.Position = Vector3.ZERO;
            c.LookAt(Vector3.FORWARD, Vector3.UP);
            c.SetHorizontalFOV(MathUtils.PI_OVER_TWO);

            Assert.AreEqual(
                new Matrix(1f, 0f, 0f, 0f, 0f, 1.333f, 0f, 0f, 0f, 0f, 1f, 1f, 0f, 0f, -0.1f, 0f),
                *((Matrix *)vp.GetRecalculatedProjectionMatrix(c))
                );

            Assert.AreEqual(
                new Matrix(1f, 0f, 0f, 0f, 0f, 1.333f, 0f, 0f, 0f, 0f, 1.02f, 1f, 0f, 0f, -10.204f, 0f),
                *((Matrix *)vp2.GetRecalculatedProjectionMatrix(c))
                );

            c.SetHorizontalFOV(MathUtils.DegToRad(70f));

            Assert.AreEqual(
                new Matrix(1.428f, 0f, 0f, 0f, 0f, 1.904f, 0f, 0f, 0f, 0f, 1f, 1f, 0f, 0f, -0.1f, 0f),
                *((Matrix *)vp.GetRecalculatedProjectionMatrix(c))
                );

            testWindow.SetResolution(1024U, 768U);

            Assert.AreEqual(
                new Matrix(1.428f, 0f, 0f, 0f, 0f, 1.904f, 0f, 0f, 0f, 0f, 1f, 1f, 0f, 0f, -0.1f, 0f),
                *((Matrix *)vp.GetRecalculatedProjectionMatrix(c))
                );

            testWindow.SetResolution(1000U, 1000U);

            Assert.AreEqual(
                new Matrix(1.428f, 0f, 0f, 0f, 0f, 1.428f, 0f, 0f, 0f, 0f, 1f, 1f, 0f, 0f, -0.1f, 0f),
                *((Matrix *)vp.GetRecalculatedProjectionMatrix(c))
                );

            c.Dispose();
            vp2.Dispose();
            vp.Dispose();
            testWindow.Close();
        }
Пример #2
0
        public unsafe Vector2 WorldToScreen(SceneViewport sv, Vector3 worldCoordinates)
        {
            Vector2 viewportSizePixels = sv.SizePixels;
            Matrix  vpMat = *((Matrix *)GetRecalculatedViewMatrix()) * *((Matrix *)sv.GetRecalculatedProjectionMatrix(this));

            var clipSpaceCoordinates = worldCoordinates * vpMat;

            float halfWidth  = 0.5f * viewportSizePixels.X;
            float halfHeight = 0.5f * viewportSizePixels.Y;

            return(new Vector2(
                       (clipSpaceCoordinates.X / clipSpaceCoordinates.Z) * halfWidth + halfWidth,
                       viewportSizePixels.Y - ((clipSpaceCoordinates.Y / clipSpaceCoordinates.Z) * halfHeight + halfHeight)
                       ));
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="pixel">Relative to viewport centre</param>
        /// <returns></returns>
        public unsafe Ray PixelRayCast(SceneViewport sv, Vector2 pixel)
        {
            Vector2 viewportSizePixels = sv.SizePixels;
            Matrix  invProjMat         = ((Matrix *)sv.GetRecalculatedProjectionMatrix(this))->Inverse;
            Matrix  invViewMat         = ((Matrix *)GetRecalculatedViewMatrix())->Inverse;
            Vector4 viewSpaceDir       = invProjMat * new Vector4(
                ((2f * pixel.X) / viewportSizePixels.X), // These two lines are converting the pixel in to NDC ([-1:1, -1:1, -1:1, -1:1])
                ((2f * pixel.Y) / -viewportSizePixels.Y),
                1f,                                      // These two lines are for homogenous clip space. Z=1f is forwards, out of the screen
                1f                                       // Perspective divide = W
                );
            Vector3 worldSpaceDir = (Vector3)(invViewMat * new Vector4(viewSpaceDir, z: 1f, w: 0f)).ToUnit();

            return(new Ray(Position, worldSpaceDir));
        }