Glatzemann fa32fcea55 added some tests
added some developer attributes
completed some more classes
2015-03-15 01:11:47 +01:00

212 lines
4.4 KiB
C#

#region Using Statements
using System;
using ANX.Framework.NonXNA.Development;
#endregion
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license
namespace ANX.Framework.Graphics
{
[PercentageComplete(100)]
[Developer("Glatzemann")]
[TestState(TestStateAttribute.TestState.InProgress)]
public struct Viewport
{
#region Private
private int x;
private int y;
private int width;
private int height;
private float near;
private float far;
#endregion
#region Public
public float AspectRatio
{
get
{
if (this.width != 0 && this.height != 0)
return (float)width / (float)height;
return 0f;
}
}
public Rectangle Bounds
{
get
{
return new Rectangle(x, y, width, height);
}
set
{
this.x = value.X;
this.y = value.Y;
this.width = value.Width;
this.height = value.Height;
}
}
public int Height
{
get
{
return this.height;
}
set
{
this.height = value;
}
}
public float MaxDepth
{
get
{
return this.far;
}
set
{
this.far = value;
}
}
public float MinDepth
{
get
{
return this.near;
}
set
{
this.near = value;
}
}
public Rectangle TitleSafeArea
{
get
{
// On Windows Xna simply returns the rectangle. Check if we need any other implementation on other platforms!
return new Rectangle(x, y, width, height);
}
}
public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
public int X
{
get
{
return this.x;
}
set
{
this.x = value;
}
}
public int Y
{
get
{
return this.y;
}
set
{
this.y = value;
}
}
#endregion
#region Constructor
public Viewport(int x, int y, int width, int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.near = 0f;
this.far = 1f;
}
public Viewport(Rectangle bounds)
{
this.x = bounds.X;
this.y = bounds.Y;
this.width = bounds.Width;
this.height = bounds.Height;
this.near = 0f;
this.far = 1f;
}
#endregion
#region Project
public Vector3 Project(Vector3 source, Matrix projection, Matrix view, Matrix world)
{
Matrix wv;
Matrix wvp;
Matrix.Multiply(ref world, ref view, out wv);
Matrix.Multiply(ref wv, ref projection, out wvp);
Vector3 vector;
Vector3.Transform(ref source, ref wvp, out vector);
float num = source.X * wvp.M14 + source.Y * wvp.M24 + source.Z * wvp.M34 + wvp.M44;
if (WithinEpsilon(num) == false)
vector /= num;
vector.X = (vector.X + 1f) * 0.5f * (float)width + (float)x;
vector.Y = (-vector.Y + 1f) * 0.5f * (float)height + (float)y;
vector.Z = vector.Z * (far - near) + near;
return vector;
}
#endregion
#region Unproject
public Vector3 Unproject(Vector3 source, Matrix projection, Matrix view, Matrix world)
{
Matrix wv;
Matrix wvp;
Matrix.Multiply(ref world, ref view, out wv);
Matrix.Multiply(ref wv, ref projection, out wvp);
wvp = Matrix.Invert(wvp);
source.X = (source.X - (float)x) / (float)width * 2f - 1f;
source.Y = -((source.Y - (float)y) / (float)height * 2f - 1f);
source.Z = (source.Z - near) / (far - near);
Vector3 vector;
Vector3.Transform(ref source, ref wvp, out vector);
float num = source.X * wvp.M14 + source.Y * wvp.M24 + source.Z * wvp.M34 + wvp.M44;
return (WithinEpsilon(num) == false) ? vector /= num : vector;
}
#endregion
#region WithinEpsilon
private static bool WithinEpsilon(float num)
{
num -= 1f;
return -1.401298E-45f <= num && num <= 1.401298E-45f;
}
#endregion
#region ToString
public override string ToString()
{
return String.Format("Viewport X: {0} Y:{1} Width: {2} Height: {3} AspectRatio: {4} MinDepth: {5} MaxDepth: {6}",
X, Y, Width, Height, AspectRatio, MinDepth, MaxDepth);
}
#endregion
}
}