From 11114ca4eaedf608620ce3de138584baa3a7fd88 Mon Sep 17 00:00:00 2001 From: Tom Edwards Date: Mon, 18 Feb 2013 18:46:26 +0000 Subject: [PATCH] Extra maths features - Added TranslationPart, ScalePart and RotationPart properties to Matrix4 - Added Normalized() to Vector2/3/4, Quaternion and Matrix --- .gitignore | 1 + Source/OpenTK/Math/Matrix4.cs | 87 ++++++++++++++++++++++++++++++++ Source/OpenTK/Math/Quaternion.cs | 11 ++++ Source/OpenTK/Math/Vector2.cs | 10 ++++ Source/OpenTK/Math/Vector2d.cs | 11 ++++ Source/OpenTK/Math/Vector3.cs | 10 ++++ Source/OpenTK/Math/Vector3d.cs | 11 ++++ Source/OpenTK/Math/Vector4.cs | 10 ++++ Source/OpenTK/Math/Vector4d.cs | 10 ++++ 9 files changed, 161 insertions(+) diff --git a/.gitignore b/.gitignore index 0dcea4d8..73da0d91 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ Binaries/ OpenTK.userprefs Source/GlobalAssemblyInfo.cs Version.txt +Source/OpenTK/OpenTK.xml # OpenTK Resource files that seem like they should be ignored: Source/Compatibility/Properties/Resources.resources diff --git a/Source/OpenTK/Math/Matrix4.cs b/Source/OpenTK/Math/Matrix4.cs index 8bd12347..0e221fe4 100644 --- a/Source/OpenTK/Math/Matrix4.cs +++ b/Source/OpenTK/Math/Matrix4.cs @@ -259,6 +259,93 @@ namespace OpenTK /// Gets or sets the value at row 4, column 4 of this instance. /// public float M44 { get { return Row3.W; } set { Row3.W = value; } } + + /// + /// Returns a copy of this instance with scale transform removed. + /// + public Matrix4 Normalized() + { + Matrix4 m = this; + m.Normalize(); + return m; + } + + /// + /// Removes scale transform from this instance. + /// + public void Normalize() + { + Row0.Xyz = Row0.Xyz.Normalized(); + Row1.Xyz = Row1.Xyz.Normalized(); + Row2.Xyz = Row2.Xyz.Normalized(); + } + + /// + /// Gets the translation component of this instance. + /// + public Vector3 TranslationPart { get { return Row3.Xyz; } } + + /// + /// Gets the scale component of this instance. + /// + public Vector3 ScalePart { get { return new Vector3 (Row0.Length, Row1.Length, Row2.Length); } } + + /// + /// Gets the rotation component of this instance. The Matrix MUST be normalized first. + /// + public Quaternion RotationPart + { + get + { + Quaternion q = new Quaternion(); + + // Adapted from Blender + double trace = 0.25 * (Row0[0] + Row1[1] + Row2[2] + 1.0); + + if (trace > 0.0f) + { + double sq = Math.Sqrt(trace); + + q.W = (float)sq; + sq = 1.0 / (4.0 * sq); + q.X = (float)((Row1[2] - Row2[1]) * sq); + q.Y = (float)((Row2[0] - Row0[2]) * sq); + q.Z = (float)((Row0[1] - Row1[0]) * sq); + } + else if (Row0[0] > Row1[1] && Row0[0] > Row2[2]) + { + double sq = 2.0 * Math.Sqrt(1.0 + Row0[0] - Row1[1] - Row2[2]); + + q.X = (float)(0.25 * sq); + sq = 1.0 / sq; + q.W = (float)((Row2[1] - Row1[2]) * sq); + q.Y = (float)((Row1[0] + Row0[1]) * sq); + q.Z = (float)((Row2[0] + Row0[2]) * sq); + } + else if (Row1[1] > Row2[2]) + { + double sq = 2.0 * Math.Sqrt(1.0 + Row1[1] - Row0[0] - Row2[2]); + + q.Y = (float)(0.25 * sq); + sq = 1.0 / sq; + q.W = (float)((Row2[0] - Row0[2]) * sq); + q.X = (float)((Row1[0] + Row0[1]) * sq); + q.Z = (float)((Row2[1] + Row1[2]) * sq); + } + else + { + double sq = 2.0 * Math.Sqrt(1.0 + Row2[2] - Row0[0] - Row1[1]); + + q.Z = (float)(0.25 * sq); + sq = 1.0 / sq; + q.W = (float)((Row1[0] - Row0[1]) * sq); + q.X = (float)((Row2[0] + Row0[2]) * sq); + q.Y = (float)((Row2[1] + Row1[2]) * sq); + } + + return q.Normalized(); + } + } #endregion diff --git a/Source/OpenTK/Math/Quaternion.cs b/Source/OpenTK/Math/Quaternion.cs index 8ee0fc01..33050e6f 100644 --- a/Source/OpenTK/Math/Quaternion.cs +++ b/Source/OpenTK/Math/Quaternion.cs @@ -189,6 +189,17 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Quaternion scaled to unit length. + /// + /// + public Quaternion Normalized() + { + Quaternion q = this; + q.Normalize(); + return q; + } + #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector2.cs b/Source/OpenTK/Math/Vector2.cs index a5c0afd9..8714e354 100644 --- a/Source/OpenTK/Math/Vector2.cs +++ b/Source/OpenTK/Math/Vector2.cs @@ -289,6 +289,16 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector2 scaled to unit length. + /// + /// + public Vector2 Normalized() + { + Vector2 v = this; + v.Normalize(); + return v; + } #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector2d.cs b/Source/OpenTK/Math/Vector2d.cs index 82c89722..c6f50ab7 100644 --- a/Source/OpenTK/Math/Vector2d.cs +++ b/Source/OpenTK/Math/Vector2d.cs @@ -249,6 +249,17 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector2d scaled to unit length. + /// + /// + public Vector2d Normalized() + { + Vector2d v = this; + v.Normalize(); + return v; + } + #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector3.cs b/Source/OpenTK/Math/Vector3.cs index 9953d8d9..4fe1a7bc 100644 --- a/Source/OpenTK/Math/Vector3.cs +++ b/Source/OpenTK/Math/Vector3.cs @@ -277,6 +277,16 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector3 scaled to unit length. + /// + public Vector3 Normalized() + { + Vector3 v = this; + v.Normalize(); + return v; + } + #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector3d.cs b/Source/OpenTK/Math/Vector3d.cs index e00a04b6..3b67ce44 100644 --- a/Source/OpenTK/Math/Vector3d.cs +++ b/Source/OpenTK/Math/Vector3d.cs @@ -275,6 +275,17 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector3d scaled to unit length. + /// + /// + public Vector3d Normalized() + { + Vector3d v = this; + v.Normalize(); + return v; + } + #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector4.cs b/Source/OpenTK/Math/Vector4.cs index 40b23bfb..198066f9 100644 --- a/Source/OpenTK/Math/Vector4.cs +++ b/Source/OpenTK/Math/Vector4.cs @@ -343,6 +343,16 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector4 scaled to unit length. + /// + public Vector4 Normalized() + { + Vector4 v = this; + v.Normalize(); + return v; + } + #region public void Normalize() /// diff --git a/Source/OpenTK/Math/Vector4d.cs b/Source/OpenTK/Math/Vector4d.cs index 0480460f..9370354c 100644 --- a/Source/OpenTK/Math/Vector4d.cs +++ b/Source/OpenTK/Math/Vector4d.cs @@ -340,6 +340,16 @@ namespace OpenTK #endregion + /// + /// Returns a copy of the Vector4d scaled to unid length. + /// + public Vector4d Normalized() + { + Vector4d v = this; + v.Normalize(); + return v; + } + #region public void Normalize() ///