#region License /* FNA - XNA4 Reimplementation for Desktop Platforms * Copyright 2009-2016 Ethan Lee and the MonoGame Team * * Released under the Microsoft Public License. * See LICENSE for details. */ #endregion #region Using Statements using System; #endregion namespace Microsoft.Xna.Framework.Graphics { /// /// Describes the view bounds for render-target surface. /// [Serializable] public struct Viewport { #region Public Properties /// /// The height of the bounds in pixels. /// public int Height { get { return height; } set { height = value; } } /// /// The upper limit of depth of this viewport. /// public float MaxDepth { get { return maxDepth; } set { maxDepth = value; } } /// /// The lower limit of depth of this viewport. /// public float MinDepth { get { return minDepth; } set { minDepth = value; } } /// /// The width of the bounds in pixels. /// public int Width { get { return width; } set { width = value; } } /// /// The y coordinate of the beginning of this viewport. /// public int Y { get { return y; } set { y = value; } } /// /// The x coordinate of the beginning of this viewport. /// public int X { get { return x; } set { x = value; } } /// /// Gets the aspect ratio of this , which is width / height. /// public float AspectRatio { get { if ((height != 0) && (width != 0)) { return (((float) width) / ((float) height)); } return 0.0f; } } /// /// Gets or sets a boundary of this . /// public Rectangle Bounds { get { return new Rectangle( x, y, width, height ); } set { x = value.X; y = value.Y; width = value.Width; height = value.Height; } } /// /// Returns the subset of the viewport that is guaranteed to be visible on a lower quality display. /// public Rectangle TitleSafeArea { get { return Bounds; } } #endregion #region Private Variables private int x; private int y; private int width; private int height; private float minDepth; private float maxDepth; #endregion #region Public Constructors /// /// Constructs a viewport from the given values. The will be 0.0 and will be 1.0. /// /// The x coordinate of the upper-left corner of the view bounds in pixels. /// The y coordinate of the upper-left corner of the view bounds in pixels. /// The width of the view bounds in pixels. /// The height of the view bounds in pixels. public Viewport(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; minDepth = 0.0f; maxDepth = 1.0f; } /// /// Constructs a viewport from the given values. /// /// A that defines the location and size of the in a render target. public Viewport(Rectangle bounds) { x = bounds.X; y = bounds.Y; width = bounds.Width; height = bounds.Height; minDepth = 0.0f; maxDepth = 1.0f; } #endregion #region Public Methods /// /// Projects a from world space into screen space. /// /// The to project. /// The projection . /// The view . /// The world . /// public Vector3 Project( Vector3 source, Matrix projection, Matrix view, Matrix world ) { Matrix matrix = Matrix.Multiply( Matrix.Multiply(world, view), projection ); Vector3 vector = Vector3.Transform(source, matrix); float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44; if (!MathHelper.WithinEpsilon(a, 1.0f)) { vector.X = vector.X / a; vector.Y = vector.Y / a; vector.Z = vector.Z / a; } vector.X = (((vector.X + 1f) * 0.5f) * Width) + X; vector.Y = (((-vector.Y + 1f) * 0.5f) * Height) + Y; vector.Z = (vector.Z * (MaxDepth - MinDepth)) + MinDepth; return vector; } /// /// Unprojects a from screen space into world space. /// /// The to unproject. /// The projection . /// The view . /// The world . /// public Vector3 Unproject(Vector3 source, Matrix projection, Matrix view, Matrix world) { Matrix matrix = Matrix.Invert( Matrix.Multiply( Matrix.Multiply(world, view), projection ) ); source.X = (((source.X - X) / ((float) Width)) * 2f) - 1f; source.Y = -((((source.Y - Y) / ((float) Height)) * 2f) - 1f); source.Z = (source.Z - MinDepth) / (MaxDepth - MinDepth); Vector3 vector = Vector3.Transform(source, matrix); float a = ( ((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34) ) + matrix.M44; if (!MathHelper.WithinEpsilon(a, 1.0f)) { vector.X = vector.X / a; vector.Y = vector.Y / a; vector.Z = vector.Z / a; } return vector; } /// /// Returns a representation of this in the format: /// {X:[] Y:[] Width:[] Height:[] MinDepth:[] MaxDepth:[]} /// /// A representation of this . public override string ToString() { return ( "{" + "X:" + x.ToString() + " Y:" + y.ToString() + " Width:" + width.ToString() + " Height:" + height.ToString() + " MinDepth:" + minDepth.ToString() + " MaxDepth:" + maxDepth.ToString() + "}" ); } #endregion } }