From 79fc848015ef5c206441862d960379632dde83f6 Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Sat, 14 Feb 2015 18:46:03 +0000 Subject: [PATCH] [Math] Vector3 Project and Unproject Add methods to Vector3 to project to and from screen space. --- Source/OpenTK/Math/Vector3.cs | 114 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Source/OpenTK/Math/Vector3.cs b/Source/OpenTK/Math/Vector3.cs index 8a09665..79cabb4 100644 --- a/Source/OpenTK/Math/Vector3.cs +++ b/Source/OpenTK/Math/Vector3.cs @@ -1222,6 +1222,120 @@ namespace OpenTK #endregion + #region Project + + /// + /// Projects a vector from object space into screen space. + /// + /// The vector to project. + /// The X coordinate of the viewport. + /// The Y coordinate of the viewport. + /// The width of the viewport. + /// The height of the viewport. + /// The minimum depth of the viewport. + /// The maximum depth of the viewport. + /// The world-view-projection matrix. + /// The vector in screen space. + /// + /// To project to normalized device coordinates (NDC) use the following parameters: + /// Project(vector, -1, -1, 2, 2, -1, 1, worldViewProjection). + /// + 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 + + /// + /// Projects a vector from screen space into object space. + /// + /// The vector to project. + /// The X coordinate of the viewport. + /// The Y coordinate of the viewport. + /// The width of the viewport. + /// The height of the viewport. + /// The minimum depth of the viewport. + /// The maximum depth of the viewport. + /// The inverse of the world-view-projection matrix. + /// The vector in object space. + /// + /// To project from normalized device coordinates (NDC) use the following parameters: + /// Project(vector, -1, -1, 2, 2, -1, 1, inverseWorldViewProjection). + /// + 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 -- 2.7.4