mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-23 12:55:36 +00:00
Merge pull request #220 from Frassle/project
[Math] Vector3 Project and Unproject
This commit is contained in:
commit
788b039e32
|
@ -1224,6 +1224,120 @@ namespace OpenTK
|
|||
|
||||
#endregion
|
||||
|
||||
#region Project
|
||||
|
||||
/// <summary>
|
||||
/// Projects a vector from object space into screen space.
|
||||
/// </summary>
|
||||
/// <param name="vector">The vector to project.</param>
|
||||
/// <param name="x">The X coordinate of the viewport.</param>
|
||||
/// <param name="y">The Y coordinate of the viewport.</param>
|
||||
/// <param name="width">The width of the viewport.</param>
|
||||
/// <param name="height">The height of the viewport.</param>
|
||||
/// <param name="minZ">The minimum depth of the viewport.</param>
|
||||
/// <param name="maxZ">The maximum depth of the viewport.</param>
|
||||
/// <param name="worldViewProjection">The world-view-projection matrix.</param>
|
||||
/// <returns>The vector in screen space.</returns>
|
||||
/// <remarks>
|
||||
/// To project to normalized device coordinates (NDC) use the following parameters:
|
||||
/// Project(vector, -1, -1, 2, 2, -1, 1, worldViewProjection).
|
||||
/// </remarks>
|
||||
public static Vector3 Project(Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, Matrix4 worldViewProjection)
|
||||
{
|
||||
Vector4 result;
|
||||
|
||||
result.X =
|
||||
vector.X * worldViewProjection.M11 +
|
||||
vector.Y * worldViewProjection.M21 +
|
||||
vector.Z * worldViewProjection.M31 +
|
||||
worldViewProjection.M41;
|
||||
|
||||
result.Y =
|
||||
vector.X * worldViewProjection.M12 +
|
||||
vector.Y * worldViewProjection.M22 +
|
||||
vector.Z * worldViewProjection.M32 +
|
||||
worldViewProjection.M42;
|
||||
|
||||
result.Z =
|
||||
vector.X * worldViewProjection.M13 +
|
||||
vector.Y * worldViewProjection.M23 +
|
||||
vector.Z * worldViewProjection.M33 +
|
||||
worldViewProjection.M43;
|
||||
|
||||
result.W =
|
||||
vector.X * worldViewProjection.M14 +
|
||||
vector.Y * worldViewProjection.M24 +
|
||||
vector.Z * worldViewProjection.M34 +
|
||||
worldViewProjection.M44;
|
||||
|
||||
result /= result.W;
|
||||
|
||||
result.X = x + (width * ((result.X + 1.0f) / 2.0f));
|
||||
result.Y = y + (height * ((result.Y + 1.0f) / 2.0f));
|
||||
result.Z = minZ + ((maxZ - minZ) * ((result.Z + 1.0f) / 2.0f));
|
||||
|
||||
return new Vector3(result.X, result.Y, result.Z);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unproject
|
||||
|
||||
/// <summary>
|
||||
/// Projects a vector from screen space into object space.
|
||||
/// </summary>
|
||||
/// <param name="vector">The vector to project.</param>
|
||||
/// <param name="x">The X coordinate of the viewport.</param>
|
||||
/// <param name="y">The Y coordinate of the viewport.</param>
|
||||
/// <param name="width">The width of the viewport.</param>
|
||||
/// <param name="height">The height of the viewport.</param>
|
||||
/// <param name="minZ">The minimum depth of the viewport.</param>
|
||||
/// <param name="maxZ">The maximum depth of the viewport.</param>
|
||||
/// <param name="worldViewProjection">The inverse of the world-view-projection matrix.</param>
|
||||
/// <returns>The vector in object space.</returns>
|
||||
/// <remarks>
|
||||
/// To project from normalized device coordinates (NDC) use the following parameters:
|
||||
/// Project(vector, -1, -1, 2, 2, -1, 1, inverseWorldViewProjection).
|
||||
/// </remarks>
|
||||
public static Vector3 Unproject(Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, Matrix4 inverseWorldViewProjection)
|
||||
{
|
||||
Vector4 result;
|
||||
|
||||
result.X = ((((vector.X - x) / width) * 2.0f) - 1.0f);
|
||||
result.Y = ((((vector.Y - y) / height) * 2.0f) - 1.0f);
|
||||
result.Z = (((vector.Z / (maxZ - minZ)) * 2.0f) - 1.0f);
|
||||
|
||||
result.X =
|
||||
result.X * inverseWorldViewProjection.M11 +
|
||||
result.Y * inverseWorldViewProjection.M21 +
|
||||
result.Z * inverseWorldViewProjection.M31 +
|
||||
inverseWorldViewProjection.M41;
|
||||
|
||||
result.Y =
|
||||
result.X * inverseWorldViewProjection.M12 +
|
||||
result.Y * inverseWorldViewProjection.M22 +
|
||||
result.Z * inverseWorldViewProjection.M32 +
|
||||
inverseWorldViewProjection.M42;
|
||||
|
||||
result.Z =
|
||||
result.X * inverseWorldViewProjection.M13 +
|
||||
result.Y * inverseWorldViewProjection.M23 +
|
||||
result.Z * inverseWorldViewProjection.M33 +
|
||||
inverseWorldViewProjection.M43;
|
||||
|
||||
result.W =
|
||||
result.X * inverseWorldViewProjection.M14 +
|
||||
result.Y * inverseWorldViewProjection.M24 +
|
||||
result.Z * inverseWorldViewProjection.M34 +
|
||||
inverseWorldViewProjection.M44;
|
||||
|
||||
result /= result.W;
|
||||
|
||||
return new Vector3(result.X, result.Y, result.Z);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Swizzle
|
||||
|
|
Loading…
Reference in a new issue