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(); }
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) )); }
/// <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)); }