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