Пример #1
0
        public static void RenderDebugAABB(this WorldView worldView, Graphics2D graphics2D, AxisAlignedBoundingBox bounds)
        {
            Vector3 renderPosition           = bounds.Center;
            Vector2 objectCenterScreenSpace  = worldView.GetScreenPosition(renderPosition);
            Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);

            graphics2D.Circle(objectCenterScreenSpace, 5, Color.Magenta);

            for (int i = 0; i < 4; i++)
            {
                graphics2D.Circle(worldView.GetScreenPosition(bounds.GetTopCorner(i)), 5, Color.Magenta);
                graphics2D.Circle(worldView.GetScreenPosition(bounds.GetBottomCorner(i)), 5, Color.Magenta);
            }

            RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;

            for (int i = 0; i < 4; i++)
            {
                screenBoundsOfObject3D.ExpandToInclude(worldView.GetScreenPosition(bounds.GetTopCorner(i)));
                screenBoundsOfObject3D.ExpandToInclude(worldView.GetScreenPosition(bounds.GetBottomCorner(i)));
            }

            graphics2D.Circle(screenBoundsOfObject3D.Left, screenBoundsOfObject3D.Bottom, 5, Color.Cyan);
            graphics2D.Circle(screenBoundsOfObject3D.Left, screenBoundsOfObject3D.Top, 5, Color.Cyan);
            graphics2D.Circle(screenBoundsOfObject3D.Right, screenBoundsOfObject3D.Bottom, 5, Color.Cyan);
            graphics2D.Circle(screenBoundsOfObject3D.Right, screenBoundsOfObject3D.Top, 5, Color.Cyan);
        }
Пример #2
0
        public void WorldViewOrthographicProjectionTests()
        {
            var world = new WorldView(1, 1);

            Assert.IsTrue(world.EyePosition.Equals(Vector3.UnitZ * 7, 1e-3));
            world.CalculateOrthogrphicMatrixOffCenterWithViewspaceHeight(680, 240, -200, 128, 5, 55);
            Assert.IsTrue(world.GetScreenPosition(new Vector3(0, 0, 0)).Equals(new Vector2((680 - 200) / 2.0, 240 / 2.0), 1e-3));
            Assert.IsTrue(world.GetScreenPosition(new Vector3(128, 64, 0)).Equals(new Vector2(680 - 200, 240), 1e-3));
            Assert.IsTrue(world.GetScreenPosition(new Vector3(-128, -64, 0)).Equals(new Vector2(0, 0), 1e-3));
            Assert.AreEqual(5, world.NearZ, 1e-3);
            Assert.AreEqual(55, world.FarZ, 1e-3);
            Assert.AreEqual(128, world.NearPlaneHeightInViewspace, 1e-3);
            var ray = world.GetRayForLocalBounds(new Vector2((680 - 200) / 2.0, 240));             // top center

            Assert.IsTrue(Vector3.UnitZ.Equals(-ray.directionNormal.GetNormal(), 1e-3));
            Assert.IsTrue(new Vector3(0, 64, 2).Equals(ray.origin, 1e-3));
            Assert.AreEqual(world.NearPlaneHeightInViewspace, world.GetViewspaceHeightAtPosition(new Vector3(1, 1, -10)), 1e-3);
            world.Scale = 3;
            Assert.AreEqual(world.NearPlaneHeightInViewspace / 3, world.GetWorldUnitsPerScreenPixelAtPosition(new Vector3(1, 1, (7 - 10) / 3.0)) * 240, 1e-3);
        }
        public static RectangleDouble GetScreenBounds(AxisAlignedBoundingBox meshBounds, WorldView world)
        {
            RectangleDouble screenBounds = RectangleDouble.ZeroIntersection;

            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.minXYZ.Y, meshBounds.minXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.minXYZ.Y, meshBounds.minXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.maxXYZ.Y, meshBounds.minXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.maxXYZ.Y, meshBounds.minXYZ.Z)));

            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.minXYZ.Y, meshBounds.maxXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.minXYZ.Y, meshBounds.maxXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.maxXYZ.Y, meshBounds.maxXYZ.Z)));
            screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.maxXYZ.Y, meshBounds.maxXYZ.Z)));
            return(screenBounds);
        }
Пример #4
0
        public void WorldViewPerspectiveProjectionTests()
        {
            var world = new WorldView(1, 1);

            Assert.IsTrue(world.EyePosition.Equals(Vector3.UnitZ * 7, 1e-3));
            world.CalculatePerspectiveMatrixOffCenter(567, 123, -200, 5, 55);
            Assert.IsTrue(world.GetScreenPosition(new Vector3(0, 0, 0)).Equals(new Vector2((567 - 200) / 2.0, 123 / 2.0), 1e-3));
            Assert.AreEqual(5, world.NearZ, 1e-3);
            Assert.AreEqual(55, world.FarZ, 1e-3);
            Assert.AreEqual(4.14213562373095, world.NearPlaneHeightInViewspace, 1e-3);
            var ray = world.GetRayForLocalBounds(new Vector2((567 - 200) / 2.0, 123));             // top center

            Assert.AreEqual(WorldView.DefaultPerspectiveVFOVDegrees / 2, MathHelper.RadiansToDegrees(Math.Atan2(ray.directionNormal.Y, -ray.directionNormal.Z)), 1e-3);
            Assert.IsTrue((Vector3.UnitZ * 7).Equals(ray.origin, 1e-3));
            Assert.AreEqual(world.NearPlaneHeightInViewspace * 2, world.GetViewspaceHeightAtPosition(new Vector3(1, 1, -10)), 1e-3);
            world.Scale = 3;
            Assert.AreEqual(world.NearPlaneHeightInViewspace * 2 / 3, world.GetWorldUnitsPerScreenPixelAtPosition(new Vector3(1, 1, (7 - 10) / 3.0)) * 123, 1e-3);
        }
Пример #5
0
        public static void RenderBounds(DrawEventArgs e, WorldView world, Matrix4X4 transformToWorld, IBvhItem bvh, int depth = int.MinValue)
        {
            for (int i = 0; i < 4; i++)
            {
                Vector3 bottomStartPosition  = Vector3Ex.Transform(bvh.GetAxisAlignedBoundingBox().GetBottomCorner(i), transformToWorld);
                var     bottomStartScreenPos = world.GetScreenPosition(bottomStartPosition);

                Vector3 bottomEndPosition  = Vector3Ex.Transform(bvh.GetAxisAlignedBoundingBox().GetBottomCorner((i + 1) % 4), transformToWorld);
                var     bottomEndScreenPos = world.GetScreenPosition(bottomEndPosition);

                Vector3 topStartPosition  = Vector3Ex.Transform(bvh.GetAxisAlignedBoundingBox().GetTopCorner(i), transformToWorld);
                var     topStartScreenPos = world.GetScreenPosition(topStartPosition);

                Vector3 topEndPosition  = Vector3Ex.Transform(bvh.GetAxisAlignedBoundingBox().GetTopCorner((i + 1) % 4), transformToWorld);
                var     topEndScreenPos = world.GetScreenPosition(topEndPosition);

                e.Graphics2D.Line(bottomStartScreenPos, bottomEndScreenPos, Color.Black);
                e.Graphics2D.Line(topStartScreenPos, topEndScreenPos, Color.Black);
                e.Graphics2D.Line(topStartScreenPos, bottomStartScreenPos, Color.Black);
            }

            if (bvh is ITriangle tri)
            {
                for (int i = 0; i < 3; i++)
                {
                    var vertexPos    = tri.GetVertex(i);
                    var screenCenter = Vector3Ex.Transform(vertexPos, transformToWorld);
                    var screenPos    = world.GetScreenPosition(screenCenter);

                    e.Graphics2D.Circle(screenPos, 3, Color.Red);
                }
            }
            else
            {
                var center      = bvh.GetCenter();
                var worldCenter = Vector3Ex.Transform(center, transformToWorld);
                var screenPos2  = world.GetScreenPosition(worldCenter);

                if (depth != int.MinValue)
                {
                    e.Graphics2D.Circle(screenPos2, 3, Color.Yellow);
                    e.Graphics2D.DrawString($"{depth},", screenPos2.X + 12 * depth, screenPos2.Y);
                }
            }
        }
        public static void RenderBounds(DrawEventArgs e, WorldView World, IEnumerable <BvhIterator> allResults)
        {
            foreach (var x in allResults)
            {
                for (int i = 0; i < 4; i++)
                {
                    Vector3 bottomStartPosition  = Vector3.Transform(x.Bvh.GetAxisAlignedBoundingBox().GetBottomCorner(i), x.TransformToWorld);
                    var     bottomStartScreenPos = World.GetScreenPosition(bottomStartPosition);

                    Vector3 bottomEndPosition  = Vector3.Transform(x.Bvh.GetAxisAlignedBoundingBox().GetBottomCorner((i + 1) % 4), x.TransformToWorld);
                    var     bottomEndScreenPos = World.GetScreenPosition(bottomEndPosition);

                    Vector3 topStartPosition  = Vector3.Transform(x.Bvh.GetAxisAlignedBoundingBox().GetTopCorner(i), x.TransformToWorld);
                    var     topStartScreenPos = World.GetScreenPosition(topStartPosition);

                    Vector3 topEndPosition  = Vector3.Transform(x.Bvh.GetAxisAlignedBoundingBox().GetTopCorner((i + 1) % 4), x.TransformToWorld);
                    var     topEndScreenPos = World.GetScreenPosition(topEndPosition);

                    e.Graphics2D.Line(bottomStartScreenPos, bottomEndScreenPos, Color.Black);
                    e.Graphics2D.Line(topStartScreenPos, topEndScreenPos, Color.Black);
                    e.Graphics2D.Line(topStartScreenPos, bottomStartScreenPos, Color.Black);
                }

                TriangleShape tri = x.Bvh as TriangleShape;
                if (tri != null)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        var vertexPos    = tri.GetVertex(i);
                        var screenCenter = Vector3.Transform(vertexPos, x.TransformToWorld);
                        var screenPos    = World.GetScreenPosition(screenCenter);

                        e.Graphics2D.Circle(screenPos, 3, Color.Red);
                    }
                }
                else
                {
                    var center      = x.Bvh.GetCenter();
                    var worldCenter = Vector3.Transform(center, x.TransformToWorld);
                    var screenPos2  = World.GetScreenPosition(worldCenter);
                    e.Graphics2D.Circle(screenPos2, 3, Color.Yellow);
                    e.Graphics2D.DrawString($"{x.Depth},", screenPos2.X + 12 * x.Depth, screenPos2.Y);
                }
            }
        }