예제 #1
0
        public void TestCtor()
        {
            // Define variables and constants
            const ViewportAnchoring TEST_ANCHORING = ViewportAnchoring.BottomRight;
            Vector2     testAnchorOffset           = new Vector2(0.3f, 0.4f);
            Vector2     testSize        = new Vector2(0.6f, 0.5f);
            const float TEST_NEAR_PLANE = 0.1f;
            const float TEST_FAR_PLANE  = 1000f;

            Window testWindow = new Window("VP Test Window");

            testWindow.ClearViewports();
            SceneViewport testViewport = testWindow.AddViewport(TEST_ANCHORING, testAnchorOffset, testSize, TEST_NEAR_PLANE, TEST_FAR_PLANE);

            // Set up context


            // Execute


            // Assert outcome
            Assert.AreEqual(TEST_ANCHORING, testViewport.Anchoring);
            Assert.AreEqual(testAnchorOffset, testViewport.AnchorOffset);
            Assert.AreEqual(testSize, testViewport.Size);
            Assert.AreEqual(TEST_NEAR_PLANE, testViewport.NearPlaneDist);
            Assert.AreEqual(TEST_FAR_PLANE, testViewport.FarPlaneDist);

            testWindow.Close();
        }
예제 #2
0
        public unsafe Vector2 WorldToScreenNormalized(SceneViewport sv, Vector3 worldCoordinates)
        {
            var nonNormalized = WorldToScreen(sv, worldCoordinates);

            return(new Vector2(
                       nonNormalized.X / sv.SizePixels.X,
                       nonNormalized.Y / sv.SizePixels.Y
                       ));
        }
예제 #3
0
 /// <summary>
 /// Adds a new <see cref="SceneViewport"/> to this window.
 /// </summary>
 /// <remarks>
 /// All newly-created Windows have a default viewport that occupies their entirety added when they are created.
 /// Therefore, there is no need to add a viewport unless you wish to override this default configuration.
 /// </remarks>
 /// <param name="anchoring">The side or corner of this viewport that retains its relative position when this window is resized.
 /// See also: <see cref="SceneViewport.Anchoring"/>.</param>
 /// <param name="anchorOffset">The offset from the anchored corner or side of the window that this viewport resides at.
 /// Both the <see cref="Vector2.X"/> and <see cref="Vector2.Y"/> values must be in the range <c>0f</c> to <c>1f</c>, where
 /// <c>0f</c> indicates an offset of 0%, and <c>1f</c> indicates an offset of <c>100%</c>.
 /// See also: <see cref="SceneViewport.AnchorOffset"/>.</param>
 /// <param name="size">The size of this viewport, specified as a ratio of the window's resolution.
 /// Both the <see cref="Vector2.X"/> and <see cref="Vector2.Y"/> values must be in the range <c>0f</c> to <c>1f</c>, where
 /// <c>0f</c> indicates a size of 0%, and <c>1f</c> indicates a size of <c>100%</c>.
 /// The combination of size and <paramref name="anchorOffset"/> in either dimension must not exceed 100% (<c>1f</c>).
 /// See also: <see cref="SceneViewport.Size"/>.</param>
 /// <param name="nearPlaneDist">The minimum distance between any object and the <see cref="Camera"/>
 /// rendering to this viewport permissible for an object to be drawn.</param>
 /// <param name="farPlaneDist">The maximum distance between any object and the <see cref="Camera"/>
 /// rendering to this viewport permissible for an object to be drawn.</param>
 /// <returns>The newly created viewport that has been added to this window.</returns>
 public SceneViewport AddViewport(ViewportAnchoring anchoring, Vector2 anchorOffset, Vector2 size,
                                  float nearPlaneDist = 0.1f, float farPlaneDist = 1000f)
 {
     lock (WindowMutationLock) {
         SceneViewport result = new SceneViewport(this, anchoring, anchorOffset, size, nearPlaneDist, farPlaneDist);
         addedViewports.Add(result);
         return(result);
     }
 }
예제 #4
0
        public unsafe Vector2 WorldToScreenNormalizedClipped(SceneViewport sv, Vector3 worldCoordinates)
        {
            var normalized = WorldToScreenNormalized(sv, worldCoordinates);

            return(new Vector2(
                       (float)MathUtils.Clamp(normalized.X, 0f, 1f),
                       (float)MathUtils.Clamp(normalized.Y, 0f, 1f)
                       ));
        }
예제 #5
0
        internal FontString(Font font, SceneLayer sceneLayer, SceneViewport viewport, ViewportAnchoring anchoring, Vector2 anchorOffset, Vector2 scale)
        {
            this.sceneLayer         = sceneLayer;
            this.viewport           = viewport;
            this.anchoring          = anchoring;
            this.anchorOffset       = anchorOffset;
            this.scale              = scale;
            this.font               = font;
            this.createMaterialFunc = CreateNewMaterial;

            viewport.TargetWindow.WindowResized += ResizeText;
        }
예제 #6
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)
                       ));
        }
예제 #7
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));
        }
예제 #8
0
        public FontString AddString(SceneLayer sceneLayer, SceneViewport viewport,
                                    ViewportAnchoring anchoring, Vector2 anchorOffset, Vector2 scale)
        {
            lock (instanceMutationLock) {
                Assure.NotNull(sceneLayer);
                Assure.False(sceneLayer.IsDisposed);
                Assure.NotNull(viewport);
                Assure.False(viewport.IsDisposed);
                if (isDisposed)
                {
                    throw new ObjectDisposedException(Name);
                }

                return(new FontString(this, sceneLayer, viewport, anchoring, anchorOffset, scale));
            }
        }
예제 #9
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();
        }
예제 #10
0
        public HUDTexture(FragmentShader fragmentShader, SceneLayer targetLayer, SceneViewport targetViewport)
        {
            lock (staticMutationLock) {
                if (hudTextureModel == null)
                {
                    throw new InvalidOperationException("HUD Texture Model must be set before creating any HUDTexture objects.");
                }
            }
            this.targetViewport            = targetViewport;
            this.material                  = new Material("HUDTexture Mat", fragmentShader);
            this.curModelInstance          = targetLayer.CreateModelInstance(hudTextureModel.Value, material, Transform.DEFAULT_TRANSFORM);
            this.fsTexColorMultiplyBinding = (ConstantBufferBinding)fragmentShader.GetBindingByIdentifier(HUDFS_TEX_PROPS_CBB_NAME);
            this.fsTexBinding              = (ResourceViewBinding)fragmentShader.GetBindingByIdentifier(HUDFS_TEX_BINDING_NAME);
            material.SetMaterialConstantValue(fsTexColorMultiplyBinding, color);
            targetViewport.TargetWindow.WindowResized += WindowResize;

            this.fragmentShader = fragmentShader;
            this.sceneLayer     = targetLayer;
        }
예제 #11
0
        public CameraFrustum GetFrustum(SceneViewport viewport)
        {
            lock (InstanceMutationLock) {
                float aspectRatio    = viewport.AspectRatio;
                float verticalFOV    = FovIsHorizontal ? DeriveVerticalFOV(FovRadians, aspectRatio) : FovRadians;
                float tanHalfFOV     = (float)Math.Tan(verticalFOV * 0.5f);
                float nearHeightHalf = tanHalfFOV * viewport.NearPlaneDist;
                float nearWidthHalf  = nearHeightHalf * aspectRatio;

                Vector3 camPos     = Position;
                Vector3 forwardVec = Orientation;
                Vector3 upVec      = UpDirection;
                Vector3 rightVec   = upVec * forwardVec;

                Vector3 nearCentre = camPos + forwardVec.WithLength(viewport.NearPlaneDist);
                Vector3 farCentre  = camPos + forwardVec.WithLength(viewport.FarPlaneDist);

                Vector3 rightPoint   = nearCentre + rightVec.WithLength(nearWidthHalf);
                Vector3 rightNormal  = (rightPoint - camPos).ToUnit() * upVec;
                Vector3 leftPoint    = nearCentre - rightVec.WithLength(nearWidthHalf);
                Vector3 leftNormal   = upVec * (leftPoint - camPos).ToUnit();
                Vector3 topPoint     = nearCentre + upVec.WithLength(nearWidthHalf);
                Vector3 topNormal    = rightVec * (topPoint - camPos).ToUnit();
                Vector3 bottomPoint  = nearCentre - upVec.WithLength(nearWidthHalf);
                Vector3 bottomNormal = (bottomPoint - camPos).ToUnit() * rightVec;

                return(new CameraFrustum(
                           nearPlane: new Plane(forwardVec, nearCentre),
                           farPlane: new Plane(-forwardVec, farCentre),
                           leftPlane: new Plane(leftNormal, leftPoint),
                           rightPlane: new Plane(rightNormal, rightPoint),
                           topPlane: new Plane(topNormal, topPoint),
                           bottomPlane: new Plane(bottomNormal, bottomPoint)
                           ));
            }
        }
예제 #12
0
 private unsafe D3D11_VIEWPORT GetViewportStruct(SceneViewport vp)
 {
     return(*((D3D11_VIEWPORT *)UnsafeUtils.Reinterpret <ViewportHandle, IntPtr>(vp.ViewportHandle, UnsafeUtils.SizeOf <ViewportHandle>())));
 }
 public static RenderCommand SetViewport(SceneViewport vp)
 {
     Assure.NotNull(vp);
     Assure.False(vp.IsDisposed, "Viewport was disposed.");
     return(new RenderCommand(RenderCommandInstruction.SetViewport, (IntPtr)vp.ViewportHandle));
 }
예제 #14
0
 internal void GetLightPassParameters(out Texture2D <TexelFormat.RGBA32Float>[] gBuffer, out Camera input, out SceneViewport output)
 {
     gBuffer = this.gBuffer;
     input   = this.input;
     output  = this.output;
 }