From 4230c6b4f097518cb87f35dfe6105b82bba5882a Mon Sep 17 00:00:00 2001 From: Andy Korth Date: Thu, 3 Jan 2013 10:41:56 -0600 Subject: [PATCH] Added Robmaister's Matrix3 implementations --- Documentation/Build.Docs.csproj | 31 +- Installers/Nsis/Build.Installer.Nsis.csproj | 31 +- Installers/Zip/Build.Installer.Zip.csproj | 56 +- OpenTK.sln | 76 +- Source/Bind/Generator.Bind.csproj | 16 +- .../Build.UpdateVersion.csproj | 2 +- .../Compatibility/OpenTK.Compatibility.csproj | 23 +- Source/Converter/Generator.Convert.csproj | 16 +- Source/Examples/Main.cs | 2 +- Source/Examples/OpenTK.Examples.csproj | 1 + Source/Examples/OpenTK/Test/MatrixTest.cs | 34 + Source/GLControl/OpenTK.GLControl.csproj | 23 +- Source/OpenTK/Math/Matrix3.cs | 678 +++++++++ Source/OpenTK/Math/Matrix3d.cs | 1356 ++++++++--------- Source/OpenTK/OpenTK.csproj | 27 +- 15 files changed, 1490 insertions(+), 882 deletions(-) create mode 100644 Source/Examples/OpenTK/Test/MatrixTest.cs create mode 100644 Source/OpenTK/Math/Matrix3.cs diff --git a/Documentation/Build.Docs.csproj b/Documentation/Build.Docs.csproj index 647ffe1d..b3f787d7 100644 --- a/Documentation/Build.Docs.csproj +++ b/Documentation/Build.Docs.csproj @@ -22,7 +22,36 @@ $(OutputPath)\html {650C6F3D-33B5-4216-9536-956AB42C0624} v2.0 - + Debug + AnyCPU + 10.0.0 + 2.0 + Exe + Build.Docs + + + none + False + Source + 4 + + + none + False + Source + 4 + + + none + False + Source + 4 + + + none + False + Source + 4 diff --git a/Installers/Nsis/Build.Installer.Nsis.csproj b/Installers/Nsis/Build.Installer.Nsis.csproj index 3a1e802e..89c252f7 100644 --- a/Installers/Nsis/Build.Installer.Nsis.csproj +++ b/Installers/Nsis/Build.Installer.Nsis.csproj @@ -17,7 +17,32 @@ {ADC34399-7613-44D2-90B2-19250F06FE7A} v2.0 - + Debug + AnyCPU + 10.0.0 + 2.0 + Exe + Build.Installer.Nsis + + + none + False + 4 + + + none + False + 4 + + + none + False + 4 + + + none + False + 4 @@ -25,9 +50,9 @@ - + - + diff --git a/Installers/Zip/Build.Installer.Zip.csproj b/Installers/Zip/Build.Installer.Zip.csproj index f2fc4ff6..1b16038b 100644 --- a/Installers/Zip/Build.Installer.Zip.csproj +++ b/Installers/Zip/Build.Installer.Zip.csproj @@ -15,39 +15,53 @@ {ADC34399-7613-44D2-90B2-19250F06FE7B} v2.0 - ..\..\ .\opentk\ + Debug + AnyCPU + 10.0.0 + 2.0 + Exe + Build.Installer.Zip + + + none + False + opentk\ + 4 + + + none + False + opentk\ + 4 + + + none + False + opentk\ + 4 + + + none + False + opentk\ + 4 - - + + - + - + - + diff --git a/OpenTK.sln b/OpenTK.sln index e24d1726..99f52c66 100644 --- a/OpenTK.sln +++ b/OpenTK.sln @@ -1,3 +1,4 @@ + Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "Source\OpenTK\OpenTK.csproj", "{A37A7E14-0000-0000-0000-000000000000}" @@ -66,20 +67,38 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {31D19132-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31D19132-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {31D19132-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {31D19132-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {31D19132-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31D19132-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.Build.0 = Release|Any CPU {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {868E37B3-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -87,6 +106,13 @@ Global {868E37B3-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {A625BE88-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -99,44 +125,16 @@ Global {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Release|Any CPU.ActiveCfg = Release|Any CPU - {31D19132-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {31D19132-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {31D19132-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {31D19132-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {31D19132-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {31D19132-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {31D19132-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.Build.0 = Release|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Source\Examples\OpenTK.Examples.csproj EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/Source/Bind/Generator.Bind.csproj b/Source/Bind/Generator.Bind.csproj index e7c06637..9ed2db03 100644 --- a/Source/Bind/Generator.Bind.csproj +++ b/Source/Bind/Generator.Bind.csproj @@ -25,7 +25,6 @@ 2.0 - publish\ true Disk @@ -49,9 +48,9 @@ DEBUG;TRACE; - true + True 4096 - false + False ..\..\Binaries\OpenTK\Debug\ False False @@ -67,7 +66,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -83,7 +82,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -95,11 +94,11 @@ ..\..\Binaries\OpenTK\Release\ none 4 - true + True TRACE; - true + True ..\..\OpenTK.snk @@ -107,15 +106,12 @@ System - False System.Core - False System.Xml - False diff --git a/Source/Build.UpdateVersion/Build.UpdateVersion.csproj b/Source/Build.UpdateVersion/Build.UpdateVersion.csproj index 34d60ecf..2b1cdde2 100644 --- a/Source/Build.UpdateVersion/Build.UpdateVersion.csproj +++ b/Source/Build.UpdateVersion/Build.UpdateVersion.csproj @@ -51,7 +51,7 @@ 4 - true + True full 4 diff --git a/Source/Compatibility/OpenTK.Compatibility.csproj b/Source/Compatibility/OpenTK.Compatibility.csproj index cd359462..93f83466 100644 --- a/Source/Compatibility/OpenTK.Compatibility.csproj +++ b/Source/Compatibility/OpenTK.Compatibility.csproj @@ -42,16 +42,16 @@ true - true + True 285212672 DEBUG;TRACE; - true + True 4096 - false + False ..\..\Binaries\OpenTK\Debug\ False False @@ -61,7 +61,7 @@ full - true + True 285212672 @@ -69,7 +69,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -83,11 +83,11 @@ none 4 0219, 0414, 0612, 0618, 1591, 3005, 3006 - true + True TRACE; - true + True 285212672 @@ -95,7 +95,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -105,7 +105,7 @@ none - true + True ..\..\OpenTK.snk @@ -113,23 +113,18 @@ System - False System.Data - False System.Drawing - False System.Windows.Forms - False System.Xml - False diff --git a/Source/Converter/Generator.Convert.csproj b/Source/Converter/Generator.Convert.csproj index 158ce6cf..c799e8c7 100644 --- a/Source/Converter/Generator.Convert.csproj +++ b/Source/Converter/Generator.Convert.csproj @@ -47,9 +47,9 @@ DEBUG;TRACE; - true + True 4096 - false + False ..\..\Binaries\OpenTK\Debug\ False False @@ -65,7 +65,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -77,7 +77,7 @@ ..\..\Binaries\OpenTK\Release\ none 4 - true + True TRACE; @@ -88,7 +88,7 @@ 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -97,7 +97,7 @@ none - true + True ..\..\OpenTK.snk @@ -105,19 +105,15 @@ System - False System.Core - False System.Xml - False System.Xml.Linq - False diff --git a/Source/Examples/Main.cs b/Source/Examples/Main.cs index ad30e767..6999104d 100644 --- a/Source/Examples/Main.cs +++ b/Source/Examples/Main.cs @@ -49,7 +49,7 @@ namespace Examples Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - // Examples.Tests.BasicMouseInput.Main (); + Examples.Tests.MatrixTest.Main (); using (Form browser = new ExampleBrowser()) { diff --git a/Source/Examples/OpenTK.Examples.csproj b/Source/Examples/OpenTK.Examples.csproj index 39d041e4..f272a374 100644 --- a/Source/Examples/OpenTK.Examples.csproj +++ b/Source/Examples/OpenTK.Examples.csproj @@ -558,6 +558,7 @@ Code + diff --git a/Source/Examples/OpenTK/Test/MatrixTest.cs b/Source/Examples/OpenTK/Test/MatrixTest.cs new file mode 100644 index 00000000..2b6d9739 --- /dev/null +++ b/Source/Examples/OpenTK/Test/MatrixTest.cs @@ -0,0 +1,34 @@ +// This code was written for the OpenTK library and has been released +// to the Public Domain. +// It is provided "as is" without express or implied warranty of any kind. + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using OpenTK; + +namespace Examples.Tests +{ + [Example("Matrix math test", ExampleCategory.OpenTK, "Test", Visible = false)] + public class MatrixTest + { + public static void Main() + { + float x = 1.0f; + float y = 1.0f; + float z = 1.0f; + + Matrix4 createdTranslation = Matrix4.CreateTranslation(new Vector3(2, 3, -1)); + + Matrix4 translation = new Matrix4(new Vector4(1, 0, 0, 2), new Vector4(0, 1, 0, 3), new Vector4(0, 0, 1, -1), new Vector4(0, 0, 0, 1)); + Vector4 point = new Vector4(x, y, z, 1); + + Vector4 result = Vector4.Transform(point, createdTranslation); + + Trace.WriteLine("Result should be: (3, 4, 0, 1) : " + result); + + } + } +} + diff --git a/Source/GLControl/OpenTK.GLControl.csproj b/Source/GLControl/OpenTK.GLControl.csproj index 1c41c469..50bda87d 100644 --- a/Source/GLControl/OpenTK.GLControl.csproj +++ b/Source/GLControl/OpenTK.GLControl.csproj @@ -42,15 +42,15 @@ true - true + True 285212672 DEBUG;TRACE; OpenTK.GLControl.xml - true + True 4096 - false + False ..\..\Binaries\OpenTK\Debug\ False False @@ -59,14 +59,14 @@ full - true + True 285212672 TRACE; OpenTK.GLControl.xml 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -78,18 +78,18 @@ ..\..\Binaries\OpenTK\Release\ none 4 - true + True TRACE; - true + True 285212672 TRACE; OpenTK.GLControl.xml 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -98,7 +98,7 @@ none - true + True ..\..\OpenTK.snk @@ -106,23 +106,18 @@ System - False System.Data - False System.Drawing - False System.Windows.Forms - False System.Xml - False diff --git a/Source/OpenTK/Math/Matrix3.cs b/Source/OpenTK/Math/Matrix3.cs new file mode 100644 index 00000000..b30ac24f --- /dev/null +++ b/Source/OpenTK/Math/Matrix3.cs @@ -0,0 +1,678 @@ +#region --- License --- +/* +Copyright (c) 2006 - 2008 The Open Toolkit library. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ +#endregion + +using System; +using System.Runtime.InteropServices; + +namespace OpenTK +{ + /// + /// Represents a 3x3 Matrix + /// + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Matrix3 : IEquatable + { + #region Fields + + /// + /// First row of the matrix. + /// + public Vector3 Row0; + + /// + /// Second row of the matrix. + /// + public Vector3 Row1; + + /// + /// Third row of the matrix. + /// + public Vector3 Row2; + + /// + /// The identity matrix. + /// + public static Matrix3 Identity = new Matrix3(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); + +#endregion + + #region Constructors + + /// + /// Constructs a new instance. + /// + /// Top row of the matrix + /// Second row of the matrix + /// Bottom row of the matrix + public Matrix3(Vector3 row0, Vector3 row1, Vector3 row2) + { + Row0 = row0; + Row1 = row1; + Row2 = row2; + } + + /// + /// Constructs a new instance. + /// + /// First item of the first row of the matrix. + /// Second item of the first row of the matrix. + /// Third item of the first row of the matrix. + /// First item of the second row of the matrix. + /// Second item of the second row of the matrix. + /// Third item of the second row of the matrix. + /// First item of the third row of the matrix. + /// Second item of the third row of the matrix. + /// Third item of the third row of the matrix. + public Matrix3( + float m00, float m01, float m02, + float m10, float m11, float m12, + float m20, float m21, float m22) + { + Row0 = new Vector3(m00, m01, m02); + Row1 = new Vector3(m10, m11, m12); + Row2 = new Vector3(m20, m21, m22); + } + +#endregion + + #region Public Members + + #region Properties + + /// + /// Gets the determinant of this matrix. + /// + public float Determinant + { + get + { + float m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, + m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, + m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z; + + return + m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 + - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33; + } + } + + /// + /// Gets the first column of this matrix. + /// + public Vector3 Column0 + { + get { return new Vector3(Row0.X, Row1.X, Row2.X); } + } + + /// + /// Gets the second column of this matrix. + /// + public Vector3 Column1 + { + get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); } + } + + /// + /// Gets the third column of this matrix. + /// + public Vector3 Column2 + { + get { return new Vector3(Row0.Z, Row1.Z, Row2.Z); } + } + + /// + /// Gets or sets the value at row 1, column 1 of this instance. + /// + public float M11 { get { return Row0.X; } set { Row0.X = value; } } + + /// + /// Gets or sets the value at row 1, column 2 of this instance. + /// + public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } + + /// + /// Gets or sets the value at row 1, column 3 of this instance. + /// + public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } + + /// + /// Gets or sets the value at row 2, column 1 of this instance. + /// + public float M21 { get { return Row1.X; } set { Row1.X = value; } } + + /// + /// Gets or sets the value at row 2, column 2 of this instance. + /// + public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } + + /// + /// Gets or sets the value at row 2, column 3 of this instance. + /// + public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } + + /// + /// Gets or sets the value at row 3, column 1 of this instance. + /// + public float M31 { get { return Row2.X; } set { Row2.X = value; } } + + /// + /// Gets or sets the value at row 3, column 2 of this instance. + /// + public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } + + /// + /// Gets or sets the value at row 3, column 3 of this instance. + /// + public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } + +#endregion + + #region Instance + + #region public void Invert() + + public void Invert() + { + this = Matrix3.Invert(this); + } + +#endregion + + #region public void Transpose() + + public void Transpose() + { + this = Matrix3.Transpose(this); + } + +#endregion + +#endregion + + #region Static + + #region CreateFromAxisAngle + + public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3 result) + { + //normalize and create a local copy of the vector. + axis.Normalize(); + float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; + + //calculate angles + float cos = (float)System.Math.Cos(-angle); + float sin = (float)System.Math.Sin(-angle); + float t = 1.0f - cos; + + //do the conversion math once + float tXX = t * axisX * axisX, + tXY = t * axisX * axisY, + tXZ = t * axisX * axisZ, + tYY = t * axisY * axisY, + tYZ = t * axisY * axisZ, + tZZ = t * axisZ * axisZ; + + float sinX = sin * axisX, + sinY = sin * axisY, + sinZ = sin * axisZ; + + result.Row0.X = tXX + cos; + result.Row0.Y = tXY - sinZ; + result.Row0.Z = tXZ + sinY; + result.Row1.X = tXY + sinZ; + result.Row1.Y = tYY + cos; + result.Row1.Z = tYZ - sinX; + result.Row2.X = tXZ - sinY; + result.Row2.Y = tYZ + sinX; + result.Row2.Z = tZZ + cos; + } + + public static Matrix3 CreateFromAxisAngle(Vector3 axis, float angle) + { + Matrix3 result; + CreateFromAxisAngle(axis, angle, out result); + return result; + } + +#endregion + + #region CreateFromQuaternion + + public static void CreateFromQuaternion(ref Quaternion q, out Matrix3 result) + { + Vector3 axis; + float angle; + q.ToAxisAngle(out axis, out angle); + CreateFromAxisAngle(axis, angle, out result); + } + + public static Matrix3 CreateFromQuaternion(Quaternion q) + { + Matrix3 result; + CreateFromQuaternion(ref q, out result); + return result; + } + +#endregion + + #region CreateRotation[XYZ] + + public static void CreateRotationX(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result = Identity; + result.Row1.Y = cos; + result.Row1.Z = sin; + result.Row2.Y = -sin; + result.Row2.Z = cos; + } + + public static Matrix3 CreateRotationX(float angle) + { + Matrix3 result; + CreateRotationX(angle, out result); + return result; + } + + public static void CreateRotationY(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result = Identity; + result.Row0.X = cos; + result.Row0.Z = -sin; + result.Row2.X = sin; + result.Row2.Z = cos; + } + + public static Matrix3 CreateRotationY(float angle) + { + Matrix3 result; + CreateRotationY(angle, out result); + return result; + } + + public static void CreateRotationZ(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result = Identity; + result.Row0.X = cos; + result.Row0.Y = sin; + result.Row1.X = -sin; + result.Row1.Y = cos; + } + + public static Matrix3 CreateRotationZ(float angle) + { + Matrix3 result; + CreateRotationZ(angle, out result); + return result; + } + +#endregion + + #region CreateScale + + /// + /// Creates a scale matrix. + /// + /// Single scale factor for the x, y, and z axes. + /// A scale matrix. + public static Matrix3 CreateScale(float scale) + { + Matrix3 result; + CreateScale(scale, out result); + return result; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factors for the x, y, and z axes. + /// A scale matrix. + public static Matrix3 CreateScale(Vector3 scale) + { + Matrix3 result; + CreateScale(ref scale, out result); + return result; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factor for the x axis. + /// Scale factor for the y axis. + /// Scale factor for the z axis. + /// A scale matrix. + public static Matrix3 CreateScale(float x, float y, float z) + { + Matrix3 result; + CreateScale(x, y, z, out result); + return result; + } + + /// + /// Creates a scale matrix. + /// + /// Single scale factor for the x, y, and z axes. + /// A scale matrix. + public static void CreateScale(float scale, out Matrix3 result) + { + result = Identity; + result.Row0.X = scale; + result.Row1.Y = scale; + result.Row2.Z = scale; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factors for the x, y, and z axes. + /// A scale matrix. + public static void CreateScale(ref Vector3 scale, out Matrix3 result) + { + result = Identity; + result.Row0.X = scale.X; + result.Row1.Y = scale.Y; + result.Row2.Z = scale.Z; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factor for the x axis. + /// Scale factor for the y axis. + /// Scale factor for the z axis. + /// A scale matrix. + public static void CreateScale(float x, float y, float z, out Matrix3 result) + { + result = Identity; + result.Row0.X = x; + result.Row1.Y = y; + result.Row2.Z = z; + } + +#endregion + + #region Multiply Functions + + public static Matrix3 Mult(Matrix3 left, Matrix3 right) + { + Matrix3 result; + Mult(ref left, ref right, out result); + return result; + } + + public static void Mult(ref Matrix3 left, ref Matrix3 right, out Matrix3 result) + { + float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, + lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, + lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, + rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, + rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, + rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z; + + result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); + result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); + result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); + result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); + result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); + result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); + result.Row2.X = ((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31); + result.Row2.Y = ((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32); + result.Row2.Z = ((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33); + } + +#endregion + + #region Invert Functions + + /// + /// Calculate the inverse of the given matrix + /// + /// The matrix to invert + /// The inverse of the given matrix if it has one, or the input if it is singular + /// Thrown if the Matrix3 is singular. + public static void Invert(ref Matrix3 mat, out Matrix3 result) + { + int[] colIdx = { 0, 0, 0 }; + int[] rowIdx = { 0, 0, 0 }; + int[] pivotIdx = { -1, -1, -1 }; + + float[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z}, + {mat.Row1.X, mat.Row1.Y, mat.Row1.Z}, + {mat.Row2.X, mat.Row2.Y, mat.Row2.Z}}; + + int icol = 0; + int irow = 0; + for (int i = 0; i < 3; i++) + { + float maxPivot = 0.0f; + for (int j = 0; j < 3; j++) + { + if (pivotIdx[j] != 0) + { + for (int k = 0; k < 3; ++k) + { + if (pivotIdx[k] == -1) + { + float absVal = System.Math.Abs(inverse[j, k]); + if (absVal > maxPivot) + { + maxPivot = absVal; + irow = j; + icol = k; + } + } + else if (pivotIdx[k] > 0) + { + result = mat; + return; + } + } + } + } + + ++(pivotIdx[icol]); + + if (irow != icol) + { + for (int k = 0; k < 3; ++k) + { + float f = inverse[irow, k]; + inverse[irow, k] = inverse[icol, k]; + inverse[icol, k] = f; + } + } + + rowIdx[i] = irow; + colIdx[i] = icol; + + float pivot = inverse[icol, icol]; + + if (pivot == 0.0f) + { + throw new InvalidOperationException("Matrix is singular and cannot be inverted."); + } + + float oneOverPivot = 1.0f / pivot; + inverse[icol, icol] = 1.0f; + for (int k = 0; k < 3; ++k) + inverse[icol, k] *= oneOverPivot; + + for (int j = 0; j < 3; ++j) + { + if (icol != j) + { + float f = inverse[j, icol]; + inverse[j, icol] = 0.0f; + for (int k = 0; k < 3; ++k) + inverse[j, k] -= inverse[icol, k] * f; + } + } + } + + for (int j = 2; j >= 0; --j) + { + int ir = rowIdx[j]; + int ic = colIdx[j]; + for (int k = 0; k < 3; ++k) + { + float f = inverse[k, ir]; + inverse[k, ir] = inverse[k, ic]; + inverse[k, ic] = f; + } + } + + result.Row0.X = inverse[0, 0]; + result.Row0.Y = inverse[0, 1]; + result.Row0.Z = inverse[0, 2]; + result.Row1.X = inverse[1, 0]; + result.Row1.Y = inverse[1, 1]; + result.Row1.Z = inverse[1, 2]; + result.Row2.X = inverse[2, 0]; + result.Row2.Y = inverse[2, 1]; + result.Row2.Z = inverse[2, 2]; + } + + /// + /// Calculate the inverse of the given matrix + /// + /// The matrix to invert + /// The inverse of the given matrix if it has one, or the input if it is singular + /// Thrown if the Matrix4 is singular. + public static Matrix3 Invert(Matrix3 mat) + { + Matrix3 result; + Invert(ref mat, out result); + return result; + } + +#endregion + + #region Transpose + + public static Matrix3 Transpose(Matrix3 mat) + { + return new Matrix3(mat.Column0, mat.Column1, mat.Column2); + } + + public static void Transpose(ref Matrix3 mat, out Matrix3 result) + { + result.Row0 = mat.Column0; + result.Row1 = mat.Column1; + result.Row2 = mat.Column2; + } + +#endregion + +#endregion + + #region Operators + + public static Matrix3 operator *(Matrix3 left, Matrix3 right) + { + return Matrix3.Mult(left, right); + } + + public static bool operator ==(Matrix3 left, Matrix3 right) + { + return left.Equals(right); + } + + public static bool operator !=(Matrix3 left, Matrix3 right) + { + return !left.Equals(right); + } + +#endregion + + #region Overrides + + #region public override string ToString() + + /// + /// Returns a System.String that represents the current Matrix3d. + /// + /// The string representation of the matrix. + public override string ToString() + { + return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); + } + +#endregion + + #region public override int GetHashCode() + + /// + /// Returns the hashcode for this instance. + /// + /// A System.Int32 containing the unique hashcode for this instance. + public override int GetHashCode() + { + return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); + } + +#endregion + + #region public override bool Equals(object obj) + + /// + /// Indicates whether this instance and a specified object are equal. + /// + /// The object to compare to. + /// True if the instances are equal; false otherwise. + public override bool Equals(object obj) + { + if (!(obj is Matrix3)) + return false; + + return this.Equals((Matrix3)obj); + } + +#endregion + +#endregion + +#endregion + + #region IEquatable Members + + public bool Equals(Matrix3 other) + { + return + Row0 == other.Row0 && + Row1 == other.Row1 && + Row2 == other.Row2; + } + +#endregion + } +} \ No newline at end of file diff --git a/Source/OpenTK/Math/Matrix3d.cs b/Source/OpenTK/Math/Matrix3d.cs index 800d799b..7a347a26 100644 --- a/Source/OpenTK/Math/Matrix3d.cs +++ b/Source/OpenTK/Math/Matrix3d.cs @@ -27,802 +27,652 @@ using System.Runtime.InteropServices; namespace OpenTK { - // Todo: Remove this warning when the code goes public. - #pragma warning disable 3019 -#if false + /// + /// Represents a 3x3 Matrix + /// [Serializable] [StructLayout(LayoutKind.Sequential)] public struct Matrix3d : IEquatable { - #region Fields & Access - - /// Row 0, Column 0 - public double R0C0; - - /// Row 0, Column 1 - public double R0C1; - - /// Row 0, Column 2 - public double R0C2; - - /// Row 1, Column 0 - public double R1C0; - - /// Row 1, Column 1 - public double R1C1; - - /// Row 1, Column 2 - public double R1C2; - - /// Row 2, Column 0 - public double R2C0; - - /// Row 2, Column 1 - public double R2C1; - - /// Row 2, Column 2 - public double R2C2; - - /// Gets the component at the given row and column in the matrix. - /// The row of the matrix. - /// The column of the matrix. - /// The component at the given row and column in the matrix. - public double this[int row, int column] - { - get - { - switch( row ) - { - case 0: - switch (column) - { - case 0: return R0C0; - case 1: return R0C1; - case 2: return R0C2; - } - break; - - case 1: - switch (column) - { - case 0: return R1C0; - case 1: return R1C1; - case 2: return R1C2; - } - break; - - case 2: - switch (column) - { - case 0: return R2C0; - case 1: return R2C1; - case 2: return R2C2; - } - break; - } - - throw new IndexOutOfRangeException(); - } - set - { - switch( row ) - { - case 0: - switch (column) - { - case 0: R0C0 = value; return; - case 1: R0C1 = value; return; - case 2: R0C2 = value; return; - } - break; - - case 1: - switch (column) - { - case 0: R1C0 = value; return; - case 1: R1C1 = value; return; - case 2: R1C2 = value; return; - } - break; - - case 2: - switch (column) - { - case 0: R2C0 = value; return; - case 1: R2C1 = value; return; - case 2: R2C2 = value; return; - } - break; - } - - throw new IndexOutOfRangeException(); - } - } - - /// Gets the component at the index into the matrix. - /// The index into the components of the matrix. - /// The component at the given index into the matrix. - public double this[int index] - { - get - { - switch (index) - { - case 0: return R0C0; - case 1: return R0C1; - case 2: return R0C2; - case 3: return R1C0; - case 4: return R1C1; - case 5: return R1C2; - case 6: return R2C0; - case 7: return R2C1; - case 8: return R2C2; - default: throw new IndexOutOfRangeException(); - } - } - set - { - switch (index) - { - case 0: R0C0 = value; return; - case 1: R0C1 = value; return; - case 2: R0C2 = value; return; - case 3: R1C0 = value; return; - case 4: R1C1 = value; return; - case 5: R1C2 = value; return; - case 6: R2C0 = value; return; - case 7: R2C1 = value; return; - case 8: R2C2 = value; return; - default: throw new IndexOutOfRangeException(); - } - } - } - - /// Converts the matrix into an IntPtr. - /// The matrix to convert. - /// An IntPtr for the matrix. - public static explicit operator IntPtr(Matrix3d matrix) - { - unsafe - { - return (IntPtr)(&matrix.R0C0); - } - } - - /// Converts the matrix into left double*. - /// The matrix to convert. - /// A double* for the matrix. - [CLSCompliant(false)] - unsafe public static explicit operator double*(Matrix3d matrix) - { - return &matrix.R0C0; - } - - /// Converts the matrix into an array of doubles. - /// The matrix to convert. - /// An array of doubles for the matrix. - public static explicit operator double[](Matrix3d matrix) - { - return new double[9] - { - matrix.R0C0, - matrix.R0C1, - matrix.R0C2, - matrix.R1C0, - matrix.R1C1, - matrix.R1C2, - matrix.R2C0, - matrix.R2C1, - matrix.R2C2 - }; - } - - #endregion - + #region Fields + + /// + /// First row of the matrix. + /// + public Vector3d Row0; + + /// + /// Second row of the matrix. + /// + public Vector3d Row1; + + /// + /// Third row of the matrix. + /// + public Vector3d Row2; + + /// + /// The identity matrix. + /// + public static Matrix3d Identity = new Matrix3d(Vector3d.UnitX, Vector3d.UnitY, Vector3d.UnitZ); + +#endregion + #region Constructors - - /// Constructs left matrix with the same components as the given matrix. - /// The matrix whose components to copy. - public Matrix3d(ref Matrix3d matrix) + + /// + /// Constructs a new instance. + /// + /// Top row of the matrix + /// Second row of the matrix + /// Bottom row of the matrix + public Matrix3d(Vector3d row0, Vector3d row1, Vector3d row2) { - this.R0C0 = matrix.R0C0; - this.R0C1 = matrix.R0C1; - this.R0C2 = matrix.R0C2; - this.R1C0 = matrix.R1C0; - this.R1C1 = matrix.R1C1; - this.R1C2 = matrix.R1C2; - this.R2C0 = matrix.R2C0; - this.R2C1 = matrix.R2C1; - this.R2C2 = matrix.R2C2; + Row0 = row0; + Row1 = row1; + Row2 = row2; } - - /// Constructs left matrix with the given values. - /// The value for row 0 column 0. - /// The value for row 0 column 1. - /// The value for row 0 column 2. - /// The value for row 1 column 0. - /// The value for row 1 column 1. - /// The value for row 1 column 2. - /// The value for row 2 column 0. - /// The value for row 2 column 1. - /// The value for row 2 column 2. - public Matrix3d - ( - double r0c0, - double r0c1, - double r0c2, - double r1c0, - double r1c1, - double r1c2, - double r2c0, - double r2c1, - double r2c2 - ) + + /// + /// Constructs a new instance. + /// + /// First item of the first row of the matrix. + /// Second item of the first row of the matrix. + /// Third item of the first row of the matrix. + /// First item of the second row of the matrix. + /// Second item of the second row of the matrix. + /// Third item of the second row of the matrix. + /// First item of the third row of the matrix. + /// Second item of the third row of the matrix. + /// Third item of the third row of the matrix. + public Matrix3d( + double m00, double m01, double m02, + double m10, double m11, double m12, + double m20, double m21, double m22) { - this.R0C0 = r0c0; - this.R0C1 = r0c1; - this.R0C2 = r0c2; - this.R1C0 = r1c0; - this.R1C1 = r1c1; - this.R1C2 = r1c2; - this.R2C0 = r2c0; - this.R2C1 = r2c1; - this.R2C2 = r2c2; + Row0 = new Vector3d(m00, m01, m02); + Row1 = new Vector3d(m10, m11, m12); + Row2 = new Vector3d(m20, m21, m22); } - - /// Constructs left matrix from the given array of double-precision floating-point numbers. - /// The array of doubles for the components of the matrix. - public Matrix3d(double[] doubleArray) - { - if (doubleArray == null || doubleArray.GetLength(0) < 9) throw new MissingFieldException(); - - this.R0C0 = doubleArray[0]; - this.R0C1 = doubleArray[1]; - this.R0C2 = doubleArray[2]; - this.R1C0 = doubleArray[3]; - this.R1C1 = doubleArray[4]; - this.R1C2 = doubleArray[5]; - this.R2C0 = doubleArray[6]; - this.R2C1 = doubleArray[7]; - this.R2C2 = doubleArray[8]; - } - - /// Constructs left matrix from the given quaternion. - /// The quaternion to use to construct the martix. - public Matrix3d(Quaterniond quaternion) - { - quaternion.Normalize(); - - double xx = quaternion.X * quaternion.X; - double yy = quaternion.Y * quaternion.Y; - double zz = quaternion.Z * quaternion.Z; - double xy = quaternion.X * quaternion.Y; - double xz = quaternion.X * quaternion.Z; - double yz = quaternion.Y * quaternion.Z; - double wx = quaternion.W * quaternion.X; - double wy = quaternion.W * quaternion.Y; - double wz = quaternion.W * quaternion.Z; - - R0C0 = 1 - 2 * (yy + zz); - R0C1 = 2 * (xy - wz); - R0C2 = 2 * (xz + wy); - - R1C0 = 2 * (xy + wz); - R1C1 = 1 - 2 * (xx + zz); - R1C2 = 2 * (yz - wx); - - R2C0 = 2 * (xz - wy); - R2C1 = 2 * (yz + wx); - R2C2 = 1 - 2 * (xx + yy); - } - - #endregion - - #region Equality - - /// Indicates whether the current matrix is equal to another matrix. - /// The OpenTK.Matrix3d structure to compare with. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - [CLSCompliant(false)] - public bool Equals(Matrix3d matrix) - { - return - R0C0 == matrix.R0C0 && - R0C1 == matrix.R0C1 && - R0C2 == matrix.R0C2 && - R1C0 == matrix.R1C0 && - R1C1 == matrix.R1C1 && - R1C2 == matrix.R1C2 && - R2C0 == matrix.R2C0 && - R2C1 == matrix.R2C1 && - R2C2 == matrix.R2C2; - } - - /// Indicates whether the current matrix is equal to another matrix. - /// The OpenTK.Matrix3d structure to compare to. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(ref Matrix3d matrix) - { - return - R0C0 == matrix.R0C0 && - R0C1 == matrix.R0C1 && - R0C2 == matrix.R0C2 && - R1C0 == matrix.R1C0 && - R1C1 == matrix.R1C1 && - R1C2 == matrix.R1C2 && - R2C0 == matrix.R2C0 && - R2C1 == matrix.R2C1 && - R2C2 == matrix.R2C2; - } - - /// Indicates whether the current matrix is equal to another matrix. - /// The left-hand operand. - /// The right-hand operand. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public static bool Equals(ref Matrix3d left, ref Matrix3d right) - { - return - left.R0C0 == right.R0C0 && - left.R0C1 == right.R0C1 && - left.R0C2 == right.R0C2 && - left.R1C0 == right.R1C0 && - left.R1C1 == right.R1C1 && - left.R1C2 == right.R1C2 && - left.R2C0 == right.R2C0 && - left.R2C1 == right.R2C1 && - left.R2C2 == right.R2C2; - } - - /// Indicates whether the current matrix is approximately equal to another matrix. - /// The OpenTK.Matrix3d structure to compare with. - /// The limit below which the matrices are considered equal. - /// true if the current matrix is approximately equal to the matrix parameter; otherwise, false. - public bool EqualsApprox(ref Matrix3d matrix, double tolerance) - { - return - System.Math.Abs(R0C0 - matrix.R0C0) <= tolerance && - System.Math.Abs(R0C1 - matrix.R0C1) <= tolerance && - System.Math.Abs(R0C2 - matrix.R0C2) <= tolerance && - System.Math.Abs(R1C0 - matrix.R1C0) <= tolerance && - System.Math.Abs(R1C1 - matrix.R1C1) <= tolerance && - System.Math.Abs(R1C2 - matrix.R1C2) <= tolerance && - System.Math.Abs(R2C0 - matrix.R2C0) <= tolerance && - System.Math.Abs(R2C1 - matrix.R2C1) <= tolerance && - System.Math.Abs(R2C2 - matrix.R2C2) <= tolerance; - } - - /// Indicates whether the current matrix is approximately equal to another matrix. - /// The left-hand operand. - /// The right-hand operand. - /// The limit below which the matrices are considered equal. - /// true if the current matrix is approximately equal to the matrix parameter; otherwise, false. - public static bool EqualsApprox(ref Matrix3d left, ref Matrix3d right, double tolerance) - { - return - System.Math.Abs(left.R0C0 - right.R0C0) <= tolerance && - System.Math.Abs(left.R0C1 - right.R0C1) <= tolerance && - System.Math.Abs(left.R0C2 - right.R0C2) <= tolerance && - System.Math.Abs(left.R1C0 - right.R1C0) <= tolerance && - System.Math.Abs(left.R1C1 - right.R1C1) <= tolerance && - System.Math.Abs(left.R1C2 - right.R1C2) <= tolerance && - System.Math.Abs(left.R2C0 - right.R2C0) <= tolerance && - System.Math.Abs(left.R2C1 - right.R2C1) <= tolerance && - System.Math.Abs(left.R2C2 - right.R2C2) <= tolerance; - } - - #endregion - - #region Arithmetic Operators - - - /// Add left matrix to this matrix. - /// The matrix to add. - public void Add(ref Matrix3d matrix) - { - R0C0 = R0C0 + matrix.R0C0; - R0C1 = R0C1 + matrix.R0C1; - R0C2 = R0C2 + matrix.R0C2; - R1C0 = R1C0 + matrix.R1C0; - R1C1 = R1C1 + matrix.R1C1; - R1C2 = R1C2 + matrix.R1C2; - R2C0 = R2C0 + matrix.R2C0; - R2C1 = R2C1 + matrix.R2C1; - R2C2 = R2C2 + matrix.R2C2; - } - - /// Add left matrix to this matrix. - /// The matrix to add. - /// The resulting matrix of the addition. - public void Add(ref Matrix3d matrix, out Matrix3d result) - { - result.R0C0 = R0C0 + matrix.R0C0; - result.R0C1 = R0C1 + matrix.R0C1; - result.R0C2 = R0C2 + matrix.R0C2; - result.R1C0 = R1C0 + matrix.R1C0; - result.R1C1 = R1C1 + matrix.R1C1; - result.R1C2 = R1C2 + matrix.R1C2; - result.R2C0 = R2C0 + matrix.R2C0; - result.R2C1 = R2C1 + matrix.R2C1; - result.R2C2 = R2C2 + matrix.R2C2; - } - - /// Add left matrix to left matrix. - /// The matrix on the matrix side of the equation. - /// The matrix on the right side of the equation - /// The resulting matrix of the addition. - public static void Add(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) - { - result.R0C0 = left.R0C0 + right.R0C0; - result.R0C1 = left.R0C1 + right.R0C1; - result.R0C2 = left.R0C2 + right.R0C2; - result.R1C0 = left.R1C0 + right.R1C0; - result.R1C1 = left.R1C1 + right.R1C1; - result.R1C2 = left.R1C2 + right.R1C2; - result.R2C0 = left.R2C0 + right.R2C0; - result.R2C1 = left.R2C1 + right.R2C1; - result.R2C2 = left.R2C2 + right.R2C2; - } - - - /// Subtract left matrix from this matrix. - /// The matrix to subtract. - public void Subtract(ref Matrix3d matrix) - { - R0C0 = R0C0 + matrix.R0C0; - R0C1 = R0C1 + matrix.R0C1; - R0C2 = R0C2 + matrix.R0C2; - R1C0 = R1C0 + matrix.R1C0; - R1C1 = R1C1 + matrix.R1C1; - R1C2 = R1C2 + matrix.R1C2; - R2C0 = R2C0 + matrix.R2C0; - R2C1 = R2C1 + matrix.R2C1; - R2C2 = R2C2 + matrix.R2C2; - } - - /// Subtract left matrix from this matrix. - /// The matrix to subtract. - /// The resulting matrix of the subtraction. - public void Subtract(ref Matrix3d matrix, out Matrix3d result) - { - result.R0C0 = R0C0 + matrix.R0C0; - result.R0C1 = R0C1 + matrix.R0C1; - result.R0C2 = R0C2 + matrix.R0C2; - result.R1C0 = R1C0 + matrix.R1C0; - result.R1C1 = R1C1 + matrix.R1C1; - result.R1C2 = R1C2 + matrix.R1C2; - result.R2C0 = R2C0 + matrix.R2C0; - result.R2C1 = R2C1 + matrix.R2C1; - result.R2C2 = R2C2 + matrix.R2C2; - } - - /// Subtract left matrix from left matrix. - /// The matrix on the matrix side of the equation. - /// The matrix on the right side of the equation - /// The resulting matrix of the subtraction. - public static void Subtract(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) - { - result.R0C0 = left.R0C0 + right.R0C0; - result.R0C1 = left.R0C1 + right.R0C1; - result.R0C2 = left.R0C2 + right.R0C2; - result.R1C0 = left.R1C0 + right.R1C0; - result.R1C1 = left.R1C1 + right.R1C1; - result.R1C2 = left.R1C2 + right.R1C2; - result.R2C0 = left.R2C0 + right.R2C0; - result.R2C1 = left.R2C1 + right.R2C1; - result.R2C2 = left.R2C2 + right.R2C2; - } - - - /// Multiply left martix times this matrix. - /// The matrix to multiply. - public void Multiply(ref Matrix3d matrix) - { - double r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0; - double r0c1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1; - double r0c2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2; - - double r1c0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0; - double r1c1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1; - double r1c2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2; - - R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0; - R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1; - R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2; - - - R0C0 = r0c0; - R0C1 = r0c1; - R0C2 = r0c2; - - R1C0 = r1c0; - R1C1 = r1c1; - R1C2 = r1c2; - } - - /// Multiply matrix times this matrix. - /// The matrix to multiply. - /// The resulting matrix of the multiplication. - public void Multiply(ref Matrix3d matrix, out Matrix3d result) - { - result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0; - result.R0C1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1; - result.R0C2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2; - result.R1C0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0; - result.R1C1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1; - result.R1C2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2; - result.R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0; - result.R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1; - result.R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2; - } - - /// Multiply left matrix times left matrix. - /// The matrix on the matrix side of the equation. - /// The matrix on the right side of the equation - /// The resulting matrix of the multiplication. - public static void Multiply(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) - { - result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0; - result.R0C1 = right.R0C0 * left.R0C1 + right.R0C1 * left.R1C1 + right.R0C2 * left.R2C1; - result.R0C2 = right.R0C0 * left.R0C2 + right.R0C1 * left.R1C2 + right.R0C2 * left.R2C2; - result.R1C0 = right.R1C0 * left.R0C0 + right.R1C1 * left.R1C0 + right.R1C2 * left.R2C0; - result.R1C1 = right.R1C0 * left.R0C1 + right.R1C1 * left.R1C1 + right.R1C2 * left.R2C1; - result.R1C2 = right.R1C0 * left.R0C2 + right.R1C1 * left.R1C2 + right.R1C2 * left.R2C2; - result.R2C0 = right.R2C0 * left.R0C0 + right.R2C1 * left.R1C0 + right.R2C2 * left.R2C0; - result.R2C1 = right.R2C0 * left.R0C1 + right.R2C1 * left.R1C1 + right.R2C2 * left.R2C1; - result.R2C2 = right.R2C0 * left.R0C2 + right.R2C1 * left.R1C2 + right.R2C2 * left.R2C2; - } - - - /// Multiply matrix times this matrix. - /// The matrix to multiply. - public void Multiply(double scalar) - { - R0C0 = scalar * R0C0; - R0C1 = scalar * R0C1; - R0C2 = scalar * R0C2; - R1C0 = scalar * R1C0; - R1C1 = scalar * R1C1; - R1C2 = scalar * R1C2; - R2C0 = scalar * R2C0; - R2C1 = scalar * R2C1; - R2C2 = scalar * R2C2; - } - - /// Multiply matrix times this matrix. - /// The matrix to multiply. - /// The resulting matrix of the multiplication. - public void Multiply(double scalar, out Matrix3d result) - { - result.R0C0 = scalar * R0C0; - result.R0C1 = scalar * R0C1; - result.R0C2 = scalar * R0C2; - result.R1C0 = scalar * R1C0; - result.R1C1 = scalar * R1C1; - result.R1C2 = scalar * R1C2; - result.R2C0 = scalar * R2C0; - result.R2C1 = scalar * R2C1; - result.R2C2 = scalar * R2C2; - } - - /// Multiply left matrix times left matrix. - /// The matrix on the matrix side of the equation. - /// The matrix on the right side of the equation - /// The resulting matrix of the multiplication. - public static void Multiply(ref Matrix3d matrix, double scalar, out Matrix3d result) - { - result.R0C0 = scalar * matrix.R0C0; - result.R0C1 = scalar * matrix.R0C1; - result.R0C2 = scalar * matrix.R0C2; - result.R1C0 = scalar * matrix.R1C0; - result.R1C1 = scalar * matrix.R1C1; - result.R1C2 = scalar * matrix.R1C2; - result.R2C0 = scalar * matrix.R2C0; - result.R2C1 = scalar * matrix.R2C1; - result.R2C2 = scalar * matrix.R2C2; - } - - - #endregion - - #region Functions - + +#endregion + + #region Public Members + + #region Properties + + /// + /// Gets the determinant of this matrix. + /// public double Determinant { get { - return R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0; + double m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, + m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, + m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z; + + return + m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 + - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33; } } - + + /// + /// Gets the first column of this matrix. + /// + public Vector3d Column0 + { + get { return new Vector3d(Row0.X, Row1.X, Row2.X); } + } + + /// + /// Gets the second column of this matrix. + /// + public Vector3d Column1 + { + get { return new Vector3d(Row0.Y, Row1.Y, Row2.Y); } + } + + /// + /// Gets the third column of this matrix. + /// + public Vector3d Column2 + { + get { return new Vector3d(Row0.Z, Row1.Z, Row2.Z); } + } + + /// + /// Gets or sets the value at row 1, column 1 of this instance. + /// + public double M11 { get { return Row0.X; } set { Row0.X = value; } } + + /// + /// Gets or sets the value at row 1, column 2 of this instance. + /// + public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } + + /// + /// Gets or sets the value at row 1, column 3 of this instance. + /// + public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } + + /// + /// Gets or sets the value at row 2, column 1 of this instance. + /// + public double M21 { get { return Row1.X; } set { Row1.X = value; } } + + /// + /// Gets or sets the value at row 2, column 2 of this instance. + /// + public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } + + /// + /// Gets or sets the value at row 2, column 3 of this instance. + /// + public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } + + /// + /// Gets or sets the value at row 3, column 1 of this instance. + /// + public double M31 { get { return Row2.X; } set { Row2.X = value; } } + + /// + /// Gets or sets the value at row 3, column 2 of this instance. + /// + public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } + + /// + /// Gets or sets the value at row 3, column 3 of this instance. + /// + public double M33 { get { return Row2.Z; } set { Row2.Z = value; } } + +#endregion + + #region Instance + + #region public void Invert() + + public void Invert() + { + this = Matrix3d.Invert(this); + } + +#endregion + + #region public void Transpose() + public void Transpose() { - Functions.Swap(ref R0C1, ref R1C0); - Functions.Swap(ref R0C2, ref R2C0); - Functions.Swap(ref R1C2, ref R2C1); + this = Matrix3d.Transpose(this); } - public void Transpose(out Matrix3d result) + +#endregion + +#endregion + + #region Static + + #region CreateFromAxisAngle + + public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix3d result) { - result.R0C0 = R0C0; - result.R0C1 = R1C0; - result.R0C2 = R2C0; - result.R1C0 = R0C1; - result.R1C1 = R1C1; - result.R1C2 = R2C1; - result.R2C0 = R0C2; - result.R2C1 = R1C2; - result.R2C2 = R2C2; + //normalize and create a local copy of the vector. + axis.Normalize(); + double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; + + //calculate angles + double cos = System.Math.Cos(-angle); + double sin = System.Math.Sin(-angle); + double t = 1.0f - cos; + + //do the conversion math once + double tXX = t * axisX * axisX, + tXY = t * axisX * axisY, + tXZ = t * axisX * axisZ, + tYY = t * axisY * axisY, + tYZ = t * axisY * axisZ, + tZZ = t * axisZ * axisZ; + + double sinX = sin * axisX, + sinY = sin * axisY, + sinZ = sin * axisZ; + + result.Row0.X = tXX + cos; + result.Row0.Y = tXY - sinZ; + result.Row0.Z = tXZ + sinY; + result.Row1.X = tXY + sinZ; + result.Row1.Y = tYY + cos; + result.Row1.Z = tYZ - sinX; + result.Row2.X = tXZ - sinY; + result.Row2.Y = tYZ + sinX; + result.Row2.Z = tZZ + cos; } - public static void Transpose(ref Matrix3d matrix, out Matrix3d result) + + public static Matrix3d CreateFromAxisAngle(Vector3d axis, double angle) { - result.R0C0 = matrix.R0C0; - result.R0C1 = matrix.R1C0; - result.R0C2 = matrix.R2C0; - result.R1C0 = matrix.R0C1; - result.R1C1 = matrix.R1C1; - result.R1C2 = matrix.R2C1; - result.R2C0 = matrix.R0C2; - result.R2C1 = matrix.R1C2; - result.R2C2 = matrix.R2C2; + Matrix3d result; + CreateFromAxisAngle(axis, angle, out result); + return result; } - - #endregion - - #region Transformation Functions - - public void Transform(ref Vector3d vector) + +#endregion + + #region CreateFromQuaternion + + public static void CreateFromQuaternion(ref Quaterniond q, out Matrix3d result) { - double x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z; - double y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z; - vector.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z; - vector.X = x; - vector.Y = y; + Vector3d axis; + double angle; + q.ToAxisAngle(out axis, out angle); + CreateFromAxisAngle(axis, angle, out result); } - public static void Transform(ref Matrix3d matrix, ref Vector3d vector) + + public static Matrix3d CreateFromQuaternion(Quaterniond q) { - double x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z; - double y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z; - vector.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z; - vector.X = x; - vector.Y = y; + Matrix3d result; + CreateFromQuaternion(ref q, out result); + return result; } - public void Transform(ref Vector3d vector, out Vector3d result) + +#endregion + + #region CreateRotation[XYZ] + + public static void CreateRotationX(double angle, out Matrix3d result) { - result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z; - result.Y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z; - result.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z; + double cos = System.Math.Cos(angle); + double sin = System.Math.Sin(angle); + + result = Identity; + result.Row1.Y = cos; + result.Row1.Z = sin; + result.Row2.Y = -sin; + result.Row2.Z = cos; } - public static void Transform(ref Matrix3d matrix, ref Vector3d vector, out Vector3d result) + + public static Matrix3d CreateRotationX(double angle) { - result.X = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z; - result.Y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z; - result.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z; + Matrix3d result; + CreateRotationX(angle, out result); + return result; } - - public void Rotate(double angle) + + public static void CreateRotationY(double angle, out Matrix3d result) { - double angleRadians = Functions.DTOR * angle; - double sin = (double)System.Math.Sin(angleRadians); - double cos = (double)System.Math.Cos(angleRadians); - - double r0c0 = cos * R0C0 + sin * R1C0; - double r0c1 = cos * R0C1 + sin * R1C1; - double r0c2 = cos * R0C2 + sin * R1C2; - - R1C0 = cos * R1C0 - sin * R0C0; - R1C1 = cos * R1C1 - sin * R0C1; - R1C2 = cos * R1C2 - sin * R0C2; - - R0C0 = r0c0; - R0C1 = r0c1; - R0C2 = r0c2; + double cos = System.Math.Cos(angle); + double sin = System.Math.Sin(angle); + + result = Identity; + result.Row0.X = cos; + result.Row0.Z = -sin; + result.Row2.X = sin; + result.Row2.Z = cos; } - public void Rotate(double angle, out Matrix3d result) + + public static Matrix3d CreateRotationY(double angle) { - double angleRadians = Functions.DTOR * angle; - double sin = (double)System.Math.Sin(angleRadians); - double cos = (double)System.Math.Cos(angleRadians); - - result.R0C0 = cos * R0C0 + sin * R1C0; - result.R0C1 = cos * R0C1 + sin * R1C1; - result.R0C2 = cos * R0C2 + sin * R1C2; - result.R1C0 = cos * R1C0 - sin * R0C0; - result.R1C1 = cos * R1C1 - sin * R0C1; - result.R1C2 = cos * R1C2 - sin * R0C2; - result.R2C0 = R2C0; - result.R2C1 = R2C1; - result.R2C2 = R2C2; + Matrix3d result; + CreateRotationY(angle, out result); + return result; } - public static void Rotate(ref Matrix3d matrix, double angle, out Matrix3d result) + + public static void CreateRotationZ(double angle, out Matrix3d result) { - double angleRadians = Functions.DTOR * angle; - double sin = (double)System.Math.Sin(angleRadians); - double cos = (double)System.Math.Cos(angleRadians); - - result.R0C0 = cos * matrix.R0C0 + sin * matrix.R1C0; - result.R0C1 = cos * matrix.R0C1 + sin * matrix.R1C1; - result.R0C2 = cos * matrix.R0C2 + sin * matrix.R1C2; - result.R1C0 = cos * matrix.R1C0 - sin * matrix.R0C0; - result.R1C1 = cos * matrix.R1C1 - sin * matrix.R0C1; - result.R1C2 = cos * matrix.R1C2 - sin * matrix.R0C2; - result.R2C0 = matrix.R2C0; - result.R2C1 = matrix.R2C1; - result.R2C2 = matrix.R2C2; + double cos = System.Math.Cos(angle); + double sin = System.Math.Sin(angle); + + result = Identity; + result.Row0.X = cos; + result.Row0.Y = sin; + result.Row1.X = -sin; + result.Row1.Y = cos; } - public static void RotateMatrix(double angle, out Matrix3d result) + + public static Matrix3d CreateRotationZ(double angle) { - double angleRadians = Functions.DTOR * angle; - double sin = (double)System.Math.Sin(angleRadians); - double cos = (double)System.Math.Cos(angleRadians); - - result.R0C0 = cos; - result.R0C1 = sin; - result.R0C2 = 0; - result.R1C0 = -sin; - result.R1C1 = cos; - result.R1C2 = 0; - result.R2C0 = 0; - result.R2C1 = 0; - result.R2C2 = 1; + Matrix3d result; + CreateRotationZ(angle, out result); + return result; } - - public Quaterniond ToQuaternion() + +#endregion + + #region CreateScale + + /// + /// Creates a scale matrix. + /// + /// Single scale factor for the x, y, and z axes. + /// A scale matrix. + public static Matrix3d CreateScale(double scale) { - //return new Quaterniond(ref this); + Matrix3d result; + CreateScale(scale, out result); + return result; } - - #endregion - - #region Constants - - /// The identity matrix. - public static readonly Matrix3d Identity = new Matrix3d - ( - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - ); - - /// A matrix of all zeros. - public static readonly Matrix3d Zero = new Matrix3d - ( - 0, 0, 0, - 0, 0, 0, - 0, 0, 0 - ); - - #endregion - - #region HashCode - - /// Returns the hash code for this instance. - /// A 32-bit signed integer that is the hash code for this instance. - public override int GetHashCode() + + /// + /// Creates a scale matrix. + /// + /// Scale factors for the x, y, and z axes. + /// A scale matrix. + public static Matrix3d CreateScale(Vector3d scale) { - return - R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^ - R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^ - R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode(); + Matrix3d result; + CreateScale(ref scale, out result); + return result; } - - #endregion - - #region String - - /// Returns the fully qualified type name of this instance. - /// A System.String containing left fully qualified type name. + + /// + /// Creates a scale matrix. + /// + /// Scale factor for the x axis. + /// Scale factor for the y axis. + /// Scale factor for the z axis. + /// A scale matrix. + public static Matrix3d CreateScale(double x, double y, double z) + { + Matrix3d result; + CreateScale(x, y, z, out result); + return result; + } + + /// + /// Creates a scale matrix. + /// + /// Single scale factor for the x, y, and z axes. + /// A scale matrix. + public static void CreateScale(double scale, out Matrix3d result) + { + result = Identity; + result.Row0.X = scale; + result.Row1.Y = scale; + result.Row2.Z = scale; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factors for the x, y, and z axes. + /// A scale matrix. + public static void CreateScale(ref Vector3d scale, out Matrix3d result) + { + result = Identity; + result.Row0.X = scale.X; + result.Row1.Y = scale.Y; + result.Row2.Z = scale.Z; + } + + /// + /// Creates a scale matrix. + /// + /// Scale factor for the x axis. + /// Scale factor for the y axis. + /// Scale factor for the z axis. + /// A scale matrix. + public static void CreateScale(double x, double y, double z, out Matrix3d result) + { + result = Identity; + result.Row0.X = x; + result.Row1.Y = y; + result.Row2.Z = z; + } + +#endregion + + #region Multiply Functions + + public static Matrix3d Mult(Matrix3d left, Matrix3d right) + { + Matrix3d result; + Mult(ref left, ref right, out result); + return result; + } + + public static void Mult(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) + { + double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, + lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, + lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, + rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, + rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, + rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z; + + result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); + result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); + result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); + result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); + result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); + result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); + result.Row2.X = ((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31); + result.Row2.Y = ((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32); + result.Row2.Z = ((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33); + } + +#endregion + + #region Invert Functions + + /// + /// Calculate the inverse of the given matrix + /// + /// The matrix to invert + /// The inverse of the given matrix if it has one, or the input if it is singular + /// Thrown if the Matrix3d is singular. + public static void Invert(ref Matrix3d mat, out Matrix3d result) + { + int[] colIdx = { 0, 0, 0 }; + int[] rowIdx = { 0, 0, 0 }; + int[] pivotIdx = { -1, -1, -1 }; + + double[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z}, + {mat.Row1.X, mat.Row1.Y, mat.Row1.Z}, + {mat.Row2.X, mat.Row2.Y, mat.Row2.Z}}; + + int icol = 0; + int irow = 0; + for (int i = 0; i < 3; i++) + { + double maxPivot = 0.0; + for (int j = 0; j < 3; j++) + { + if (pivotIdx[j] != 0) + { + for (int k = 0; k < 3; ++k) + { + if (pivotIdx[k] == -1) + { + double absVal = System.Math.Abs(inverse[j, k]); + if (absVal > maxPivot) + { + maxPivot = absVal; + irow = j; + icol = k; + } + } + else if (pivotIdx[k] > 0) + { + result = mat; + return; + } + } + } + } + + ++(pivotIdx[icol]); + + if (irow != icol) + { + for (int k = 0; k < 3; ++k) + { + double f = inverse[irow, k]; + inverse[irow, k] = inverse[icol, k]; + inverse[icol, k] = f; + } + } + + rowIdx[i] = irow; + colIdx[i] = icol; + + double pivot = inverse[icol, icol]; + + if (pivot == 0.0) + { + throw new InvalidOperationException("Matrix is singular and cannot be inverted."); + } + + double oneOverPivot = 1.0 / pivot; + inverse[icol, icol] = 1.0; + for (int k = 0; k < 3; ++k) + inverse[icol, k] *= oneOverPivot; + + for (int j = 0; j < 3; ++j) + { + if (icol != j) + { + double f = inverse[j, icol]; + inverse[j, icol] = 0.0; + for (int k = 0; k < 3; ++k) + inverse[j, k] -= inverse[icol, k] * f; + } + } + } + + for (int j = 2; j >= 0; --j) + { + int ir = rowIdx[j]; + int ic = colIdx[j]; + for (int k = 0; k < 3; ++k) + { + double f = inverse[k, ir]; + inverse[k, ir] = inverse[k, ic]; + inverse[k, ic] = f; + } + } + + result.Row0.X = inverse[0, 0]; + result.Row0.Y = inverse[0, 1]; + result.Row0.Z = inverse[0, 2]; + result.Row1.X = inverse[1, 0]; + result.Row1.Y = inverse[1, 1]; + result.Row1.Z = inverse[1, 2]; + result.Row2.X = inverse[2, 0]; + result.Row2.Y = inverse[2, 1]; + result.Row2.Z = inverse[2, 2]; + } + + /// + /// Calculate the inverse of the given matrix + /// + /// The matrix to invert + /// The inverse of the given matrix if it has one, or the input if it is singular + /// Thrown if the Matrix4 is singular. + public static Matrix3d Invert(Matrix3d mat) + { + Matrix3d result; + Invert(ref mat, out result); + return result; + } + +#endregion + + #region Transpose + + public static Matrix3d Transpose(Matrix3d mat) + { + return new Matrix3d(mat.Column0, mat.Column1, mat.Column2); + } + + public static void Transpose(ref Matrix3d mat, out Matrix3d result) + { + result.Row0 = mat.Column0; + result.Row1 = mat.Column1; + result.Row2 = mat.Column2; + } + +#endregion + +#endregion + + #region Operators + + public static Matrix3d operator *(Matrix3d left, Matrix3d right) + { + return Matrix3d.Mult(left, right); + } + + public static bool operator ==(Matrix3d left, Matrix3d right) + { + return left.Equals(right); + } + + public static bool operator !=(Matrix3d left, Matrix3d right) + { + return !left.Equals(right); + } + +#endregion + + #region Overrides + + #region public override string ToString() + + /// + /// Returns a System.String that represents the current Matrix3d. + /// + /// The string representation of the matrix. public override string ToString() { - return String.Format( - "|{00}, {01}, {02}|\n" + - "|{03}, {04}, {05}|\n" + - "|{06}, {07}, {18}|\n" + - R0C0, R0C1, R0C2, - R1C0, R1C1, R1C2, - R2C0, R2C1, R2C2); + return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); } - - #endregion + +#endregion + + #region public override int GetHashCode() + + /// + /// Returns the hashcode for this instance. + /// + /// A System.Int32 containing the unique hashcode for this instance. + public override int GetHashCode() + { + return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); + } + +#endregion + + #region public override bool Equals(object obj) + + /// + /// Indicates whether this instance and a specified object are equal. + /// + /// The object to compare to. + /// True if the instances are equal; false otherwise. + public override bool Equals(object obj) + { + if (!(obj is Matrix3d)) + return false; + + return this.Equals((Matrix3d)obj); + } + +#endregion + +#endregion + +#endregion + + #region IEquatable Members + + public bool Equals(Matrix3d other) + { + return + Row0 == other.Row0 && + Row1 == other.Row1 && + Row2 == other.Row2; + } + +#endregion } -#endif - #pragma warning restore 3019 -} +} \ No newline at end of file diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj index 9cd3f603..d794c9b4 100644 --- a/Source/OpenTK/OpenTK.csproj +++ b/Source/OpenTK/OpenTK.csproj @@ -42,32 +42,32 @@ true - true + True 285212672 DEBUG;TRACE; OpenTK.xml - true + True 4096 - false + False ..\..\Binaries\OpenTK\Debug\ False False 4 AllRules.ruleset full - true + True - true + True 285212672 TRACE; OpenTK.xml 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -79,19 +79,19 @@ ..\..\Binaries\OpenTK\Release\ none 4 - true + True TRACE; - true + True - true + True 285212672 TRACE; OpenTK.xml 4096 - true + True ..\..\Binaries\OpenTK\Release\ False False @@ -100,7 +100,7 @@ none - true + True ..\..\OpenTK.snk @@ -108,19 +108,15 @@ System - False System.Data - False System.Drawing - False System.Xml - False @@ -769,6 +765,7 @@ +