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()
///