Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Viewport.cs
305 lines | 6.6 KiB | text/x-csharp | CSharpLexer
#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
* Copyright 2009-2020 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
{
/// <summary>
/// Describes the view bounds for render-target surface.
/// </summary>
[Serializable]
public struct Viewport
{
#region Public Properties
/// <summary>
/// The height of the bounds in pixels.
/// </summary>
public int Height
{
get
{
return height;
}
set
{
height = value;
}
}
/// <summary>
/// The upper limit of depth of this viewport.
/// </summary>
public float MaxDepth
{
get
{
return maxDepth;
}
set
{
maxDepth = value;
}
}
/// <summary>
/// The lower limit of depth of this viewport.
/// </summary>
public float MinDepth
{
get
{
return minDepth;
}
set
{
minDepth = value;
}
}
/// <summary>
/// The width of the bounds in pixels.
/// </summary>
public int Width
{
get
{
return width;
}
set
{
width = value;
}
}
/// <summary>
/// The y coordinate of the beginning of this viewport.
/// </summary>
public int Y
{
get
{
return y;
}
set
{
y = value;
}
}
/// <summary>
/// The x coordinate of the beginning of this viewport.
/// </summary>
public int X
{
get
{
return x;
}
set
{
x = value;
}
}
/// <summary>
/// Gets the aspect ratio of this <see cref="Viewport"/>, which is width / height.
/// </summary>
public float AspectRatio
{
get
{
if ((height != 0) && (width != 0))
{
return (((float) width) / ((float) height));
}
return 0.0f;
}
}
/// <summary>
/// Gets or sets a boundary of this <see cref="Viewport"/>.
/// </summary>
public Rectangle Bounds
{
get
{
return new Rectangle(
x,
y,
width,
height
);
}
set
{
x = value.X;
y = value.Y;
width = value.Width;
height = value.Height;
}
}
/// <summary>
/// Returns the subset of the viewport that is guaranteed to be visible on a lower quality display.
/// </summary>
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
/// <summary>
/// Constructs a viewport from the given values. The <see cref="MinDepth"/> will be 0.0 and <see cref="MaxDepth"/> will be 1.0.
/// </summary>
/// <param name="x">The x coordinate of the upper-left corner of the view bounds in pixels.</param>
/// <param name="y">The y coordinate of the upper-left corner of the view bounds in pixels.</param>
/// <param name="width">The width of the view bounds in pixels.</param>
/// <param name="height">The height of the view bounds in pixels.</param>
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;
}
/// <summary>
/// Constructs a viewport from the given values.
/// </summary>
/// <param name="bounds">A <see cref="Rectangle"/> that defines the location and size of the <see cref="Viewport"/> in a render target.</param>
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
/// <summary>
/// Projects a <see cref="Vector3"/> from world space into screen space.
/// </summary>
/// <param name="source">The <see cref="Vector3"/> to project.</param>
/// <param name="projection">The projection <see cref="Matrix"/>.</param>
/// <param name="view">The view <see cref="Matrix"/>.</param>
/// <param name="world">The world <see cref="Matrix"/>.</param>
/// <returns></returns>
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;
}
/// <summary>
/// Unprojects a <see cref="Vector3"/> from screen space into world space.
/// </summary>
/// <param name="source">The <see cref="Vector3"/> to unproject.</param>
/// <param name="projection">The projection <see cref="Matrix"/>.</param>
/// <param name="view">The view <see cref="Matrix"/>.</param>
/// <param name="world">The world <see cref="Matrix"/>.</param>
/// <returns></returns>
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;
}
/// <summary>
/// Returns a <see cref="String"/> representation of this <see cref="Viewport"/> in the format:
/// {X:[<see cref="X"/>] Y:[<see cref="Y"/>] Width:[<see cref="Width"/>] Height:[<see cref="Height"/>] MinDepth:[<see cref="MinDepth"/>] MaxDepth:[<see cref="MaxDepth"/>]}
/// </summary>
/// <returns>A <see cref="String"/> representation of this <see cref="Viewport"/>.</returns>
public override string ToString()
{
return (
"{" +
"X:" + x.ToString() +
" Y:" + y.ToString() +
" Width:" + width.ToString() +
" Height:" + height.ToString() +
" MinDepth:" + minDepth.ToString() +
" MaxDepth:" + maxDepth.ToString() +
"}"
);
}
#endregion
}
}