Represents a perspective projection camera.
PerspectiveCamera specifies a projection of a 3-D model to a 2-D visual surface. This projection includes perspective foreshortening. In other words, the PerspectiveCamera describes a frustrum whose sides converge toward a point on the horizon. Objects closer to the camera appear larger, and objects farther from the camera appear smaller.
Inheritance: ProjectionCamera
		public void CanRenderModelWithTextures()
		{
			// Arrange.
			Scene scene = MeshellatorLoader.ImportFromFile("Models/Obj/Tank.obj");
			using (var renderer = new WarpSceneRenderer(scene, 800, 600))
			{
				renderer.Options.TriangleWindingOrderReversed = true;

				Camera camera = new PerspectiveCamera
				{
					FarPlaneDistance = 100000,
					NearPlaneDistance = 1,
					FieldOfView = MathUtility.PI_OVER_4,
					LookDirection = new Vector3D(-1, -0.3f, 1),
					Position = new Point3D(300, 150, -150),
					UpDirection = Vector3D.Up
				};

				// Act.
				var bitmap = renderer.Render(camera);

				// Assert.
				Assert.IsNotNull(bitmap);
				SaveImage(bitmap, "tank.jpg");
			}
		}
		public void CanRenderPrimitive()
		{
			// Arrange.
			Scene scene = MeshellatorLoader.CreateFromTeapot(10, 10);
			using (var renderer = new WarpSceneRenderer(scene, 550, 350))
			{
				renderer.Options.BackgroundColor = Color.FromRgb(200, 200, 200);

				Camera camera = new PerspectiveCamera
				{
					LookDirection = new Vector3D(-1, -0.3f, 1),
					Position = new Point3D(50, 20, -20),
				};

				// Act.
				BitmapSource bitmap = renderer.Render(camera);

				// Assert.
				Assert.IsNotNull(bitmap);
				SaveImage(bitmap, "teapot.jpg");
			}
		}
		public void CanRenderModel()
		{
			// Arrange.
			Scene scene = MeshellatorLoader.ImportFromFile("Models/3ds/85-nissan-fairlady.3ds");
			using (var renderer = new WarpSceneRenderer(scene, 800, 600))
			{
				Camera camera = new PerspectiveCamera
				{
					FarPlaneDistance = 100000,
					NearPlaneDistance = 1,
					FieldOfView = MathUtility.PI_OVER_4,
					LookDirection = new Vector3D(-1, -0.3f, 1),
					Position = new Point3D(3000, 1500, -1500),
					UpDirection = Vector3D.Up
				};

				// Act.
				var bitmap = renderer.Render(camera);

				// Assert.
				Assert.IsNotNull(bitmap);
				SaveImage(bitmap, "nissan.jpg");
			}
		}
示例#4
0
        public static PerspectiveCamera CreateFromBounds(AxisAlignedBox3D bounds, Viewport3D viewport,
                                                         float fieldOfView, float yaw = 0.0f, float pitch = 0.0f, float zoom = 1.0f)
        {
            // Calculate initial guess at camera settings.
            Matrix3D          transform       = Matrix3D.CreateFromYawPitchRoll(yaw, pitch, 0);
            Vector3D          cameraDirection = Vector3D.Normalize(transform.Transform(Vector3D.Forward));
            PerspectiveCamera initialGuess    = new PerspectiveCamera
            {
                FieldOfView       = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance  = bounds.Size.Length() * 10,
                Position          = bounds.Center - cameraDirection * bounds.Size.Length() * 2,
                LookDirection     = cameraDirection,
                UpDirection       = Vector3D.Up
            };

            Matrix3D projection = initialGuess.GetProjectionMatrix(viewport.AspectRatio);
            Matrix3D view       = initialGuess.GetViewMatrix();

            // Project bounding box corners onto screen, and calculate screen bounds.
            float closestZ     = float.MaxValue;
            Box2D?screenBounds = null;

            Point3D[] corners = bounds.GetCorners();
            foreach (Point3D corner in corners)
            {
                Point3D screenPoint = viewport.Project(corner,
                                                       projection, view, Matrix3D.Identity);

                if (screenPoint.Z < closestZ)
                {
                    closestZ = screenPoint.Z;
                }

                IntPoint2D intScreenPoint = new IntPoint2D((int)screenPoint.X, (int)screenPoint.Y);
                if (screenBounds == null)
                {
                    screenBounds = new Box2D(intScreenPoint, intScreenPoint);
                }
                else
                {
                    Box2D value = screenBounds.Value;
                    value.Expand(intScreenPoint);
                    screenBounds = value;
                }
            }

            // Now project back from screen bounds into scene, setting Z to the minimum bounding box Z value.
            IntPoint2D minScreen = screenBounds.Value.Min;
            IntPoint2D maxScreen = screenBounds.Value.Max;
            Point3D    min       = viewport.Unproject(new Point3D(minScreen.X, minScreen.Y, closestZ),
                                                      projection, view, Matrix3D.Identity);
            Point3D max = viewport.Unproject(new Point3D(maxScreen.X, maxScreen.Y, closestZ),
                                             projection, view, Matrix3D.Identity);

            // Use these new values to calculate the distance the camera should be from the AABB centre.
            Vector3D size   = Vector3D.Abs(max - min);
            float    radius = size.Length();
            float    dist   = radius / (2 * MathUtility.Tan(fieldOfView * viewport.AspectRatio / 2));

            Point3D closestBoundsCenter = (min + (max - min) / 2);
            Point3D position            = closestBoundsCenter - cameraDirection * dist * (1 / zoom);

            return(new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = dist * 10,
                Position = position,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            });
        }
示例#5
0
        public static PerspectiveCamera CreateFromBounds(AxisAlignedBox3D bounds, Viewport3D viewport,
			float fieldOfView, float yaw = 0.0f, float pitch = 0.0f, float zoom = 1.0f)
        {
            // Calculate initial guess at camera settings.
            Matrix3D transform = Matrix3D.CreateFromYawPitchRoll(yaw, pitch, 0);
            Vector3D cameraDirection = Vector3D.Normalize(transform.Transform(Vector3D.Forward));
            PerspectiveCamera initialGuess = new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = bounds.Size.Length() * 10,
                Position = bounds.Center - cameraDirection * bounds.Size.Length() * 2,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            };

            Matrix3D projection = initialGuess.GetProjectionMatrix(viewport.AspectRatio);
            Matrix3D view = initialGuess.GetViewMatrix();

            // Project bounding box corners onto screen, and calculate screen bounds.
            float closestZ = float.MaxValue;
            Box2D? screenBounds = null;
            Point3D[] corners = bounds.GetCorners();
            foreach (Point3D corner in corners)
            {
                Point3D screenPoint = viewport.Project(corner,
                    projection, view, Matrix3D.Identity);

                if (screenPoint.Z < closestZ)
                    closestZ = screenPoint.Z;

                IntPoint2D intScreenPoint = new IntPoint2D((int) screenPoint.X, (int) screenPoint.Y);
                if (screenBounds == null)
                    screenBounds = new Box2D(intScreenPoint, intScreenPoint);
                else
                {
                    Box2D value = screenBounds.Value;
                    value.Expand(intScreenPoint);
                    screenBounds = value;
                }
            }

            // Now project back from screen bounds into scene, setting Z to the minimum bounding box Z value.
            IntPoint2D minScreen = screenBounds.Value.Min;
            IntPoint2D maxScreen = screenBounds.Value.Max;
            Point3D min = viewport.Unproject(new Point3D(minScreen.X, minScreen.Y, closestZ),
                projection, view, Matrix3D.Identity);
            Point3D max = viewport.Unproject(new Point3D(maxScreen.X, maxScreen.Y, closestZ),
                projection, view, Matrix3D.Identity);

            // Use these new values to calculate the distance the camera should be from the AABB centre.
            Vector3D size = Vector3D.Abs(max - min);
            float radius = size.Length();
            float dist = radius / (2 * MathUtility.Tan(fieldOfView * viewport.AspectRatio / 2));

            Point3D closestBoundsCenter = (min + (max - min) / 2);
            Point3D position = closestBoundsCenter - cameraDirection * dist * (1 / zoom);

            return new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = dist * 10,
                Position = position,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            };
        }