diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..73da0d91
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,139 @@
+# Ignores specific to OpenTK.
+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
+Source/Compatibility/Tao/Platform/Windows/SimpleOpenGlControl.resources
+Source/Examples/ExampleBrowser.resources
+Source/Examples/OpenAL/1.1/Parrot.resources
+Source/Examples/OpenTK/Fonts/FontRenderingBasic.resources
+Source/Examples/OpenTK/GLControl/DerivedGLControl.resources
+Source/Examples/OpenTK/GLControl/GLControlGameLoop.resources
+Source/Examples/OpenTK/GLControl/GLControlSimple.resources
+Source/Examples/OpenTK/GLControl/MultipleGLControls.resources
+Source/Examples/OpenTK/Test/Extensions.resources
+Source/Examples/OpenTK/Test/InputLogger.resources
+Source/Examples/Properties/Resources.resources
+Source/OpenTK/Properties/Resources.resources
+
+
+# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
+[Bb]in/
+[Oo]bj/
+
+# mstest test results
+TestResults
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Mac folder attribute metadata file
+.DS_Store
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+x64/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.log
+*.vspscc
+*.vssscc
+.builds
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# Mindbench SASS cache
+.sass-cache/
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+packages
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql
+TestResults
+[Tt]est[Rr]esult*
+*.Cache
+ClientBin
+[Ss]tyle[Cc]op.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
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/README.md b/README.md
new file mode 100644
index 00000000..80b93bd1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+OpenTK
+======
+
+The Open Toolkit is an advanced, low-level C# library that wraps OpenGL, OpenCL and OpenAL. The OpenTK home is http://www.opentk.com/
+
+This is an unofficial fork for community changes that we hope will someday make it into the official repository. Unfortunately, the only official maintainer of OpenTK has been missing since early 2012.
+
+This fork was created from the latest official SVN repository. It contains numerous fixes by the original maintainer that are not found in the last release (2010-10-06). This fork is based on AndyKorth's OpenTK fork with lots of fixes from all over the community.
+
+Documentation
+=============
+
+The best source of documentation is the [OpenTK Manual](http://www.opentk.com/doc)
+
+Need Help?
+==========
+
+Head over to the [OpenTK forums](http://www.opentk.com/forum). It's the best way to reach the community.
+
+OpenTK Version: 1.1.1160.61462 (build 2013-03-07), also available via nuget (OpenTK and OpenTKWithOpenAL) and used in the DeltaEngine.
diff --git a/Source/Bind/Generator.Bind.csproj b/Source/Bind/Generator.Bind.csproj
index e7c06637..10149ada 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
@@ -1040,7 +1036,6 @@
Designer
-
diff --git a/Source/Build.UpdateVersion/Build.UpdateVersion.csproj b/Source/Build.UpdateVersion/Build.UpdateVersion.csproj
index 34d60ecf..1510b9a9 100644
--- a/Source/Build.UpdateVersion/Build.UpdateVersion.csproj
+++ b/Source/Build.UpdateVersion/Build.UpdateVersion.csproj
@@ -38,7 +38,6 @@
-
@@ -51,7 +50,7 @@
4
- true
+ True
full
4
diff --git a/Source/Build.UpdateVersion/Program.cs b/Source/Build.UpdateVersion/Program.cs
index 9e7a9303..29d17cc9 100644
--- a/Source/Build.UpdateVersion/Program.cs
+++ b/Source/Build.UpdateVersion/Program.cs
@@ -1,168 +1,191 @@
-#region License
-//
-// The Open Toolkit Library License
-//
-// Copyright (c) 2006 - 2010 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.Diagnostics;
-using System.IO;
-
-namespace Build.UpdateVersion
-{
- class Program
- {
- const string Major = "1";
- const string Minor = "1";
-
- static string RootDirectory;
- static string SourceDirectory;
-
- public static void Main()
- {
- string wdir = Environment.CurrentDirectory;
- if (Directory.GetParent(wdir).Name == "Source")
- {
- // Running through msbuild inside Source/Build.UpdateVersion/
- RootDirectory = "../..";
- SourceDirectory = "..";
- }
- else
- {
- // Running manually inside Binaries/OpenTK/[Debug|Release]/
- RootDirectory = "../../..";
- SourceDirectory = "../../../Source";
- }
-
- DateTime now = DateTime.UtcNow;
- GenerateVersionInfo(now, Path.Combine(RootDirectory, "Version.txt"));
- GenerateAssemblyInfo(now, Path.Combine(SourceDirectory, "GlobalAssemblyInfo.cs"));
- }
-
- static void GenerateVersionInfo(DateTime now, string file)
- {
- string version = null;
-
- if (System.IO.File.Exists(file))
- {
- string[] lines = System.IO.File.ReadAllLines(file);
- if (lines.Length > 0 && !String.IsNullOrEmpty(lines[0]))
- {
- version = lines[0];
- }
- }
-
- // If the file does not exist, create it.
- if (version == null)
- {
- version = now.ToString("u").Split(' ')[0];
- System.IO.File.WriteAllLines(file, new string[] { version });
- }
- }
-
- static void GenerateAssemblyInfo(DateTime now, string file)
- {
- // Build number is defined as the number of days since 1/1/2010.
- // Revision number is defined as the fraction of the current day, expressed in seconds.
- double timespan = now.Subtract(new DateTime(2010, 1, 1)).TotalDays;
- string build = ((int)timespan).ToString();
-
- string revision = RetrieveSvnRevision() ?? RetrieveBzrRevision() ?? RetrieveSeconds(timespan);
- revision = revision.Trim();
-
- File.WriteAllLines(file, new string[]
- {
- "// This file is auto-generated through Source/Build.Tasks/GenerateAssemblyInfo.cs.",
- "// Do not edit by hand!",
- "",
- "using System;",
- "using System.Reflection;",
- "using System.Resources;",
- "using System.Runtime.CompilerServices;",
- "using System.Runtime.InteropServices;",
- "",
- "[assembly: AssemblyCompany(\"The Open Toolkit Library\")]",
- "[assembly: AssemblyProduct(\"The Open Toolkit Library\")]",
- "[assembly: AssemblyCopyright(\"Copyright © 2006 - 2010 the Open Toolkit Library\")]",
- "[assembly: AssemblyTrademark(\"OpenTK\")]",
- String.Format("[assembly: AssemblyVersion(\"{0}.{1}.0.0\")]", Major, Minor),
- String.Format("[assembly: AssemblyFileVersion(\"{0}.{1}.{2}.{3}\")]", Major, Minor, build, revision),
- });
- }
-
- static string RetrieveSeconds(double timespan)
- {
- string revision = ((int)((timespan - (int)timespan) * UInt16.MaxValue)).ToString();
- return revision;
- }
-
- static string RetrieveSvnRevision()
- {
- try
- {
- string output = RunProcess("svn", "info", RootDirectory);
-
- const string RevisionText = "Revision: ";
- int index = output.IndexOf(RevisionText);
- if (index > -1)
- return output.Substring(index + RevisionText.Length, 5)
- .Replace('\r', ' ').Replace('\n', ' ').Trim();
- }
- catch (Exception e)
- {
- Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
- }
- return null;
- }
-
- static string RetrieveBzrRevision()
- {
- try
- {
- string output = RunProcess("bzr", "revno", RootDirectory);
- return output != null && !output.StartsWith("bzr") ? output : null;
- }
- catch (Exception e)
- {
- Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
- }
- return null;
- }
-
- static string RunProcess(string cmd, string args, string wdir)
- {
- ProcessStartInfo info = new ProcessStartInfo(cmd, args);
- info.WorkingDirectory = wdir;
- info.RedirectStandardOutput = true;
- info.RedirectStandardError = true;
- info.UseShellExecute = false;
- Process p = new Process();
- p.StartInfo = info;
- p.Start();
- p.WaitForExit();
- string output = p.StandardOutput.ReadToEnd();
- return output;
- }
- }
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2010 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.Diagnostics;
+using System.IO;
+
+namespace Build.UpdateVersion
+{
+ class Program
+ {
+ const string Major = "1";
+ const string Minor = "1";
+
+ static string RootDirectory;
+ static string SourceDirectory;
+
+ public static void Main()
+ {
+ string wdir = Environment.CurrentDirectory;
+ if (Directory.GetParent(wdir).Name == "Source")
+ {
+ // Running through msbuild inside Source/Build.UpdateVersion/
+ RootDirectory = "../..";
+ SourceDirectory = "..";
+ }
+ else
+ {
+ // Running manually inside Binaries/OpenTK/[Debug|Release]/
+ RootDirectory = "../../..";
+ SourceDirectory = "../../../Source";
+ }
+
+ DateTime now = DateTime.UtcNow;
+ GenerateVersionInfo(now, Path.Combine(RootDirectory, "Version.txt"));
+ GenerateAssemblyInfo(now, Path.Combine(SourceDirectory, "GlobalAssemblyInfo.cs"));
+ }
+
+ static void GenerateVersionInfo(DateTime now, string file)
+ {
+ string version = null;
+
+ if (System.IO.File.Exists(file))
+ {
+ string[] lines = System.IO.File.ReadAllLines(file);
+ if (lines.Length > 0 && !String.IsNullOrEmpty(lines[0]))
+ {
+ version = lines[0];
+ }
+ }
+
+ // If the file does not exist, create it.
+ if (version == null)
+ {
+ version = now.ToString("u").Split(' ')[0];
+ System.IO.File.WriteAllLines(file, new string[] { version });
+ }
+ }
+
+ static void GenerateAssemblyInfo(DateTime now, string file)
+ {
+ // Build number is defined as the number of days since 1/1/2010.
+ // Revision number is defined as the fraction of the current day, expressed in seconds.
+ double timespan = now.Subtract(new DateTime(2010, 1, 1)).TotalDays;
+ string build = ((int)timespan).ToString();
+
+ string revision = RetrieveGitRevision() ?? RetrieveSvnRevision() ?? RetrieveBzrRevision() ?? RetrieveSeconds(timespan);
+ revision = revision.Trim();
+
+ Console.WriteLine("Build timestamp was: " + build);
+ Console.WriteLine("Revision detected was: " + revision);
+
+ File.WriteAllLines(file, new string[]
+ {
+ "// This file is auto-generated through Source/Build.Tasks/GenerateAssemblyInfo.cs.",
+ "// Do not edit by hand!",
+ "",
+ "using System;",
+ "using System.Reflection;",
+ "using System.Resources;",
+ "using System.Runtime.CompilerServices;",
+ "using System.Runtime.InteropServices;",
+ "",
+ "[assembly: AssemblyCompany(\"The Open Toolkit Library\")]",
+ "[assembly: AssemblyProduct(\"The Open Toolkit Library\")]",
+ "[assembly: AssemblyCopyright(\"Copyright © 2006 - 2010 the Open Toolkit Library\")]",
+ "[assembly: AssemblyTrademark(\"OpenTK\")]",
+ String.Format("[assembly: AssemblyVersion(\"{0}.{1}.0.0\")]", Major, Minor),
+ String.Format("[assembly: AssemblyFileVersion(\"{0}.{1}.{2}.{3}\")]", Major, Minor, build, revision),
+ });
+ }
+
+ static string RetrieveSeconds(double timespan)
+ {
+ string revision = ((int)((timespan - (int)timespan) * UInt16.MaxValue)).ToString();
+ return revision;
+ }
+
+ static string RetrieveGitRevision()
+ {
+ try
+ {
+ string output = RunProcess("git", "log -1", RootDirectory);
+
+ const string RevisionText = "commit ";
+ int index = output.IndexOf(RevisionText);
+ int endIndex = output.IndexOf("\n"); // since it's the first line...
+ if (index > -1)
+ return output.Substring(index + RevisionText.Length, endIndex - index - RevisionText.Length).Trim();
+ }
+ catch (Exception e)
+ {
+ Debug.Print("Failed to retrieve git revision. Error: {0}", e);
+ }
+ return null;
+ }
+
+
+ static string RetrieveSvnRevision()
+ {
+ try
+ {
+ string output = RunProcess("svn", "info", RootDirectory);
+
+ const string RevisionText = "Revision: ";
+ int index = output.IndexOf(RevisionText);
+ if (index > -1)
+ return output.Substring(index + RevisionText.Length, 5)
+ .Replace('\r', ' ').Replace('\n', ' ').Trim();
+ }
+ catch (Exception e)
+ {
+ Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
+ }
+ return null;
+ }
+
+ static string RetrieveBzrRevision()
+ {
+ try
+ {
+ string output = RunProcess("bzr", "revno", RootDirectory);
+ return output != null && !output.StartsWith("bzr") ? output : null;
+ }
+ catch (Exception e)
+ {
+ Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
+ }
+ return null;
+ }
+
+ static string RunProcess(string cmd, string args, string wdir)
+ {
+ ProcessStartInfo info = new ProcessStartInfo(cmd, args);
+ info.WorkingDirectory = wdir;
+ info.RedirectStandardOutput = true;
+ info.RedirectStandardError = true;
+ info.UseShellExecute = false;
+ Process p = new Process();
+ p.StartInfo = info;
+ p.Start();
+ p.WaitForExit();
+ string output = p.StandardOutput.ReadToEnd();
+ return output;
+ }
+ }
}
\ No newline at end of file
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..cc6529aa 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
@@ -166,7 +162,6 @@
-
diff --git a/Source/Examples/Data/Shaders/Parallax_FS.glsl b/Source/Examples/Data/Shaders/Parallax_FS.glsl
index 113f2e4e..ea259a47 100644
--- a/Source/Examples/Data/Shaders/Parallax_FS.glsl
+++ b/Source/Examples/Data/Shaders/Parallax_FS.glsl
@@ -1,57 +1,57 @@
-// Copyright (c) 2008 the OpenTK Team. See license.txt for legal bla
-
-// Material uniforms
-uniform sampler2D Material_DiffuseAndHeight;
-uniform sampler2D Material_NormalAndGloss;
-uniform vec3 Material_ScaleBiasShininess; // x=Scale, y=Bias, z=Shininess
-
-// Light uniforms
-uniform vec3 Light_DiffuseColor;
-uniform vec3 Light_SpecularColor;
-
-// from VS
-varying vec3 VaryingLightVector;
-varying vec3 VaryingEyeVector;
-
-vec3 normal;
-
-void main()
-{
- vec3 lightVector = normalize( VaryingLightVector );
- vec3 eyeVector = normalize( VaryingEyeVector );
-
- // first, find the parallax displacement by reading only the height map
- float parallaxOffset = texture2D( Material_DiffuseAndHeight, gl_TexCoord[0].st ).a *
- Material_ScaleBiasShininess.x - Material_ScaleBiasShininess.y;
- vec2 newTexCoords = gl_TexCoord[0].st + ( parallaxOffset * eyeVector.xy ); // displace texcoords according to viewer
-
- // knowing the displacement, read RGB, Normal and Gloss
- vec3 diffuseColor = texture2D( Material_DiffuseAndHeight, newTexCoords.st ).rgb;
- vec4 temp = texture2D( Material_NormalAndGloss, newTexCoords.st );
-
- // build a usable normal vector
- normal.xy = temp.ag * 2.0 - 1.0; // swizzle alpha and green to x/y and scale to [-1..+1]
- normal.z = sqrt( 1.0 - normal.x*normal.x - normal.y*normal.y ); // z = sqrt(1-x²-y²)
-
- // move other properties to be better readable
- float gloss = temp.r;
-
-// float alpha = temp.b;
-// if ( alpha < 0.2 ) // optimization: should move this test before reading RGB texture
-// discard;
-
- // tweaked phong lighting
- float lambert = max( dot( lightVector, normal ), 0.0 );
-
- gl_FragColor = vec4( Light_DiffuseColor * diffuseColor, 1.0 ) *
- lambert;
-
- if ( lambert > 0.0 )
- {
- float specular = pow(
- clamp( dot( reflect( -lightVector, normal ), eyeVector ), 0.0, 1.0 ),
- Material_ScaleBiasShininess.z );
-
- gl_FragColor += vec4( Light_SpecularColor * diffuseColor, 1.0 ) * ( specular * gloss );
- }
+// Copyright (c) 2008 the OpenTK Team. See license.txt for legal bla
+
+// Material uniforms
+uniform sampler2D Material_DiffuseAndHeight;
+uniform sampler2D Material_NormalAndGloss;
+uniform vec3 Material_ScaleBiasShininess; // x=Scale, y=Bias, z=Shininess
+
+// Light uniforms
+uniform vec3 Light_DiffuseColor;
+uniform vec3 Light_SpecularColor;
+
+// from VS
+varying vec3 VaryingLightVector;
+varying vec3 VaryingEyeVector;
+
+vec3 normal;
+
+void main()
+{
+ vec3 lightVector = normalize( VaryingLightVector );
+ vec3 eyeVector = normalize( VaryingEyeVector );
+
+ // first, find the parallax displacement by reading only the height map
+ float parallaxOffset = texture2D( Material_DiffuseAndHeight, gl_TexCoord[0].st ).a *
+ Material_ScaleBiasShininess.x - Material_ScaleBiasShininess.y;
+ vec2 newTexCoords = gl_TexCoord[0].st + ( parallaxOffset * eyeVector.xy ); // displace texcoords according to viewer
+
+ // knowing the displacement, read RGB, Normal and Gloss
+ vec3 diffuseColor = texture2D( Material_DiffuseAndHeight, newTexCoords.st ).rgb;
+ vec4 temp = texture2D( Material_NormalAndGloss, newTexCoords.st );
+
+ // build a usable normal vector
+ normal.xy = temp.ag * 2.0 - 1.0; // swizzle alpha and green to x/y and scale to [-1..+1]
+ normal.z = sqrt( 1.0 - normal.x*normal.x - normal.y*normal.y ); // z = sqrt(1-x^2-y^2)
+
+ // move other properties to be better readable
+ float gloss = temp.r;
+
+// float alpha = temp.b;
+// if ( alpha < 0.2 ) // optimization: should move this test before reading RGB texture
+// discard;
+
+ // tweaked phong lighting
+ float lambert = max( dot( lightVector, normal ), 0.0 );
+
+ gl_FragColor = vec4( Light_DiffuseColor * diffuseColor, 1.0 ) *
+ lambert;
+
+ if ( lambert > 0.0 )
+ {
+ float specular = pow(
+ clamp( dot( reflect( -lightVector, normal ), eyeVector ), 0.0, 1.0 ),
+ Material_ScaleBiasShininess.z );
+
+ gl_FragColor += vec4( Light_SpecularColor * diffuseColor, 1.0 ) * ( specular * gloss );
+ }
}
\ No newline at end of file
diff --git a/Source/Examples/Main.cs b/Source/Examples/Main.cs
index c44eeae7..cb940537 100644
--- a/Source/Examples/Main.cs
+++ b/Source/Examples/Main.cs
@@ -41,10 +41,19 @@ namespace Examples
public static void Main()
{
try
- {
+ {
+ // This seems to be useful enough to leave in for a while.
+ TextWriterTraceListener console = new TextWriterTraceListener(System.Console.Out);
+ Trace.Listeners.Add (console);
+
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
+ // The ExampleBrowser works pretty poorly on some platforms, so you may want to start examples directly.
+ // for example: Examples.Tutorial.T12_GLSL_Parallax.Main ();
+ // Examples.Tutorial.T10_GLSL_Cube.Main ();
+ Examples.Tests.BasicMouseInput.Main ();
+
using (Form browser = new ExampleBrowser())
{
try
diff --git a/Source/Examples/OpenTK.Examples.csproj b/Source/Examples/OpenTK.Examples.csproj
index b52793d5..f272a374 100644
--- a/Source/Examples/OpenTK.Examples.csproj
+++ b/Source/Examples/OpenTK.Examples.csproj
@@ -44,16 +44,16 @@
true
- true
+ True
285212672
DEBUG;TRACE;
- true
+ True
4096
- false
+ False
..\..\Binaries\OpenTK\Debug\
False
False
@@ -62,7 +62,7 @@
full
- true
+ True
285212672
@@ -70,7 +70,7 @@
4096
- true
+ True
..\..\Binaries\OpenTK\Release\
False
False
@@ -82,11 +82,11 @@
..\..\Binaries\OpenTK\Release\
none
4
- true
+ True
TRACE;
- true
+ True
285212672
@@ -94,7 +94,7 @@
4096
- true
+ True
..\..\Binaries\OpenTK\Release\
False
False
@@ -103,7 +103,7 @@
none
- true
+ True
..\..\OpenTK.snk
@@ -111,23 +111,18 @@
System
- False
System.Data
- False
System.Drawing
- False
System.Windows.Forms
- False
System.Xml
- False
@@ -560,6 +555,10 @@
Always
+
+ Code
+
+
diff --git a/Source/Examples/OpenTK/Test/BasicMouseInput.cs b/Source/Examples/OpenTK/Test/BasicMouseInput.cs
new file mode 100644
index 00000000..a66d8268
--- /dev/null
+++ b/Source/Examples/OpenTK/Test/BasicMouseInput.cs
@@ -0,0 +1,89 @@
+// This code was written for the OpenTK library and has been released
+// to the Public Domain by Andy Korth
+// It is provided "as is" without express or implied warranty of any kind.
+
+#region --- Using Directives ---
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+using OpenTK;
+using OpenTK.Graphics;
+using OpenTK.Graphics.OpenGL;
+using OpenTK.Input;
+
+#endregion --- Using Directives ---
+
+namespace Examples.Tests
+{
+ ///
+ /// Demonstrates basic recommended mouse input, and to see if it actually works
+ ///
+ [Example("Basic Mouse Input", ExampleCategory.OpenTK,"Basic Mouse Input")]
+ public class BasicMouseInput : GameWindow
+ {
+
+ public BasicMouseInput()
+ : base(800, 600)
+ { }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+
+ this.Mouse.ButtonUp += (object sender, MouseButtonEventArgs buttonEvent) => {
+ Console.WriteLine("Mouse button up: " + buttonEvent.Button + " at: " + buttonEvent.Position);
+ };
+
+ GL.ClearColor(Color.MidnightBlue);
+ GL.Enable(EnableCap.DepthTest);
+ }
+
+ protected override void OnUpdateFrame(FrameEventArgs e)
+ {
+ base.OnUpdateFrame(e);
+
+ // Here's the big test!
+ if(OpenTK.Input.Mouse.GetState()[MouseButton.Left]){
+ Console.WriteLine("The left mouse button is down!");
+ }
+
+
+ // While we are here, test keyboard.
+ if(OpenTK.Input.Keyboard.GetState()[Key.A]){
+ Console.WriteLine("The A key is down!");
+ }
+
+ if (Keyboard[OpenTK.Input.Key.Escape])
+ this.Exit();
+
+ if (Keyboard[OpenTK.Input.Key.F11])
+ if (WindowState != WindowState.Fullscreen)
+ WindowState = WindowState.Fullscreen;
+ else
+ WindowState = WindowState.Normal;
+ }
+
+
+ protected override void OnRenderFrame(FrameEventArgs e)
+ {
+ GL.Clear(ClearBufferMask.ColorBufferBit);
+ SwapBuffers();
+ }
+
+ [STAThread]
+ public static void Main()
+ {
+ using (BasicMouseInput example = new BasicMouseInput())
+ {
+ // Get the title and category of this example using reflection.
+ ExampleAttribute info = ((ExampleAttribute)example.GetType().GetCustomAttributes(false)[0]);
+ example.Title = String.Format("OpenTK | {0} {1}: {2}", info.Category, info.Difficulty, info.Title);
+
+ example.Run(30.0);
+ }
+ }
+
+ }
+}
diff --git a/Source/Examples/OpenTK/Test/MatrixTest.cs b/Source/Examples/OpenTK/Test/MatrixTest.cs
new file mode 100644
index 00000000..690ae2d6
--- /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, translation);
+
+ 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/Graphics/ES10/ES.cs b/Source/OpenTK/Graphics/ES10/ES.cs
index 46a96ad2..14ee343c 100644
--- a/Source/OpenTK/Graphics/ES10/ES.cs
+++ b/Source/OpenTK/Graphics/ES10/ES.cs
@@ -34,6 +34,7 @@ namespace OpenTK.Graphics.ES10
#pragma warning disable 1591
#pragma warning disable 1572
#pragma warning disable 1573
+ #pragma warning disable 3006
partial class GL
{
diff --git a/Source/OpenTK/Graphics/ES11/ES.cs b/Source/OpenTK/Graphics/ES11/ES.cs
index 016ee7a9..a9104b43 100644
--- a/Source/OpenTK/Graphics/ES11/ES.cs
+++ b/Source/OpenTK/Graphics/ES11/ES.cs
@@ -34,6 +34,7 @@ namespace OpenTK.Graphics.ES11
#pragma warning disable 1591
#pragma warning disable 1572
#pragma warning disable 1573
+ #pragma warning disable 3006
partial class GL
{
diff --git a/Source/OpenTK/Graphics/ES20/ES.cs b/Source/OpenTK/Graphics/ES20/ES.cs
index 2e4c3a71..bcad6f80 100644
--- a/Source/OpenTK/Graphics/ES20/ES.cs
+++ b/Source/OpenTK/Graphics/ES20/ES.cs
@@ -34,6 +34,7 @@ namespace OpenTK.Graphics.ES20
#pragma warning disable 1591
#pragma warning disable 1572
#pragma warning disable 1573
+ #pragma warning disable 3006
partial class GL
{
diff --git a/Source/OpenTK/Graphics/ES20/Helper.cs b/Source/OpenTK/Graphics/ES20/Helper.cs
index f0046f36..9ce72459 100644
--- a/Source/OpenTK/Graphics/ES20/Helper.cs
+++ b/Source/OpenTK/Graphics/ES20/Helper.cs
@@ -137,6 +137,28 @@ namespace OpenTK.Graphics.ES20
GL.Uniform4(location, quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
}
+ public static void UniformMatrix2(int location, bool transpose, ref Matrix2 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3(int location, bool transpose, ref Matrix3 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix)
{
unsafe
diff --git a/Source/OpenTK/Graphics/OpenGL/GL.cs b/Source/OpenTK/Graphics/OpenGL/GL.cs
index ba764839..ef73d314 100644
--- a/Source/OpenTK/Graphics/OpenGL/GL.cs
+++ b/Source/OpenTK/Graphics/OpenGL/GL.cs
@@ -34,6 +34,7 @@ namespace OpenTK.Graphics.OpenGL
#pragma warning disable 1591
#pragma warning disable 1572
#pragma warning disable 1573
+ #pragma warning disable 3006
partial class GL
{
diff --git a/Source/OpenTK/Graphics/OpenGL/GLHelper.cs b/Source/OpenTK/Graphics/OpenGL/GLHelper.cs
index 6e071871..fdee387e 100644
--- a/Source/OpenTK/Graphics/OpenGL/GLHelper.cs
+++ b/Source/OpenTK/Graphics/OpenGL/GLHelper.cs
@@ -300,17 +300,6 @@ namespace OpenTK.Graphics.OpenGL
}
}
- public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix)
- {
- unsafe
- {
- fixed (float* matrix_ptr = &matrix.Row0.X)
- {
- GL.UniformMatrix4(location, 1, transpose, matrix_ptr);
- }
- }
- }
-
public static void Normal3(Vector3d normal)
{
GL.Normal3(normal.X, normal.Y, normal.Z);
@@ -420,6 +409,8 @@ namespace OpenTK.Graphics.OpenGL
}
}
+ #endregion
+
#region Uniform
[CLSCompliant(false)]
@@ -465,7 +456,203 @@ namespace OpenTK.Graphics.OpenGL
GL.Uniform4(location, quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
}
- #endregion
+ public static void UniformMatrix2(int location, bool transpose, ref Matrix2 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix2(int location, bool transpose, ref Matrix2d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix2x3(int location, bool transpose, ref Matrix2x3 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2x3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix2x3(int location, bool transpose, ref Matrix2x3d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2x3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix2x4(int location, bool transpose, ref Matrix2x4 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2x4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix2x4(int location, bool transpose, ref Matrix2x4d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix2x4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3x2(int location, bool transpose, ref Matrix3x2 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3x2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3x2(int location, bool transpose, ref Matrix3x2d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3x2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3(int location, bool transpose, ref Matrix3 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3(int location, bool transpose, ref Matrix3d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3x4(int location, bool transpose, ref Matrix3x4 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3x4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix3x4(int location, bool transpose, ref Matrix3x4d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix3x4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4x2(int location, bool transpose, ref Matrix4x2 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4x2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4x2(int location, bool transpose, ref Matrix4x2d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4x2(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4x3(int location, bool transpose, ref Matrix4x3 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4x3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4x3(int location, bool transpose, ref Matrix4x3d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4x3(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix)
+ {
+ unsafe
+ {
+ fixed (float* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
+
+ public static void UniformMatrix4(int location, bool transpose, ref Matrix4d matrix)
+ {
+ unsafe
+ {
+ fixed (double* matrix_ptr = &matrix.Row0.X)
+ {
+ GL.UniformMatrix4(location, 1, transpose, matrix_ptr);
+ }
+ }
+ }
#endregion
diff --git a/Source/OpenTK/Input/GamePadAxis.cs b/Source/OpenTK/Input/GamePadAxis.cs
new file mode 100644
index 00000000..c1c96c53
--- /dev/null
+++ b/Source/OpenTK/Input/GamePadAxis.cs
@@ -0,0 +1,56 @@
+//
+// GamePadAxis.cs
+//
+// Author:
+// robert <${AuthorEmail}>
+//
+// Copyright (c) 2012 robert
+//
+// 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.
+using System;
+
+namespace OpenTK
+{
+ public enum GamePadAxis
+ {
+ /// The first axis of the gamepad.
+ Axis0 = 0,
+ /// The second axis of the gamepad.
+ Axis1,
+ /// The third axis of the gamepad.
+ Axis2,
+ /// The fourth axis of the gamepad.
+ Axis3,
+ /// The fifth axis of the gamepad.
+ Axis4,
+ /// The sixth axis of the gamepad.
+ Axis5,
+ /// The seventh axis of the gamepad.
+ Axis6,
+ /// The eighth axis of the gamepad.
+ Axis7,
+ /// The ninth axis of the gamepad.
+ Axis8,
+ /// The tenth axis of the gamepad.
+ Axis9,
+ /// The last axis of the gamepad.
+ LastAxis
+ }
+}
+
diff --git a/Source/OpenTK/Input/GamePadButton.cs b/Source/OpenTK/Input/GamePadButton.cs
new file mode 100644
index 00000000..f4f543ad
--- /dev/null
+++ b/Source/OpenTK/Input/GamePadButton.cs
@@ -0,0 +1,68 @@
+//
+// GamePadButton.cs
+//
+// Author:
+// robert <${AuthorEmail}>
+//
+// Copyright (c) 2012 robert
+//
+// 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.
+using System;
+
+namespace OpenTK
+{
+ public enum GamePadButton
+ {
+ /// The first button of the gamepad.
+ Button0 = 0,
+ /// The second button of the gamepad.
+ Button1,
+ /// The third button of the gamepad.
+ Button2,
+ /// The fourth button of the gamepad.
+ Button3,
+ /// The fifth button of the gamepad.
+ Button4,
+ /// The sixth button of the gamepad.
+ Button5,
+ /// The seventh button of the gamepad.
+ Button6,
+ /// The eighth button of the gamepad.
+ Button7,
+ /// The ninth button of the gamepad.
+ Button8,
+ /// The tenth button of the gamepad.
+ Button9,
+ /// The eleventh button of the gamepad.
+ Button10,
+ /// The twelfth button of the gamepad.
+ Button11,
+ /// The thirteenth button of the gamepad.
+ Button12,
+ /// The fourteenth button of the gamepad.
+ Button13,
+ /// The fifteenth button of the gamepad.
+ Button14,
+ /// The sixteenth button of the gamepad.
+ Button15,
+ /// The last button of the gamepad.
+ LastButton
+ }
+}
+
diff --git a/Source/OpenTK/Input/GamePadState.cs b/Source/OpenTK/Input/GamePadState.cs
index ed2d2fd0..21e3aa91 100644
--- a/Source/OpenTK/Input/GamePadState.cs
+++ b/Source/OpenTK/Input/GamePadState.cs
@@ -32,7 +32,8 @@ namespace OpenTK.Input
///
/// Encapsulates the state of a GamePad device.
///
- public struct GamePadState
+ public struct GamePadState /*: IEquatable*/
{
+
}
}
diff --git a/Source/OpenTK/Input/IGamePadDriver.cs b/Source/OpenTK/Input/IGamePadDriver.cs
index 0f536dda..3df61309 100644
--- a/Source/OpenTK/Input/IGamePadDriver.cs
+++ b/Source/OpenTK/Input/IGamePadDriver.cs
@@ -6,5 +6,26 @@ namespace OpenTK.Input
{
interface IGamePadDriver
{
+ ///
+ /// Retrieves the combined for all gamepad devices.
+ ///
+ /// A structure containing the combined state for all gamepad devices.
+ GamePadState GetState();
+
+ ///
+ /// Retrieves the for the specified gamepad device.
+ ///
+ /// The index of the keyboard device.
+ /// A structure containing the state of the gamepad device.
+ GamePadState GetState(int index);
+
+ ///
+ /// Retrieves the device name for the gamepad device.
+ ///
+ /// The index of the gamepad device.
+ /// A with the name of the specified device or .
+ ///
+ /// If no device exists at the specified index, the return value is .
+ string GetDeviceName(int index);
}
}
diff --git a/Source/OpenTK/Input/KeyboardDevice.cs b/Source/OpenTK/Input/KeyboardDevice.cs
index b1a14b9c..d21ca5a7 100644
--- a/Source/OpenTK/Input/KeyboardDevice.cs
+++ b/Source/OpenTK/Input/KeyboardDevice.cs
@@ -22,6 +22,7 @@ namespace OpenTK.Input
{
//private IKeyboard keyboard;
private bool[] keys = new bool[Enum.GetValues(typeof(Key)).Length];
+ private bool[] scancodes = new bool[256];
private string description;
private int numKeys, numFKeys, numLeds;
private IntPtr devID;
@@ -44,24 +45,16 @@ namespace OpenTK.Input
public bool this[Key key]
{
get { return keys[(int)key]; }
- internal set
- {
- if (keys[(int)key] != value || KeyRepeat)
- {
- keys[(int)key] = value;
+ }
- if (value && KeyDown != null)
- {
- args.Key = key;
- KeyDown(this, args);
- }
- else if (!value && KeyUp != null)
- {
- args.Key = key;
- KeyUp(this, args);
- }
- }
- }
+ ///
+ /// Gets a value indicating the status of the specified Key.
+ ///
+ /// The scancode to check.
+ /// True if the scancode is pressed, false otherwise.
+ public bool this[uint scancode]
+ {
+ get { return scancodes[scancode]; }
}
///
@@ -197,12 +190,34 @@ namespace OpenTK.Input
internal void ClearKeys()
{
for (int i = 0; i < keys.Length; i++)
- if (this[(Key)i]) // Make sure KeyUp events are *not* raised for keys that are up, even if key repeat is on.
- this[(Key)i] = false;
+ keys[i] = false;
+ for (uint i = 0; i < scancodes.Length; i++)
+ scancodes[i] = false;
}
#endregion
+ internal void SetKey(Key key, uint scancode, bool state)
+ {
+ if (keys[(int)key] != state || KeyRepeat)
+ {
+ keys[(int)key] = scancodes[scancode] = state;
+
+ if (state && KeyDown != null)
+ {
+ args.Key = key;
+ args.ScanCode = scancode;
+ KeyDown(this, args);
+ }
+ else if (!state && KeyUp != null)
+ {
+ args.Key = key;
+ args.ScanCode = scancode;
+ KeyUp(this, args);
+ }
+ }
+ }
+
#endregion
}
}
\ No newline at end of file
diff --git a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
index ac3ce8af..f607090c 100644
--- a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
+++ b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
@@ -1,83 +1,95 @@
-#region License
-//
-// The Open Toolkit Library License
-//
-// Copyright (c) 2006 - 2009 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.Collections.Generic;
-using System.Text;
-
-namespace OpenTK.Input
-{
- ///
- /// Defines the event data for events.
- ///
- ///
- ///
- /// Do not cache instances of this type outside their event handler.
- /// If necessary, you can clone a KeyboardEventArgs instance using the
- /// constructor.
- ///
- ///
- public class KeyboardKeyEventArgs : EventArgs
- {
- #region Fields
-
- Key key;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Constructs a new KeyboardEventArgs instance.
- ///
- public KeyboardKeyEventArgs() { }
-
- ///
- /// Constructs a new KeyboardEventArgs instance.
- ///
- /// An existing KeyboardEventArgs instance to clone.
- public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
- {
- Key = args.Key;
- }
-
- #endregion
-
- #region Public Members
-
- ///
- /// Gets the that generated this event.
- ///
- public Key Key
- {
- get { return key; }
- internal set { key = value; }
- }
-
- #endregion
- }
-}
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2009 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.Collections.Generic;
+using System.Text;
+
+namespace OpenTK.Input
+{
+ ///
+ /// Defines the event data for events.
+ ///
+ ///
+ ///
+ /// Do not cache instances of this type outside their event handler.
+ /// If necessary, you can clone a KeyboardEventArgs instance using the
+ /// constructor.
+ ///
+ ///
+ public class KeyboardKeyEventArgs : EventArgs
+ {
+ #region Fields
+
+ Key key;
+ uint scancode;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new KeyboardEventArgs instance.
+ ///
+ public KeyboardKeyEventArgs() { }
+
+ ///
+ /// Constructs a new KeyboardEventArgs instance.
+ ///
+ /// An existing KeyboardEventArgs instance to clone.
+ public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
+ {
+ Key = args.Key;
+ ScanCode = args.ScanCode;
+ }
+
+ #endregion
+
+ #region Public Members
+
+ ///
+ /// Gets the that generated this event.
+ ///
+ public Key Key
+ {
+ get { return key; }
+ internal set { key = value; }
+ }
+
+ ///
+ /// Gets the scancode which generated this event.
+ ///
+ public uint ScanCode
+ {
+ get { return scancode; }
+ internal set { scancode = value; }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Input/KeyboardState.cs b/Source/OpenTK/Input/KeyboardState.cs
index d37c60da..15c42ade 100644
--- a/Source/OpenTK/Input/KeyboardState.cs
+++ b/Source/OpenTK/Input/KeyboardState.cs
@@ -43,6 +43,9 @@ namespace OpenTK.Input
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
unsafe fixed int Keys[NumInts];
+
+ const int CodesSize = 256;
+ unsafe fixed int Codes[CodesSize];
bool is_connected;
#endregion
@@ -58,13 +61,17 @@ namespace OpenTK.Input
public bool this[Key key]
{
get { return IsKeyDown(key); }
- internal set
- {
- if (value)
- EnableBit((int)key);
- else
- DisableBit((int)key);
- }
+ }
+
+ ///
+ /// Gets a indicating whether the specified
+ /// is pressed.
+ ///
+ /// The to check.
+ /// True if key is pressed; false otherwise.
+ public bool this[short code]
+ {
+ get { return IsKeyDown(code); }
}
///
@@ -76,6 +83,15 @@ namespace OpenTK.Input
return ReadBit((int)key);
}
+ ///
+ /// Gets a indicating whether this scan code is down.
+ ///
+ /// The scan code to check.
+ public bool IsKeyDown(short code)
+ {
+ return ReadBit(code,true);
+ }
+
///
/// Gets a indicating whether this key is up.
///
@@ -85,6 +101,15 @@ namespace OpenTK.Input
return !ReadBit((int)key);
}
+ ///
+ /// Gets a indicating whether this scan code is down.
+ ///
+ /// The scan code to check.
+ public bool IsKeyUp(short code)
+ {
+ return !ReadBit(code,true);
+ }
+
///
/// Gets a indicating whether this keyboard
/// is connected.
@@ -187,48 +212,62 @@ namespace OpenTK.Input
#region Internal Members
- internal bool ReadBit(int offset)
+ internal void SetKeyState(Key key, byte code, bool down)
{
- ValidateOffset(offset);
-
- int int_offset = offset / 32;
- int bit_offset = offset % 32;
- unsafe
+ if (down)
{
- fixed (int* k = Keys)
- {
- return (*(k + int_offset) & (1 << bit_offset)) != 0u;
- }
+ EnableBit((int)key);
+ EnableBit(code,true);
+ }
+ else
+ {
+ DisableBit((int)key);
+ DisableBit(code, true);
}
}
- internal void EnableBit(int offset)
+ internal bool ReadBit(int offset, bool ScanCode = false)
{
- ValidateOffset(offset);
+ ValidateOffset(offset, ScanCode);
int int_offset = offset / 32;
int bit_offset = offset % 32;
unsafe
{
- fixed (int* k = Keys)
- {
- *(k + int_offset) |= 1 << bit_offset;
- }
+ if (ScanCode)
+ fixed (int* c = Codes) { return (*(c + int_offset) & (1 << bit_offset)) != 0u; }
+ else
+ fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; }
}
}
- internal void DisableBit(int offset)
+ internal void EnableBit(int offset, bool ScanCode = false)
{
- ValidateOffset(offset);
+ ValidateOffset(offset, ScanCode);
int int_offset = offset / 32;
int bit_offset = offset % 32;
unsafe
{
- fixed (int* k = Keys)
- {
- *(k + int_offset) &= ~(1 << bit_offset);
- }
+ if (ScanCode)
+ fixed (int* c = Codes) { *(c + int_offset) |= 1 << bit_offset; }
+ else
+ fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; }
+ }
+ }
+
+ internal void DisableBit(int offset, bool ScanCode = false)
+ {
+ ValidateOffset(offset, ScanCode);
+
+ int int_offset = offset / 32;
+ int bit_offset = offset % 32;
+ unsafe
+ {
+ if (ScanCode)
+ fixed (int* c = Codes) { *(c + int_offset) &= ~(1 << bit_offset); }
+ else
+ fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
}
}
@@ -242,6 +281,12 @@ namespace OpenTK.Input
for (int i = 0; i < NumInts; i++)
*(k1 + i) |= *(k2 + i);
}
+ int* c2 = other.Codes;
+ fixed (int* c1 = Codes)
+ {
+ for (int i = 0; i < CodesSize; i++)
+ *(c1 + i) |= *(c2 + i);
+ }
}
IsConnected |= other.IsConnected;
}
@@ -250,9 +295,9 @@ namespace OpenTK.Input
#region Private Members
- static void ValidateOffset(int offset)
+ static void ValidateOffset(int offset, bool ScanCode)
{
- if (offset < 0 || offset >= NumInts * IntSize)
+ if (offset < 0 || offset >= (ScanCode ? 256 : NumInts * IntSize))
throw new ArgumentOutOfRangeException("offset");
}
diff --git a/Source/OpenTK/Math/Matrix2.cs b/Source/OpenTK/Math/Matrix2.cs
new file mode 100644
index 00000000..0a0cb382
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2.cs
@@ -0,0 +1,764 @@
+#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 2x2 matrix
+ ///
+ public struct Matrix2 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2 Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2 Row1;
+
+ ///
+ /// The identity matrix.
+ ///
+ public static readonly Matrix2 Identity = new Matrix2(Vector2.UnitX, Vector2.UnitY);
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2 Zero = new Matrix2(Vector2.Zero, Vector2.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2(Vector2 row0, Vector2 row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// Constructs a new instance
+ ///
+ /// First item of the first row of the matrix.
+ /// Second 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.
+ public Matrix2(
+ float m00, float m01,
+ float m10, float m11)
+ {
+ Row0 = new Vector2(m00, m01);
+ Row1 = new Vector2(m10, m11);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets the determinant of this matrix.
+ ///
+ public float Determinant
+ {
+ get
+ {
+ float m11 = Row0.X, m12 = Row0.Y,
+ m21 = Row1.X, m22 = Row1.Y;
+
+ return m11 * m22 - m12 * m21;
+ }
+ }
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector2 Column0
+ {
+ get { return new Vector2(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector2 Column1
+ {
+ get { return new Vector2(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// 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 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2 Diagonal
+ {
+ get
+ {
+ return new Vector2(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Transpose()
+
+ ///
+ /// Converts this instance to it's transpose.
+ ///
+ public void Transpose()
+ {
+ this = Matrix2.Transpose(this);
+ }
+
+ #endregion
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix2.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2 instance.
+ public static void CreateRotation(float angle, out Matrix2 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2 instance.
+ public static Matrix2 CreateRotation(float angle)
+ {
+ Matrix2 result;
+ CreateRotation(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 void CreateScale(float scale, out Matrix2 result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2 CreateScale(float scale)
+ {
+ Matrix2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2 scale, out Matrix2 result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2 CreateScale(Vector2 scale)
+ {
+ Matrix2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(float x, float y, out Matrix2 result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2 CreateScale(float x, float y)
+ {
+ Matrix2 result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2 left, float right, out Matrix2 result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2 Mult(Matrix2 left, float right)
+ {
+ Matrix2 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2 left, ref Matrix2 right, out Matrix2 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2 Mult(Matrix2 left, Matrix2 right)
+ {
+ Matrix2 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2 left, ref Matrix2x3 right, out Matrix2x3 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3 Mult(Matrix2 left, Matrix2x3 right)
+ {
+ Matrix2x3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2 left, ref Matrix2x4 right, out Matrix2x4 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4 Mult(Matrix2 left, Matrix2x4 right)
+ {
+ Matrix2x4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2 left, ref Matrix2 right, out Matrix2 result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2 Add(Matrix2 left, Matrix2 right)
+ {
+ Matrix2 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2 left, ref Matrix2 right, out Matrix2 result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2 Subtract(Matrix2 left, Matrix2 right)
+ {
+ Matrix2 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #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 Matrix2 is singular.
+ public static void Invert(ref Matrix2 mat, out Matrix2 result)
+ {
+ float det = mat.Determinant;
+
+ if (det == 0)
+ throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
+
+ float invDet = 1f / det;
+
+ result.Row0.X = mat.Row1.Y * invDet;
+ result.Row0.Y = -mat.Row0.Y * invDet;
+ result.Row1.X = -mat.Row1.X * invDet;
+ result.Row1.Y = mat.Row0.X * invDet;
+ }
+
+ ///
+ /// 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 Matrix2 is singular.
+ public static Matrix2 Invert(Matrix2 mat)
+ {
+ Matrix2 result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2 mat, out Matrix2 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2 Transpose(Matrix2 mat)
+ {
+ Matrix2 result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix2 operator *(float left, Matrix2 right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix2 operator *(Matrix2 left, float right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix2 operator *(Matrix2 left, Matrix2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the multiplication
+ public static Matrix2x3 operator *(Matrix2 left, Matrix2x3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the multiplication
+ public static Matrix2x4 operator *(Matrix2 left, Matrix2x4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the addition
+ public static Matrix2 operator +(Matrix2 left, Matrix2 right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the subtraction
+ public static Matrix2 operator -(Matrix2 left, Matrix2 right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2 left, Matrix2 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2 left, Matrix2 right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #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 Matrix2))
+ return false;
+
+ return this.Equals((Matrix2)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix2d.cs b/Source/OpenTK/Math/Matrix2d.cs
new file mode 100644
index 00000000..999f105e
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2d.cs
@@ -0,0 +1,764 @@
+#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 2x2 matrix
+ ///
+ public struct Matrix2d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2d Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2d Row1;
+
+ ///
+ /// The identity matrix.
+ ///
+ public static readonly Matrix2d Identity = new Matrix2d(Vector2d.UnitX, Vector2d.UnitY);
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2d Zero = new Matrix2d(Vector2d.Zero, Vector2d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2d(Vector2d row0, Vector2d row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// Constructs a new instance
+ ///
+ /// First item of the first row of the matrix.
+ /// Second 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.
+ public Matrix2d(
+ double m00, double m01,
+ double m10, double m11)
+ {
+ Row0 = new Vector2d(m00, m01);
+ Row1 = new Vector2d(m10, m11);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets the determinant of this matrix.
+ ///
+ public double Determinant
+ {
+ get
+ {
+ double m11 = Row0.X, m12 = Row0.Y,
+ m21 = Row1.X, m22 = Row1.Y;
+
+ return m11 * m22 - m12 * m21;
+ }
+ }
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector2d Column0
+ {
+ get { return new Vector2d(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector2d Column1
+ {
+ get { return new Vector2d(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// 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 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2d Diagonal
+ {
+ get
+ {
+ return new Vector2d(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Transpose()
+
+ ///
+ /// Converts this instance to it's transpose.
+ ///
+ public void Transpose()
+ {
+ this = Matrix2d.Transpose(this);
+ }
+
+ #endregion
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix2d.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2d instance.
+ public static void CreateRotation(double angle, out Matrix2d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2d instance.
+ public static Matrix2d CreateRotation(double angle)
+ {
+ Matrix2d result;
+ CreateRotation(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 void CreateScale(double scale, out Matrix2d result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2d CreateScale(double scale)
+ {
+ Matrix2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2d scale, out Matrix2d result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2d CreateScale(Vector2d scale)
+ {
+ Matrix2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(double x, double y, out Matrix2d result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2d CreateScale(double x, double y)
+ {
+ Matrix2d result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2d left, double right, out Matrix2d result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2d Mult(Matrix2d left, double right)
+ {
+ Matrix2d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2d left, ref Matrix2d right, out Matrix2d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2d Mult(Matrix2d left, Matrix2d right)
+ {
+ Matrix2d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2d left, ref Matrix2x3d right, out Matrix2x3d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3d Mult(Matrix2d left, Matrix2x3d right)
+ {
+ Matrix2x3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2d left, ref Matrix2x4d right, out Matrix2x4d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4d Mult(Matrix2d left, Matrix2x4d right)
+ {
+ Matrix2x4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2d left, ref Matrix2d right, out Matrix2d result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2d Add(Matrix2d left, Matrix2d right)
+ {
+ Matrix2d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2d left, ref Matrix2d right, out Matrix2d result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2d Subtract(Matrix2d left, Matrix2d right)
+ {
+ Matrix2d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #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 Matrix2d is singular.
+ public static void Invert(ref Matrix2d mat, out Matrix2d result)
+ {
+ double det = mat.Determinant;
+
+ if (det == 0)
+ throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
+
+ double invDet = 1f / det;
+
+ result.Row0.X = mat.Row1.Y * invDet;
+ result.Row0.Y = -mat.Row0.Y * invDet;
+ result.Row1.X = -mat.Row1.X * invDet;
+ result.Row1.Y = mat.Row0.X * invDet;
+ }
+
+ ///
+ /// 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 Matrix2d is singular.
+ public static Matrix2d Invert(Matrix2d mat)
+ {
+ Matrix2d result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2d mat, out Matrix2d result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2d Transpose(Matrix2d mat)
+ {
+ Matrix2d result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix2d operator *(double left, Matrix2d right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix2d operator *(Matrix2d left, double right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix2d operator *(Matrix2d left, Matrix2d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the multiplication
+ public static Matrix2x3d operator *(Matrix2d left, Matrix2x3d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the multiplication
+ public static Matrix2x4d operator *(Matrix2d left, Matrix2x4d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the addition
+ public static Matrix2d operator +(Matrix2d left, Matrix2d right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the subtraction
+ public static Matrix2d operator -(Matrix2d left, Matrix2d right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2d left, Matrix2d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2d left, Matrix2d right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #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 Matrix2d))
+ return false;
+
+ return this.Equals((Matrix2d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix2x3.cs b/Source/OpenTK/Math/Matrix2x3.cs
new file mode 100644
index 00000000..bd2236ca
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2x3.cs
@@ -0,0 +1,724 @@
+#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.Collections.Generic;
+
+namespace OpenTK
+{
+ ///
+ /// Represents a 2x3 matrix.
+ ///
+ public struct Matrix2x3 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector3 Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector3 Row1;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2x3 Zero = new Matrix2x3(Vector3.Zero, Vector3.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2x3(Vector3 row0, Vector3 row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// 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.
+ public Matrix2x3(
+ float m00, float m01, float m02,
+ float m10, float m11, float m12)
+ {
+ Row0 = new Vector3(m00, m01, m02);
+ Row1 = new Vector3(m10, m11, m12);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector2 Column0
+ {
+ get { return new Vector2(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector2 Column1
+ {
+ get { return new Vector2(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the third column of this matrix.
+ ///
+ public Vector2 Column2
+ {
+ get { return new Vector2(Row0.Z, Row1.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; }
+ }
+
+ ///
+ /// 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2 Diagonal
+ {
+ get
+ {
+ return new Vector2(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3 instance.
+ public static void CreateRotation(float angle, out Matrix2x3 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3 instance.
+ public static Matrix2x3 CreateRotation(float angle)
+ {
+ Matrix2x3 result;
+ CreateRotation(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 void CreateScale(float scale, out Matrix2x3 result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x3 CreateScale(float scale)
+ {
+ Matrix2x3 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2 scale, out Matrix2x3 result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x3 CreateScale(Vector2 scale)
+ {
+ Matrix2x3 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(float x, float y, out Matrix2x3 result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2x3 CreateScale(float x, float y)
+ {
+ Matrix2x3 result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3 left, float right, out Matrix2x3 result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row0.Z = left.Row0.Z * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row1.Z = left.Row1.Z * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3 Mult(Matrix2x3 left, float right)
+ {
+ Matrix2x3 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3 left, ref Matrix3x2 right, out Matrix2 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,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y;
+
+ result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31);
+ result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32);
+ result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31);
+ result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2 Mult(Matrix2x3 left, Matrix3x2 right)
+ {
+ Matrix2 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3 left, ref Matrix3 right, out Matrix2x3 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,
+ 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);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3 Mult(Matrix2x3 left, Matrix3 right)
+ {
+ Matrix2x3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3 left, ref Matrix3x4 right, out Matrix2x4 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,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = ((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34);
+ 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.Row1.W = ((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4 Mult(Matrix2x3 left, Matrix3x4 right)
+ {
+ Matrix2x4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2x3 left, ref Matrix2x3 right, out Matrix2x3 result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row0.Z = left.Row0.Z + right.Row0.Z;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row1.Z = left.Row1.Z + right.Row1.Z;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2x3 Add(Matrix2x3 left, Matrix2x3 right)
+ {
+ Matrix2x3 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2x3 left, ref Matrix2x3 right, out Matrix2x3 result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row0.Z = left.Row0.Z - right.Row0.Z;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row1.Z = left.Row1.Z - right.Row1.Z;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2x3 Subtract(Matrix2x3 left, Matrix2x3 right)
+ {
+ Matrix2x3 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2x3 mat, out Matrix3x2 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row2.X = mat.Row0.Z;
+ result.Row2.Y = mat.Row1.Z;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix3x2 Transpose(Matrix2x3 mat)
+ {
+ Matrix3x2 result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the multiplication
+ public static Matrix2x3 operator *(float left, Matrix2x3 right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the multiplication
+ public static Matrix2x3 operator *(Matrix2x3 left, float right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix2 operator *(Matrix2x3 left, Matrix3x2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the multiplication
+ public static Matrix2x3 operator *(Matrix2x3 left, Matrix3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the multiplication
+ public static Matrix2x4 operator *(Matrix2x3 left, Matrix3x4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the addition
+ public static Matrix2x3 operator +(Matrix2x3 left, Matrix2x3 right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the subtraction
+ public static Matrix2x3 operator -(Matrix2x3 left, Matrix2x3 right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2x3 left, Matrix2x3 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2x3 left, Matrix2x3 right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix2x3.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #endregion
+
+ #region public override bool Equals(object obj)
+
+ ///
+ /// Indicates whether this instance and a specified object are equal.
+ ///
+ /// The object to compare tresult.
+ /// True if the instances are equal; false otherwise.
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Matrix2x3))
+ return false;
+
+ return this.Equals((Matrix2x3)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2x3 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix2x3d.cs b/Source/OpenTK/Math/Matrix2x3d.cs
new file mode 100644
index 00000000..30a59eb5
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2x3d.cs
@@ -0,0 +1,724 @@
+#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.Collections.Generic;
+
+namespace OpenTK
+{
+ ///
+ /// Represents a 2x3 matrix.
+ ///
+ public struct Matrix2x3d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector3d Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector3d Row1;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2x3d Zero = new Matrix2x3d(Vector3d.Zero, Vector3d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2x3d(Vector3d row0, Vector3d row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// 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.
+ public Matrix2x3d(
+ double m00, double m01, double m02,
+ double m10, double m11, double m12)
+ {
+ Row0 = new Vector3d(m00, m01, m02);
+ Row1 = new Vector3d(m10, m11, m12);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector2d Column0
+ {
+ get { return new Vector2d(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector2d Column1
+ {
+ get { return new Vector2d(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the third column of this matrix.
+ ///
+ public Vector2d Column2
+ {
+ get { return new Vector2d(Row0.Z, Row1.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; }
+ }
+
+ ///
+ /// 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2d Diagonal
+ {
+ get
+ {
+ return new Vector2d(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3d instance.
+ public static void CreateRotation(double angle, out Matrix2x3d result)
+ {
+ double cos = System.Math.Cos(angle);
+ double sin = System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3d instance.
+ public static Matrix2x3d CreateRotation(double angle)
+ {
+ Matrix2x3d result;
+ CreateRotation(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 void CreateScale(double scale, out Matrix2x3d result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x3d CreateScale(double scale)
+ {
+ Matrix2x3d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2d scale, out Matrix2x3d result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x3d CreateScale(Vector2d scale)
+ {
+ Matrix2x3d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(double x, double y, out Matrix2x3d result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2x3d CreateScale(double x, double y)
+ {
+ Matrix2x3d result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3d left, double right, out Matrix2x3d result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row0.Z = left.Row0.Z * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row1.Z = left.Row1.Z * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3d Mult(Matrix2x3d left, double right)
+ {
+ Matrix2x3d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3d left, ref Matrix3x2 right, out Matrix2d 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,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y;
+
+ result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31);
+ result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32);
+ result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31);
+ result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2d Mult(Matrix2x3d left, Matrix3x2 right)
+ {
+ Matrix2d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3d left, ref Matrix3 right, out Matrix2x3d 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,
+ 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);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3d Mult(Matrix2x3d left, Matrix3 right)
+ {
+ Matrix2x3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x3d left, ref Matrix3x4 right, out Matrix2x4d 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,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = ((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34);
+ 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.Row1.W = ((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4d Mult(Matrix2x3d left, Matrix3x4 right)
+ {
+ Matrix2x4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2x3d left, ref Matrix2x3d right, out Matrix2x3d result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row0.Z = left.Row0.Z + right.Row0.Z;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row1.Z = left.Row1.Z + right.Row1.Z;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2x3d Add(Matrix2x3d left, Matrix2x3d right)
+ {
+ Matrix2x3d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2x3d left, ref Matrix2x3d right, out Matrix2x3d result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row0.Z = left.Row0.Z - right.Row0.Z;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row1.Z = left.Row1.Z - right.Row1.Z;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2x3d Subtract(Matrix2x3d left, Matrix2x3d right)
+ {
+ Matrix2x3d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2x3d mat, out Matrix3x2d result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row2.X = mat.Row0.Z;
+ result.Row2.Y = mat.Row1.Z;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix3x2d Transpose(Matrix2x3d mat)
+ {
+ Matrix3x2d result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the multiplication
+ public static Matrix2x3d operator *(double left, Matrix2x3d right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the multiplication
+ public static Matrix2x3d operator *(Matrix2x3d left, double right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix2d operator *(Matrix2x3d left, Matrix3x2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the multiplication
+ public static Matrix2x3d operator *(Matrix2x3d left, Matrix3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the multiplication
+ public static Matrix2x4d operator *(Matrix2x3d left, Matrix3x4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the addition
+ public static Matrix2x3d operator +(Matrix2x3d left, Matrix2x3d right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the subtraction
+ public static Matrix2x3d operator -(Matrix2x3d left, Matrix2x3d right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2x3d left, Matrix2x3d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2x3d left, Matrix2x3d right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix2x3d.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #endregion
+
+ #region public override bool Equals(object obj)
+
+ ///
+ /// Indicates whether this instance and a specified object are equal.
+ ///
+ /// The object to compare tresult.
+ /// True if the instances are equal; false otherwise.
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Matrix2x3d))
+ return false;
+
+ return this.Equals((Matrix2x3d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2x3d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix2x4.cs b/Source/OpenTK/Math/Matrix2x4.cs
new file mode 100644
index 00000000..c3afecdb
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2x4.cs
@@ -0,0 +1,761 @@
+#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 2x4 matrix.
+ ///
+ public struct Matrix2x4 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector4 Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector4 Row1;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2x4 Zero = new Matrix2x4(Vector4.Zero, Vector4.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2x4(Vector4 row0, Vector4 row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// 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.
+ /// Fourth 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.
+ /// Fourth item of the second row of the matrix.
+ public Matrix2x4(
+ float m00, float m01, float m02, float m03,
+ float m10, float m11, float m12, float m13)
+ {
+ Row0 = new Vector4(m00, m01, m02, m03);
+ Row1 = new Vector4(m10, m11, m12, m13);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of the matrix.
+ ///
+ public Vector2 Column0
+ {
+ get { return new Vector2(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of the matrix.
+ ///
+ public Vector2 Column1
+ {
+ get { return new Vector2(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the third column of the matrix.
+ ///
+ public Vector2 Column2
+ {
+ get { return new Vector2(Row0.Z, Row1.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the fourth column of the matrix.
+ ///
+ public Vector2 Column3
+ {
+ get { return new Vector2(Row0.W, Row1.W); }
+ set { Row0.W = value.X; Row1.W = value.Y; }
+ }
+
+ ///
+ /// 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 1, column 4 of this instance.
+ ///
+ public float M14 { get { return Row0.W; } set { Row0.W = 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 2, column 4 of this instance.
+ ///
+ public float M24 { get { return Row1.W; } set { Row1.W = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector2 Diagonal
+ {
+ get
+ {
+ return new Vector2(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x4 instance.
+ public static void CreateRotation(float angle, out Matrix2x4 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3 instance.
+ public static Matrix2x4 CreateRotation(float angle)
+ {
+ Matrix2x4 result;
+ CreateRotation(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 void CreateScale(float scale, out Matrix2x4 result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x4 CreateScale(float scale)
+ {
+ Matrix2x4 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2 scale, out Matrix2x4 result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x4 CreateScale(Vector2 scale)
+ {
+ Matrix2x4 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(float x, float y, out Matrix2x4 result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2x4 CreateScale(float x, float y)
+ {
+ Matrix2x4 result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4 left, float right, out Matrix2x4 result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row0.Z = left.Row0.Z * right;
+ result.Row0.W = left.Row0.W * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row1.Z = left.Row1.Z * right;
+ result.Row1.W = left.Row1.W * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4 Mult(Matrix2x4 left, float right)
+ {
+ Matrix2x4 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4 left, ref Matrix4x2 right, out Matrix2 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2 Mult(Matrix2x4 left, Matrix4x2 right)
+ {
+ Matrix2 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4 left, ref Matrix4x3 right, out Matrix2x3 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ 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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3 Mult(Matrix2x4 left, Matrix4x3 right)
+ {
+ Matrix2x3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4 left, ref Matrix4 right, out Matrix2x4 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43);
+ result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43);
+ result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4 Mult(Matrix2x4 left, Matrix4 right)
+ {
+ Matrix2x4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2x4 left, ref Matrix2x4 right, out Matrix2x4 result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row0.Z = left.Row0.Z + right.Row0.Z;
+ result.Row0.W = left.Row0.W + right.Row0.W;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row1.Z = left.Row1.Z + right.Row1.Z;
+ result.Row1.W = left.Row1.W + right.Row1.W;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2x4 Add(Matrix2x4 left, Matrix2x4 right)
+ {
+ Matrix2x4 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2x4 left, ref Matrix2x4 right, out Matrix2x4 result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row0.Z = left.Row0.Z - right.Row0.Z;
+ result.Row0.W = left.Row0.W - right.Row0.W;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row1.Z = left.Row1.Z - right.Row1.Z;
+ result.Row1.W = left.Row1.W - right.Row1.W;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2x4 Subtract(Matrix2x4 left, Matrix2x4 right)
+ {
+ Matrix2x4 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2x4 mat, out Matrix4x2 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row2.X = mat.Row0.Z;
+ result.Row2.Y = mat.Row1.Z;
+ result.Row3.X = mat.Row0.W;
+ result.Row3.Y = mat.Row1.W;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix4x2 Transpose(Matrix2x4 mat)
+ {
+ Matrix4x2 result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the multiplication
+ public static Matrix2x4 operator *(float left, Matrix2x4 right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the multiplication
+ public static Matrix2x4 operator *(Matrix2x4 left, float right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix2 operator *(Matrix2x4 left, Matrix4x2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3 which holds the result of the multiplication
+ public static Matrix2x3 operator *(Matrix2x4 left, Matrix4x3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the multiplication
+ public static Matrix2x4 operator *(Matrix2x4 left, Matrix4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the addition
+ public static Matrix2x4 operator +(Matrix2x4 left, Matrix2x4 right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4 which holds the result of the subtraction
+ public static Matrix2x4 operator -(Matrix2x4 left, Matrix2x4 right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2x4 left, Matrix2x4 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2x4 left, Matrix2x4 right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #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 Matrix2x4))
+ return false;
+
+ return this.Equals((Matrix2x4)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2x4 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix2x4d.cs b/Source/OpenTK/Math/Matrix2x4d.cs
new file mode 100644
index 00000000..deb2b1cb
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix2x4d.cs
@@ -0,0 +1,761 @@
+#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 2x4 matrix.
+ ///
+ public struct Matrix2x4d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector4d Row0;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector4d Row1;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix2x4d Zero = new Matrix2x4d(Vector4d.Zero, Vector4d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix2x4d(Vector4d row0, Vector4d row1)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ }
+
+ ///
+ /// 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.
+ /// Fourth 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.
+ /// Fourth item of the second row of the matrix.
+ public Matrix2x4d(
+ double m00, double m01, double m02, double m03,
+ double m10, double m11, double m12, double m13)
+ {
+ Row0 = new Vector4d(m00, m01, m02, m03);
+ Row1 = new Vector4d(m10, m11, m12, m13);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of the matrix.
+ ///
+ public Vector2d Column0
+ {
+ get { return new Vector2d(Row0.X, Row1.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the second column of the matrix.
+ ///
+ public Vector2d Column1
+ {
+ get { return new Vector2d(Row0.Y, Row1.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the third column of the matrix.
+ ///
+ public Vector2d Column2
+ {
+ get { return new Vector2d(Row0.Z, Row1.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; }
+ }
+
+ ///
+ /// Gets or sets the fourth column of the matrix.
+ ///
+ public Vector2d Column3
+ {
+ get { return new Vector2d(Row0.W, Row1.W); }
+ set { Row0.W = value.X; Row1.W = value.Y; }
+ }
+
+ ///
+ /// 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 1, column 4 of this instance.
+ ///
+ public double M14 { get { return Row0.W; } set { Row0.W = 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 2, column 4 of this instance.
+ ///
+ public double M24 { get { return Row1.W; } set { Row1.W = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector2d Diagonal
+ {
+ get
+ {
+ return new Vector2d(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x4d instance.
+ public static void CreateRotation(double angle, out Matrix2x4d result)
+ {
+ double cos = System.Math.Cos(angle);
+ double sin = System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix2x3d instance.
+ public static Matrix2x4d CreateRotation(double angle)
+ {
+ Matrix2x4d result;
+ CreateRotation(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 void CreateScale(double scale, out Matrix2x4d result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x4d CreateScale(double scale)
+ {
+ Matrix2x4d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2d scale, out Matrix2x4d result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix2x4d CreateScale(Vector2d scale)
+ {
+ Matrix2x4d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(double x, double y, out Matrix2x4d result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix2x4d CreateScale(double x, double y)
+ {
+ Matrix2x4d result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4d left, double right, out Matrix2x4d result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row0.Z = left.Row0.Z * right;
+ result.Row0.W = left.Row0.W * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row1.Z = left.Row1.Z * right;
+ result.Row1.W = left.Row1.W * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4d Mult(Matrix2x4d left, double right)
+ {
+ Matrix2x4d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4d left, ref Matrix4x2 right, out Matrix2d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2d Mult(Matrix2x4d left, Matrix4x2 right)
+ {
+ Matrix2d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4d left, ref Matrix4x3 right, out Matrix2x3d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ 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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x3d Mult(Matrix2x4d left, Matrix4x3 right)
+ {
+ Matrix2x3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix2x4d left, ref Matrix4 right, out Matrix2x4d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W;
+
+ result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41);
+ result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42);
+ result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43);
+ result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44);
+ result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41);
+ result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42);
+ result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43);
+ result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix2x4d Mult(Matrix2x4d left, Matrix4 right)
+ {
+ Matrix2x4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix2x4d left, ref Matrix2x4d right, out Matrix2x4d result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row0.Z = left.Row0.Z + right.Row0.Z;
+ result.Row0.W = left.Row0.W + right.Row0.W;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row1.Z = left.Row1.Z + right.Row1.Z;
+ result.Row1.W = left.Row1.W + right.Row1.W;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix2x4d Add(Matrix2x4d left, Matrix2x4d right)
+ {
+ Matrix2x4d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix2x4d left, ref Matrix2x4d right, out Matrix2x4d result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row0.Z = left.Row0.Z - right.Row0.Z;
+ result.Row0.W = left.Row0.W - right.Row0.W;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row1.Z = left.Row1.Z - right.Row1.Z;
+ result.Row1.W = left.Row1.W - right.Row1.W;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix2x4d Subtract(Matrix2x4d left, Matrix2x4d right)
+ {
+ Matrix2x4d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix2x4d mat, out Matrix4x2d result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row2.X = mat.Row0.Z;
+ result.Row2.Y = mat.Row1.Z;
+ result.Row3.X = mat.Row0.W;
+ result.Row3.Y = mat.Row1.W;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix4x2d Transpose(Matrix2x4d mat)
+ {
+ Matrix4x2d result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the multiplication
+ public static Matrix2x4d operator *(double left, Matrix2x4d right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the multiplication
+ public static Matrix2x4d operator *(Matrix2x4d left, double right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix2d operator *(Matrix2x4d left, Matrix4x2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x3d which holds the result of the multiplication
+ public static Matrix2x3d operator *(Matrix2x4d left, Matrix4x3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the multiplication
+ public static Matrix2x4d operator *(Matrix2x4d left, Matrix4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the addition
+ public static Matrix2x4d operator +(Matrix2x4d left, Matrix2x4d right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2x4d which holds the result of the subtraction
+ public static Matrix2x4d operator -(Matrix2x4d left, Matrix2x4d right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix2x4d left, Matrix2x4d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix2x4d left, Matrix2x4d right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// The string representation of the matrix.
+ public override string ToString()
+ {
+ return String.Format("{0}\n{1}", Row0, Row1);
+ }
+
+ #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();
+ }
+
+ #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 Matrix2x4d))
+ return false;
+
+ return this.Equals((Matrix2x4d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix2x4d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix3.cs b/Source/OpenTK/Math/Matrix3.cs
new file mode 100644
index 00000000..cd2f3bc7
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix3.cs
@@ -0,0 +1,974 @@
+#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 containing 3D rotation and scale.
+ ///
+ [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 readonly Matrix3 Identity = new Matrix3(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ);
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix3 Zero = new Matrix3(Vector3.Zero, Vector3.Zero, Vector3.Zero);
+
+ #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);
+ }
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// A Matrix4 to take the upper-left 3x3 from.
+ public Matrix3(Matrix4 matrix)
+ {
+ Row0 = matrix.Row0.Xyz;
+ Row1 = matrix.Row1.Xyz;
+ Row2 = matrix.Row2.Xyz;
+ }
+
+ #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; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3 Diagonal
+ {
+ get
+ {
+ return new Vector3(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix3.Invert(this);
+ }
+
+ #endregion
+
+ #region public void Transpose()
+
+ ///
+ /// Converts this instance into its transpose.
+ ///
+ public void Transpose()
+ {
+ this = Matrix3.Transpose(this);
+ }
+
+ #endregion
+
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix3 Normalized()
+ {
+ Matrix3 m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix3 Inverted()
+ {
+ Matrix3 m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns a copy of this Matrix3 without scale.
+ ///
+ public Matrix3 ClearScale()
+ {
+ Matrix3 m = this;
+ m.Row0 = m.Row0.Normalized();
+ m.Row1 = m.Row1.Normalized();
+ m.Row2 = m.Row2.Normalized();
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix3 without rotation.
+ ///
+ public Matrix3 ClearRotation()
+ {
+ Matrix3 m = this;
+ m.Row0 = new Vector3(m.Row0.Length, 0, 0);
+ m.Row1 = new Vector3(0, m.Row1.Length, 0);
+ m.Row2 = new Vector3(0, 0, m.Row2.Length);
+ return m;
+ }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3 ExtractScale() { return new Vector3(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaternion ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0;
+ var row1 = Row1;
+ var row2 = Row2;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaternion q = new Quaternion();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ 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);
+ }
+
+ q.Normalize();
+ return q;
+ }
+
+ #endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ 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;
+ }
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix3 CreateFromAxisAngle(Vector3 axis, float angle)
+ {
+ Matrix3 result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateFromQuaternion
+
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// Matrix result.
+ 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);
+ }
+
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// A matrix instance.
+ public static Matrix3 CreateFromQuaternion(Quaternion q)
+ {
+ Matrix3 result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateRotation[XYZ]
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ 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;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ public static Matrix3 CreateRotationX(float angle)
+ {
+ Matrix3 result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ 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;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ public static Matrix3 CreateRotationY(float angle)
+ {
+ Matrix3 result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ 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;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3 instance.
+ 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
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3 Mult(Matrix3 left, Matrix3 right)
+ {
+ Matrix3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ 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
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix3 Transpose(Matrix3 mat)
+ {
+ return new Matrix3(mat.Column0, mat.Column1, mat.Column2);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ public static void Transpose(ref Matrix3 mat, out Matrix3 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row0.Z = mat.Row2.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row1.Z = mat.Row2.Y;
+ result.Row2.X = mat.Row0.Z;
+ result.Row2.Y = mat.Row1.Z;
+ result.Row2.Z = mat.Row2.Z;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3d which holds the result of the multiplication
+ public static Matrix3 operator *(Matrix3 left, Matrix3 right)
+ {
+ return Matrix3.Mult(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3 left, Matrix3 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ 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
+
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// A matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ 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..757c36ca 100644
--- a/Source/OpenTK/Math/Matrix3d.cs
+++ b/Source/OpenTK/Math/Matrix3d.cs
@@ -27,802 +27,939 @@ 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 containing 3D rotation and scale with double-precision components.
+ ///
[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
- };
- }
-
+ #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 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)
+ {
+ Row0 = new Vector3d(m00, m01, m02);
+ Row1 = new Vector3d(m10, m11, m12);
+ Row2 = new Vector3d(m20, m21, m22);
}
- /// 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.
+ ///
+ /// A Matrix4d to take the upper-left 3x3 from.
+ public Matrix3d(Matrix4d matrix)
{
- 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;
- }
-
- /// 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);
+ Row0 = matrix.Row0.Xyz;
+ Row1 = matrix.Row1.Xyz;
+ Row2 = matrix.Row2.Xyz;
}
#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
-
+
+ #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; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3d Diagonal
+ {
+ get
+ {
+ return new Vector3d(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
}
}
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix3d.Invert(this);
+ }
+
+ #endregion
+
+ #region public void Transpose()
+
+ ///
+ /// Converts this instance into its 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
+
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix3d Normalized()
{
- 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;
+ Matrix3d m = this;
+ m.Normalize();
+ return m;
}
- public static void Transpose(ref Matrix3d matrix, out Matrix3d result)
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
{
- 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;
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix3d Inverted()
+ {
+ Matrix3d m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+
+ ///
+ /// Returns a copy of this Matrix3 without scale.
+ ///
+ public Matrix3d ClearScale()
+ {
+ Matrix3d m = this;
+ m.Row0 = m.Row0.Normalized();
+ m.Row1 = m.Row1.Normalized();
+ m.Row2 = m.Row2.Normalized();
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix3 without rotation.
+ ///
+ public Matrix3d ClearRotation()
+ {
+ Matrix3d m = this;
+ m.Row0 = new Vector3d(m.Row0.Length, 0, 0);
+ m.Row1 = new Vector3d(0, m.Row1.Length, 0);
+ m.Row2 = new Vector3d(0, 0, m.Row2.Length);
+ return m;
+ }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3d ExtractScale() { return new Vector3d(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaterniond ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0;
+ var row1 = Row1;
+ var row2 = Row2;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaterniond q = new Quaterniond();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (row1[2] - row2[1]) * sq;
+ q.Y = (row2[0] - row0[2]) * sq;
+ q.Z = (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 = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[1] - row1[2]) * sq;
+ q.Y = (row1[0] + row0[1]) * sq;
+ q.Z = (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 = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[0] - row0[2]) * sq;
+ q.X = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[1] + row1[2]) * sq;
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row1[0] - row0[1]) * sq;
+ q.X = (row2[0] + row0[2]) * sq;
+ q.Y = (row2[1] + row1[2]) * sq;
+ }
+
+ q.Normalize();
+ return q;
}
#endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
- #region Transformation Functions
-
- public void Transform(ref Vector3d vector)
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static void CreateFromAxisAngle(Vector3d axis, double angle, 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;
- }
- public static void Transform(ref Matrix3d matrix, ref Vector3d vector)
- {
- 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;
- }
- public void Transform(ref Vector3d vector, out Vector3d 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;
- }
- public static void Transform(ref Matrix3d matrix, ref Vector3d vector, out Vector3d result)
- {
- 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;
+ //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 void Rotate(double angle)
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix3d CreateFromAxisAngle(Vector3d axis, double angle)
{
- 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;
+ Matrix3d result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
}
- public void Rotate(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 * 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;
- }
- public static void Rotate(ref Matrix3d matrix, 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;
- }
- public static void RotateMatrix(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;
- result.R0C1 = sin;
- result.R0C2 = 0;
- result.R1C0 = -sin;
- result.R1C1 = cos;
- result.R1C2 = 0;
- result.R2C0 = 0;
- result.R2C1 = 0;
- result.R2C2 = 1;
- }
-
- public Quaterniond ToQuaternion()
- {
- //return new Quaterniond(ref this);
- }
-
+
#endregion
+
+ #region CreateFromQuaternion
- #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()
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// Matrix result.
+ public static void CreateFromQuaternion(ref Quaterniond q, out Matrix3d result)
{
- return
- R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^
- R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^
- R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode();
+ Vector3d axis;
+ double angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);
}
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// A matrix instance.
+ public static Matrix3d CreateFromQuaternion(Quaterniond q)
+ {
+ Matrix3d result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
#endregion
+
+ #region CreateRotation[XYZ]
- #region String
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static void CreateRotationX(double angle, out Matrix3d result)
+ {
+ 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;
+ }
- /// Returns the fully qualified type name of this instance.
- /// A System.String containing left fully qualified type name.
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static Matrix3d CreateRotationX(double angle)
+ {
+ Matrix3d result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static void CreateRotationY(double angle, out Matrix3d result)
+ {
+ 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;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static Matrix3d CreateRotationY(double angle)
+ {
+ Matrix3d result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static void CreateRotationZ(double angle, out Matrix3d result)
+ {
+ 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;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3d instance.
+ public static Matrix3d CreateRotationZ(double angle)
+ {
+ Matrix3d 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 Matrix3d CreateScale(double scale)
+ {
+ Matrix3d 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 Matrix3d CreateScale(Vector3d scale)
+ {
+ Matrix3d 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 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
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3d Mult(Matrix3d left, Matrix3d right)
+ {
+ Matrix3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ 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
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix3d Transpose(Matrix3d mat)
+ {
+ return new Matrix3d(mat.Column0, mat.Column1, mat.Column2);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ 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
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3d which holds the result of the multiplication
+ public static Matrix3d operator *(Matrix3d left, Matrix3d right)
+ {
+ return Matrix3d.Mult(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3d left, Matrix3d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ 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
+
+ #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
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// A matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix3d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2;
+ }
+
#endregion
}
-#endif
- #pragma warning restore 3019
}
diff --git a/Source/OpenTK/Math/Matrix3x2.cs b/Source/OpenTK/Math/Matrix3x2.cs
new file mode 100644
index 00000000..639f093a
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix3x2.cs
@@ -0,0 +1,736 @@
+#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 3x2 matrix.
+ ///
+ public struct Matrix3x2 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2 Row0;
+
+ ///
+ /// Second row of the matrix.
+ ///
+ public Vector2 Row1;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2 Row2;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix3x2 Zero = new Matrix3x2(Vector2.Zero, Vector2.Zero, Vector2.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Second row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix3x2(Vector2 row0, Vector2 row1, Vector2 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.
+ /// First item of the second row of the matrix.
+ /// Second 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.
+ public Matrix3x2(
+ float m00, float m01,
+ float m10, float m11,
+ float m20, float m21)
+ {
+ Row0 = new Vector2(m00, m01);
+ Row1 = new Vector2(m10, m11);
+ Row2 = new Vector2(m20, m21);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector3 Column0
+ {
+ get { return new Vector3(Row0.X, Row1.X, Row2.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector3 Column1
+ {
+ get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.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 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 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2 Diagonal
+ {
+ get
+ {
+ return new Vector2(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static void CreateRotation(float angle, out Matrix3x2 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static Matrix3x2 CreateRotation(float angle)
+ {
+ Matrix3x2 result;
+ CreateRotation(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 void CreateScale(float scale, out Matrix3x2 result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix3x2 CreateScale(float scale)
+ {
+ Matrix3x2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2 scale, out Matrix3x2 result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix3x2 CreateScale(Vector2 scale)
+ {
+ Matrix3x2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(float x, float y, out Matrix3x2 result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix3x2 CreateScale(float x, float y)
+ {
+ Matrix3x2 result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2 left, float right, out Matrix3x2 result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row2.X = left.Row2.X * right;
+ result.Row2.Y = left.Row2.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x2 Mult(Matrix3x2 left, float right)
+ {
+ Matrix3x2 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2 left, ref Matrix2 right, out Matrix3x2 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x2 Mult(Matrix3x2 left, Matrix2 right)
+ {
+ Matrix3x2 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2 left, ref Matrix2x3 right, out Matrix3 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3 Mult(Matrix3x2 left, Matrix2x3 right)
+ {
+ Matrix3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2 left, ref Matrix2x4 right, out Matrix3x4 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x4 Mult(Matrix3x2 left, Matrix2x4 right)
+ {
+ Matrix3x4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row2.X = left.Row2.X + right.Row2.X;
+ result.Row2.Y = left.Row2.Y + right.Row2.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix3x2 Add(Matrix3x2 left, Matrix3x2 right)
+ {
+ Matrix3x2 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row2.X = left.Row2.X - right.Row2.X;
+ result.Row2.Y = left.Row2.Y - right.Row2.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix3x2 Subtract(Matrix3x2 left, Matrix3x2 right)
+ {
+ Matrix3x2 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix3x2 mat, out Matrix2x3 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row0.Z = mat.Row2.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row1.Z = mat.Row2.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2x3 Transpose(Matrix3x2 mat)
+ {
+ Matrix2x3 result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2 which holds the result of the multiplication
+ public static Matrix3x2 operator *(float left, Matrix3x2 right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2 which holds the result of the multiplication
+ public static Matrix3x2 operator *(Matrix3x2 left, float right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2 which holds the result of the multiplication
+ public static Matrix3x2 operator *(Matrix3x2 left, Matrix2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3 which holds the result of the multiplication
+ public static Matrix3 operator *(Matrix3x2 left, Matrix2x3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the multiplication
+ public static Matrix3x4 operator *(Matrix3x2 left, Matrix2x4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2 which holds the result of the addition
+ public static Matrix3x2 operator +(Matrix3x2 left, Matrix3x2 right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2 which holds the result of the subtraction
+ public static Matrix3x2 operator -(Matrix3x2 left, Matrix3x2 right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3x2 left, Matrix3x2 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix3x2 left, Matrix3x2 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 Matrix3x2))
+ return false;
+
+ return this.Equals((Matrix3x2)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix3x2 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix3x2d.cs b/Source/OpenTK/Math/Matrix3x2d.cs
new file mode 100644
index 00000000..8f1804e9
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix3x2d.cs
@@ -0,0 +1,736 @@
+#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 3x2 matrix.
+ ///
+ public struct Matrix3x2d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2d Row0;
+
+ ///
+ /// Second row of the matrix.
+ ///
+ public Vector2d Row1;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2d Row2;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix3x2d Zero = new Matrix3x2d(Vector2d.Zero, Vector2d.Zero, Vector2d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Second row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix3x2d(Vector2d row0, Vector2d row1, Vector2d 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.
+ /// First item of the second row of the matrix.
+ /// Second 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.
+ public Matrix3x2d(
+ double m00, double m01,
+ double m10, double m11,
+ double m20, double m21)
+ {
+ Row0 = new Vector2d(m00, m01);
+ Row1 = new Vector2d(m10, m11);
+ Row2 = new Vector2d(m20, m21);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector3d Column0
+ {
+ get { return new Vector3d(Row0.X, Row1.X, Row2.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector3d Column1
+ {
+ get { return new Vector3d(Row0.Y, Row1.Y, Row2.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.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 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 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 values along the main diagonal of the matrix.
+ ///
+ public Vector2d Diagonal
+ {
+ get
+ {
+ return new Vector2d(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2d instance.
+ public static void CreateRotation(double angle, out Matrix3x2d result)
+ {
+ double cos = System.Math.Cos(angle);
+ double sin = System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2d instance.
+ public static Matrix3x2d CreateRotation(double angle)
+ {
+ Matrix3x2d result;
+ CreateRotation(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 void CreateScale(double scale, out Matrix3x2d result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix3x2d CreateScale(double scale)
+ {
+ Matrix3x2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2d scale, out Matrix3x2d result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix3x2d CreateScale(Vector2d scale)
+ {
+ Matrix3x2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(double x, double y, out Matrix3x2d result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix3x2d CreateScale(double x, double y)
+ {
+ Matrix3x2d result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2d left, double right, out Matrix3x2d result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row2.X = left.Row2.X * right;
+ result.Row2.Y = left.Row2.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x2d Mult(Matrix3x2d left, double right)
+ {
+ Matrix3x2d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2d left, ref Matrix2d right, out Matrix3x2d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x2d Mult(Matrix3x2d left, Matrix2d right)
+ {
+ Matrix3x2d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2d left, ref Matrix2x3d right, out Matrix3d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3d Mult(Matrix3x2d left, Matrix2x3d right)
+ {
+ Matrix3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix3x2d left, ref Matrix2x4d right, out Matrix3x4d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix3x4d Mult(Matrix3x2d left, Matrix2x4d right)
+ {
+ Matrix3x4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix3x2d left, ref Matrix3x2d right, out Matrix3x2d result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row2.X = left.Row2.X + right.Row2.X;
+ result.Row2.Y = left.Row2.Y + right.Row2.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix3x2d Add(Matrix3x2d left, Matrix3x2d right)
+ {
+ Matrix3x2d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix3x2d left, ref Matrix3x2d right, out Matrix3x2d result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row2.X = left.Row2.X - right.Row2.X;
+ result.Row2.Y = left.Row2.Y - right.Row2.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix3x2d Subtract(Matrix3x2d left, Matrix3x2d right)
+ {
+ Matrix3x2d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix3x2d mat, out Matrix2x3d result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row0.Z = mat.Row2.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row1.Z = mat.Row2.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2x3d Transpose(Matrix3x2d mat)
+ {
+ Matrix2x3d result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2d which holds the result of the multiplication
+ public static Matrix3x2d operator *(double left, Matrix3x2d right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2d which holds the result of the multiplication
+ public static Matrix3x2d operator *(Matrix3x2d left, double right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2d which holds the result of the multiplication
+ public static Matrix3x2d operator *(Matrix3x2d left, Matrix2d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3d which holds the result of the multiplication
+ public static Matrix3d operator *(Matrix3x2d left, Matrix2x3d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the multiplication
+ public static Matrix3x4d operator *(Matrix3x2d left, Matrix2x4d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2d which holds the result of the addition
+ public static Matrix3x2d operator +(Matrix3x2d left, Matrix3x2d right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x2d which holds the result of the subtraction
+ public static Matrix3x2d operator -(Matrix3x2d left, Matrix3x2d right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3x2d left, Matrix3x2d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix3x2d left, Matrix3x2d 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 Matrix3x2d))
+ return false;
+
+ return this.Equals((Matrix3x2d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix3x2d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix3x4.cs b/Source/OpenTK/Math/Matrix3x4.cs
new file mode 100644
index 00000000..7d251d57
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix3x4.cs
@@ -0,0 +1,1000 @@
+#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 3x4 Matrix
+ ///
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Matrix3x4 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix
+ ///
+ public Vector4 Row0;
+
+ ///
+ /// 2nd row of the matrix
+ ///
+ public Vector4 Row1;
+
+ ///
+ /// Bottom row of the matrix
+ ///
+ public Vector4 Row2;
+
+ ///
+ /// The zero matrix
+ ///
+ public static Matrix3x4 Zero = new Matrix3x4(Vector4.Zero, Vector4.Zero, Vector4.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix
+ /// Second row of the matrix
+ /// Bottom row of the matrix
+ public Matrix3x4(Vector4 row0, Vector4 row1, Vector4 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.
+ /// Fourth 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.
+ /// Fourth 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.
+ /// First item of the third row of the matrix.
+ public Matrix3x4(
+ float m00, float m01, float m02, float m03,
+ float m10, float m11, float m12, float m13,
+ float m20, float m21, float m22, float m23)
+ {
+ Row0 = new Vector4(m00, m01, m02, m03);
+ Row1 = new Vector4(m10, m11, m12, m13);
+ Row2 = new Vector4(m20, m21, m22, m23);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// 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 the fourth column of this matrix.
+ ///
+ public Vector3 Column3
+ {
+ get { return new Vector3(Row0.W, Row1.W, Row2.W); }
+ }
+
+ ///
+ /// 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 1, column 4 of this instance.
+ ///
+ public float M14 { get { return Row0.W; } set { Row0.W = 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 2, column 4 of this instance.
+ ///
+ public float M24 { get { return Row1.W; } set { Row1.W = 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; } }
+
+ ///
+ /// Gets or sets the value at row 3, column 4 of this instance.
+ ///
+ public float M34 { get { return Row2.W; } set { Row2.W = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3 Diagonal
+ {
+ get
+ {
+ return new Vector3(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix3x4.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3x4 result)
+ {
+ axis.Normalize();
+ float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z;
+
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+ float t = 1.0f - cos;
+
+ 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.Row0.W = 0;
+ result.Row1.X = tXY + sinZ;
+ result.Row1.Y = tYY + cos;
+ result.Row1.Z = tYZ - sinX;
+ result.Row1.W = 0;
+ result.Row2.X = tXZ - sinY;
+ result.Row2.Y = tYZ + sinX;
+ result.Row2.Z = tZZ + cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix3x4 CreateFromAxisAngle(Vector3 axis, float angle)
+ {
+ Matrix3x4 result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateFromQuaternion
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static void CreateFromQuaternion(ref Quaternion q, out Matrix3x4 result)
+ {
+ float x = q.X, y = q.Y, z = q.Z, w = q.W,
+ tx = 2 * x, ty = 2 * y, tz = 2 * z,
+ txx = tx * x, tyy = ty * y, tzz = tz * z,
+ txy = tx * y, txz = tx * z, tyz = ty * z,
+ txw = tx * w, tyw = ty * w, tzw = tz * w;
+
+ result.Row0.X = 1f - (tyy + tzz);
+ result.Row0.Y = txy + tzw;
+ result.Row0.Z = txz - tyw;
+ result.Row0.W = 0f;
+ result.Row1.X = txy - tzw;
+ result.Row1.Y = 1f - (txx + tzz);
+ result.Row1.Z = tyz + txw;
+ result.Row1.W = 0f;
+ result.Row2.X = txz + tyw;
+ result.Row2.Y = tyz - txw;
+ result.Row2.Z = 1f - (txx + tyy);
+ result.Row2.W = 0f;
+
+ /*Vector3 axis;
+ float angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);*/
+ }
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static Matrix3x4 CreateFromQuaternion(Quaternion q)
+ {
+ Matrix3x4 result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateRotation[XYZ]
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationX(float angle, out Matrix3x4 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = cos;
+ result.Row1.Z = sin;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = -sin;
+ result.Row2.Z = cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4 CreateRotationX(float angle)
+ {
+ Matrix3x4 result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationY(float angle, out Matrix3x4 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = 0;
+ result.Row0.Z = -sin;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = sin;
+ result.Row2.Y = 0;
+ result.Row2.Z = cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4 CreateRotationY(float angle)
+ {
+ Matrix3x4 result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationZ(float angle, out Matrix3x4 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4 CreateRotationZ(float angle)
+ {
+ Matrix3x4 result;
+ CreateRotationZ(angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateTranslation
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(float x, float y, float z, out Matrix3x4 result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = x;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(ref Vector3 vector, out Matrix3x4 result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = vector.X;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = vector.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = vector.Z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4 CreateTranslation(float x, float y, float z)
+ {
+ Matrix3x4 result;
+ CreateTranslation(x, y, z, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4 CreateTranslation(Vector3 vector)
+ {
+ Matrix3x4 result;
+ CreateTranslation(vector.X, vector.Y, vector.Z, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateScale
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Single scale factor for x,y and z axes
+ /// A scaling matrix
+ public static Matrix3x4 CreateScale(float scale)
+ {
+ return CreateScale(scale, scale, scale);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factors for x,y and z axes
+ /// A scaling matrix
+ public static Matrix3x4 CreateScale(Vector3 scale)
+ {
+ return CreateScale(scale.X, scale.Y, scale.Z);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factor for x-axis
+ /// Scale factor for y-axis
+ /// Scale factor for z-axis
+ /// A scaling matrix
+ public static Matrix3x4 CreateScale(float x, float y, float z)
+ {
+ Matrix3x4 result;
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = z;
+ result.Row2.W = 0;
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3 Mult(Matrix3x4 left, Matrix4x3 right)
+ {
+ Matrix3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4 left, ref Matrix4x3 right, out Matrix3 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W,
+ 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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + (lM14 * rM41);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + (lM14 * rM42);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + (lM14 * rM43);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + (lM24 * rM41);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + (lM24 * rM42);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + (lM24 * rM43);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + (lM34 * rM41);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + (lM34 * rM42);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + (lM34 * rM43);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3x4 Mult(Matrix3x4 left, Matrix3x4 right)
+ {
+ Matrix3x4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34) + lM14;
+ 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.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34) + lM24;
+ 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);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34) + lM34;
+
+ /*result.Row0 = (right.Row0 * lM11 + right.Row1 * lM12 + right.Row2 * lM13);
+ result.Row0.W += lM14;
+
+ result.Row1 = (right.Row0 * lM21 + right.Row1 * lM22 + right.Row2 * lM23);
+ result.Row1.W += lM24;
+
+ result.Row2 = (right.Row0 * lM31 + right.Row1 * lM32 + right.Row2 * lM33);
+ result.Row2.W += lM34;*/
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3x4 Mult(Matrix3x4 left, float right)
+ {
+ Matrix3x4 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4 left, float right, out Matrix3x4 result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ }
+
+ #endregion
+
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix3x4 Add(Matrix3x4 left, Matrix3x4 right)
+ {
+ Matrix3x4 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix3x4 Subtract(Matrix3x4 left, Matrix3x4 right)
+ {
+ Matrix3x4 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ }
+
+ #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 Matrix4 is singular.
+ public static Matrix3x4 Invert(Matrix3x4 mat)
+ {
+ Matrix3x4 result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ ///
+ /// 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 void Invert(ref Matrix3x4 mat, out Matrix3x4 result)
+ {
+ Matrix3 inverseRotation = new Matrix3(mat.Column0, mat.Column1, mat.Column2);
+ inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared;
+ inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared;
+ inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared;
+
+ Vector3 translation = new Vector3(mat.Row0.W, mat.Row1.W, mat.Row2.W);
+
+ result.Row0 = new Vector4(inverseRotation.Row0, -Vector3.Dot(inverseRotation.Row0, translation));
+ result.Row1 = new Vector4(inverseRotation.Row1, -Vector3.Dot(inverseRotation.Row1, translation));
+ result.Row2 = new Vector4(inverseRotation.Row2, -Vector3.Dot(inverseRotation.Row2, translation));
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix4x3 Transpose(Matrix3x4 mat)
+ {
+ return new Matrix4x3(mat.Column0, mat.Column1, mat.Column2, mat.Column3);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ public static void Transpose(ref Matrix3x4 mat, out Matrix4x3 result)
+ {
+ result.Row0 = mat.Column0;
+ result.Row1 = mat.Column1;
+ result.Row2 = mat.Column2;
+ result.Row3 = mat.Column3;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3 which holds the result of the multiplication
+ public static Matrix3 operator *(Matrix3x4 left, Matrix4x3 right)
+ {
+ return Matrix3x4.Mult(left, right);
+ }
+
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the multiplication
+ public static Matrix3x4 operator *(Matrix3x4 left, Matrix3x4 right)
+ {
+ return Matrix3x4.Mult(left, right);
+ }
+
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the multiplication
+ public static Matrix3x4 operator *(Matrix3x4 left, float right)
+ {
+ return Matrix3x4.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the addition
+ public static Matrix3x4 operator +(Matrix3x4 left, Matrix3x4 right)
+ {
+ return Matrix3x4.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4 which holds the result of the subtraction
+ public static Matrix3x4 operator -(Matrix3x4 left, Matrix3x4 right)
+ {
+ return Matrix3x4.Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3x4 left, Matrix3x4 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix3x4 left, Matrix3x4 right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// 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 Matrix3x4))
+ return false;
+
+ return this.Equals((Matrix3x4)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix3x4 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix3x4d.cs b/Source/OpenTK/Math/Matrix3x4d.cs
new file mode 100644
index 00000000..fa37cfc8
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix3x4d.cs
@@ -0,0 +1,1000 @@
+#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 3x4 Matrix
+ ///
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Matrix3x4d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix
+ ///
+ public Vector4d Row0;
+
+ ///
+ /// 2nd row of the matrix
+ ///
+ public Vector4d Row1;
+
+ ///
+ /// Bottom row of the matrix
+ ///
+ public Vector4d Row2;
+
+ ///
+ /// The zero matrix
+ ///
+ public static Matrix3x4d Zero = new Matrix3x4d(Vector4d.Zero, Vector4d.Zero, Vector4d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix
+ /// Second row of the matrix
+ /// Bottom row of the matrix
+ public Matrix3x4d(Vector4d row0, Vector4d row1, Vector4d 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.
+ /// Fourth 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.
+ /// Fourth 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.
+ /// First item of the third row of the matrix.
+ public Matrix3x4d(
+ double m00, double m01, double m02, double m03,
+ double m10, double m11, double m12, double m13,
+ double m20, double m21, double m22, double m23)
+ {
+ Row0 = new Vector4d(m00, m01, m02, m03);
+ Row1 = new Vector4d(m10, m11, m12, m13);
+ Row2 = new Vector4d(m20, m21, m22, m23);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// 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 the fourth column of this matrix.
+ ///
+ public Vector3d Column3
+ {
+ get { return new Vector3d(Row0.W, Row1.W, Row2.W); }
+ }
+
+ ///
+ /// 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 1, column 4 of this instance.
+ ///
+ public double M14 { get { return Row0.W; } set { Row0.W = 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 2, column 4 of this instance.
+ ///
+ public double M24 { get { return Row1.W; } set { Row1.W = 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; } }
+
+ ///
+ /// Gets or sets the value at row 3, column 4 of this instance.
+ ///
+ public double M34 { get { return Row2.W; } set { Row2.W = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3d Diagonal
+ {
+ get
+ {
+ return new Vector3d(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix3x4d.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix3x4d result)
+ {
+ axis.Normalize();
+ double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z;
+
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+ double t = 1.0f - cos;
+
+ 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.Row0.W = 0;
+ result.Row1.X = tXY + sinZ;
+ result.Row1.Y = tYY + cos;
+ result.Row1.Z = tYZ - sinX;
+ result.Row1.W = 0;
+ result.Row2.X = tXZ - sinY;
+ result.Row2.Y = tYZ + sinX;
+ result.Row2.Z = tZZ + cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix3x4d CreateFromAxisAngle(Vector3d axis, double angle)
+ {
+ Matrix3x4d result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateFromQuaternion
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static void CreateFromQuaternion(ref Quaternion q, out Matrix3x4d result)
+ {
+ double x = q.X, y = q.Y, z = q.Z, w = q.W,
+ tx = 2 * x, ty = 2 * y, tz = 2 * z,
+ txx = tx * x, tyy = ty * y, tzz = tz * z,
+ txy = tx * y, txz = tx * z, tyz = ty * z,
+ txw = tx * w, tyw = ty * w, tzw = tz * w;
+
+ result.Row0.X = 1f - (tyy + tzz);
+ result.Row0.Y = txy + tzw;
+ result.Row0.Z = txz - tyw;
+ result.Row0.W = 0f;
+ result.Row1.X = txy - tzw;
+ result.Row1.Y = 1f - (txx + tzz);
+ result.Row1.Z = tyz + txw;
+ result.Row1.W = 0f;
+ result.Row2.X = txz + tyw;
+ result.Row2.Y = tyz - txw;
+ result.Row2.Z = 1f - (txx + tyy);
+ result.Row2.W = 0f;
+
+ /*Vector3d axis;
+ double angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);*/
+ }
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static Matrix3x4d CreateFromQuaternion(Quaternion q)
+ {
+ Matrix3x4d result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateRotation[XYZ]
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationX(double angle, out Matrix3x4d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = cos;
+ result.Row1.Z = sin;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = -sin;
+ result.Row2.Z = cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4d CreateRotationX(double angle)
+ {
+ Matrix3x4d result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationY(double angle, out Matrix3x4d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = 0;
+ result.Row0.Z = -sin;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = sin;
+ result.Row2.Y = 0;
+ result.Row2.Z = cos;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4d CreateRotationY(double angle)
+ {
+ Matrix3x4d result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationZ(double angle, out Matrix3x4d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4d CreateRotationZ(double angle)
+ {
+ Matrix3x4d result;
+ CreateRotationZ(angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateTranslation
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(double x, double y, double z, out Matrix3x4d result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = x;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(ref Vector3d vector, out Matrix3x4d result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = vector.X;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row1.W = vector.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row2.W = vector.Z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4d CreateTranslation(double x, double y, double z)
+ {
+ Matrix3x4d result;
+ CreateTranslation(x, y, z, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static Matrix3x4d CreateTranslation(Vector3d vector)
+ {
+ Matrix3x4d result;
+ CreateTranslation(vector.X, vector.Y, vector.Z, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateScale
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Single scale factor for x,y and z axes
+ /// A scaling matrix
+ public static Matrix3x4d CreateScale(double scale)
+ {
+ return CreateScale(scale, scale, scale);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factors for x,y and z axes
+ /// A scaling matrix
+ public static Matrix3x4d CreateScale(Vector3d scale)
+ {
+ return CreateScale(scale.X, scale.Y, scale.Z);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factor for x-axis
+ /// Scale factor for y-axis
+ /// Scale factor for z-axis
+ /// A scaling matrix
+ public static Matrix3x4d CreateScale(double x, double y, double z)
+ {
+ Matrix3x4d result;
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = z;
+ result.Row2.W = 0;
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3d Mult(Matrix3x4d left, Matrix4x3d right)
+ {
+ Matrix3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4d left, ref Matrix4x3d right, out Matrix3d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W,
+ 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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + (lM14 * rM41);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + (lM14 * rM42);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + (lM14 * rM43);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + (lM24 * rM41);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + (lM24 * rM42);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + (lM24 * rM43);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + (lM34 * rM41);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + (lM34 * rM42);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + (lM34 * rM43);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3x4d Mult(Matrix3x4d left, Matrix3x4d right)
+ {
+ Matrix3x4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34) + lM14;
+ 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.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34) + lM24;
+ 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);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34) + lM34;
+
+ /*result.Row0 = (right.Row0 * lM11 + right.Row1 * lM12 + right.Row2 * lM13);
+ result.Row0.W += lM14;
+
+ result.Row1 = (right.Row0 * lM21 + right.Row1 * lM22 + right.Row2 * lM23);
+ result.Row1.W += lM24;
+
+ result.Row2 = (right.Row0 * lM31 + right.Row1 * lM32 + right.Row2 * lM33);
+ result.Row2.W += lM34;*/
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix3x4d Mult(Matrix3x4d left, double right)
+ {
+ Matrix3x4d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix3x4d left, double right, out Matrix3x4d result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ }
+
+ #endregion
+
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix3x4d Add(Matrix3x4d left, Matrix3x4d right)
+ {
+ Matrix3x4d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix3x4d Subtract(Matrix3x4d left, Matrix3x4d right)
+ {
+ Matrix3x4d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ }
+
+ #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 Matrix4 is singular.
+ public static Matrix3x4d Invert(Matrix3x4d mat)
+ {
+ Matrix3x4d result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ ///
+ /// 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 void Invert(ref Matrix3x4d mat, out Matrix3x4d result)
+ {
+ Matrix3d inverseRotation = new Matrix3d(mat.Column0, mat.Column1, mat.Column2);
+ inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared;
+ inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared;
+ inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared;
+
+ Vector3d translation = new Vector3d(mat.Row0.W, mat.Row1.W, mat.Row2.W);
+
+ result.Row0 = new Vector4d(inverseRotation.Row0, -Vector3d.Dot(inverseRotation.Row0, translation));
+ result.Row1 = new Vector4d(inverseRotation.Row1, -Vector3d.Dot(inverseRotation.Row1, translation));
+ result.Row2 = new Vector4d(inverseRotation.Row2, -Vector3d.Dot(inverseRotation.Row2, translation));
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix4x3d Transpose(Matrix3x4d mat)
+ {
+ return new Matrix4x3d(mat.Column0, mat.Column1, mat.Column2, mat.Column3);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ public static void Transpose(ref Matrix3x4d mat, out Matrix4x3d result)
+ {
+ result.Row0 = mat.Column0;
+ result.Row1 = mat.Column1;
+ result.Row2 = mat.Column2;
+ result.Row3 = mat.Column3;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3d which holds the result of the multiplication
+ public static Matrix3d operator *(Matrix3x4d left, Matrix4x3d right)
+ {
+ return Matrix3x4d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4d which holds the result of the multiplication
+ public static Matrix3x4d operator *(Matrix3x4d left, Matrix3x4d right)
+ {
+ return Matrix3x4d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4d which holds the result of the multiplication
+ public static Matrix3x4d operator *(Matrix3x4d left, double right)
+ {
+ return Matrix3x4d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4d which holds the result of the addition
+ public static Matrix3x4d operator +(Matrix3x4d left, Matrix3x4d right)
+ {
+ return Matrix3x4d.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix3x4d which holds the result of the subtraction
+ public static Matrix3x4d operator -(Matrix3x4d left, Matrix3x4d right)
+ {
+ return Matrix3x4d.Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix3x4d left, Matrix3x4d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix3x4d left, Matrix3x4d right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4.
+ ///
+ /// 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 Matrix3x4d))
+ return false;
+
+ return this.Equals((Matrix3x4d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix3x4d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix4.cs b/Source/OpenTK/Math/Matrix4.cs
index 643361bf..2d311fd5 100644
--- a/Source/OpenTK/Math/Matrix4.cs
+++ b/Source/OpenTK/Math/Matrix4.cs
@@ -28,8 +28,9 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 4x4 Matrix
+ /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection.
///
+ ///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4 : IEquatable
@@ -37,26 +38,34 @@ namespace OpenTK
#region Fields
///
- /// Top row of the matrix
+ /// Top row of the matrix.
///
public Vector4 Row0;
+
///
- /// 2nd row of the matrix
+ /// 2nd row of the matrix.
///
public Vector4 Row1;
+
///
- /// 3rd row of the matrix
+ /// 3rd row of the matrix.
///
public Vector4 Row2;
+
///
- /// Bottom row of the matrix
+ /// Bottom row of the matrix.
///
public Vector4 Row3;
///
- /// The identity matrix
+ /// The identity matrix.
///
- public static Matrix4 Identity = new Matrix4(Vector4.UnitX, Vector4.UnitY, Vector4.UnitZ, Vector4.UnitW);
+ public static readonly Matrix4 Identity = new Matrix4(Vector4.UnitX, Vector4.UnitY, Vector4.UnitZ, Vector4.UnitW);
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix4 Zero = new Matrix4(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero);
#endregion
@@ -65,10 +74,10 @@ namespace OpenTK
///
/// Constructs a new instance.
///
- /// Top row of the matrix
- /// Second row of the matrix
- /// Third row of the matrix
- /// Bottom row of the matrix
+ /// Top row of the matrix.
+ /// Second row of the matrix.
+ /// Third row of the matrix.
+ /// Bottom row of the matrix.
public Matrix4(Vector4 row0, Vector4 row1, Vector4 row2, Vector4 row3)
{
Row0 = row0;
@@ -115,52 +124,61 @@ namespace OpenTK
#region Properties
///
- /// The determinant of this matrix
+ /// Gets the determinant of this matrix.
///
public float Determinant
{
get
{
+ float m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, m14 = Row0.W,
+ m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, m24 = Row1.W,
+ m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z, m34 = Row2.W,
+ m41 = Row3.X, m42 = Row3.Y, m43 = Row3.Z, m44 = Row3.W;
+
return
- Row0.X * Row1.Y * Row2.Z * Row3.W - Row0.X * Row1.Y * Row2.W * Row3.Z + Row0.X * Row1.Z * Row2.W * Row3.Y - Row0.X * Row1.Z * Row2.Y * Row3.W
- + Row0.X * Row1.W * Row2.Y * Row3.Z - Row0.X * Row1.W * Row2.Z * Row3.Y - Row0.Y * Row1.Z * Row2.W * Row3.X + Row0.Y * Row1.Z * Row2.X * Row3.W
- - Row0.Y * Row1.W * Row2.X * Row3.Z + Row0.Y * Row1.W * Row2.Z * Row3.X - Row0.Y * Row1.X * Row2.Z * Row3.W + Row0.Y * Row1.X * Row2.W * Row3.Z
- + Row0.Z * Row1.W * Row2.X * Row3.Y - Row0.Z * Row1.W * Row2.Y * Row3.X + Row0.Z * Row1.X * Row2.Y * Row3.W - Row0.Z * Row1.X * Row2.W * Row3.Y
- + Row0.Z * Row1.Y * Row2.W * Row3.X - Row0.Z * Row1.Y * Row2.X * Row3.W - Row0.W * Row1.X * Row2.Y * Row3.Z + Row0.W * Row1.X * Row2.Z * Row3.Y
- - Row0.W * Row1.Y * Row2.Z * Row3.X + Row0.W * Row1.Y * Row2.X * Row3.Z - Row0.W * Row1.Z * Row2.X * Row3.Y + Row0.W * Row1.Z * Row2.Y * Row3.X;
+ m11 * m22 * m33 * m44 - m11 * m22 * m34 * m43 + m11 * m23 * m34 * m42 - m11 * m23 * m32 * m44
+ + m11 * m24 * m32 * m43 - m11 * m24 * m33 * m42 - m12 * m23 * m34 * m41 + m12 * m23 * m31 * m44
+ - m12 * m24 * m31 * m43 + m12 * m24 * m33 * m41 - m12 * m21 * m33 * m44 + m12 * m21 * m34 * m43
+ + m13 * m24 * m31 * m42 - m13 * m24 * m32 * m41 + m13 * m21 * m32 * m44 - m13 * m21 * m34 * m42
+ + m13 * m22 * m34 * m41 - m13 * m22 * m31 * m44 - m14 * m21 * m32 * m43 + m14 * m21 * m33 * m42
+ - m14 * m22 * m33 * m41 + m14 * m22 * m31 * m43 - m14 * m23 * m31 * m42 + m14 * m23 * m32 * m41;
}
}
///
- /// The first column of this matrix
+ /// Gets the first column of this matrix.
///
public Vector4 Column0
{
get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; }
}
///
- /// The second column of this matrix
+ /// Gets the second column of this matrix.
///
public Vector4 Column1
{
get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; }
}
///
- /// The third column of this matrix
+ /// Gets the third column of this matrix.
///
public Vector4 Column2
{
get { return new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; Row2.Z = value.Z; Row3.Z = value.W; }
}
///
- /// The fourth column of this matrix
+ /// Gets the fourth column of this matrix.
///
public Vector4 Column3
{
get { return new Vector4(Row0.W, Row1.W, Row2.W, Row3.W); }
+ set { Row0.W = value.X; Row1.W = value.Y; Row2.W = value.Z; Row3.W = value.W; }
}
///
@@ -242,6 +260,56 @@ 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; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector4 Diagonal
+ {
+ get
+ {
+ return new Vector4(Row0.X, Row1.Y, Row2.Z, Row3.W);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ Row3.W = value.W;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y + Row2.Z + Row3.W; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
#endregion
@@ -271,6 +339,165 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix4 Normalized()
+ {
+ Matrix4 m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ Row3 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix4 Inverted()
+ {
+ Matrix4 m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns a copy of this Matrix4 without translation.
+ ///
+ public Matrix4 ClearTranslation()
+ {
+ Matrix4 m = this;
+ m.Row3.Xyz = Vector3.Zero;
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4 without scale.
+ ///
+ public Matrix4 ClearScale()
+ {
+ Matrix4 m = this;
+ m.Row0.Xyz = m.Row0.Xyz.Normalized();
+ m.Row1.Xyz = m.Row1.Xyz.Normalized();
+ m.Row2.Xyz = m.Row2.Xyz.Normalized();
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4 without rotation.
+ ///
+ public Matrix4 ClearRotation()
+ {
+ Matrix4 m = this;
+ m.Row0.Xyz = new Vector3(m.Row0.Xyz.Length, 0, 0);
+ m.Row1.Xyz = new Vector3(0, m.Row1.Xyz.Length, 0);
+ m.Row2.Xyz = new Vector3(0, 0, m.Row2.Xyz.Length);
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4 without projection.
+ ///
+ public Matrix4 ClearProjection()
+ {
+ Matrix4 m = this;
+ m.Column3 = Vector4.Zero;
+ return m;
+ }
+
+ ///
+ /// Returns the translation component of this instance.
+ ///
+ public Vector3 ExtractTranslation() { return Row3.Xyz; }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3 ExtractScale() { return new Vector3(Row0.Xyz.Length, Row1.Xyz.Length, Row2.Xyz.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaternion ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0.Xyz;
+ var row1 = Row1.Xyz;
+ var row2 = Row2.Xyz;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaternion q = new Quaternion();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ 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);
+ }
+
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Returns the projection component of this instance.
+ ///
+ public Vector4 ExtractProjection()
+ {
+ return Column3;
+ }
+
#endregion
#region Static
@@ -285,16 +512,40 @@ namespace OpenTK
/// A matrix instance.
public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4 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;
- axis.Normalize();
+ // 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;
- result = new Matrix4(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0.0f,
- t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0.0f,
- t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0.0f,
- 0, 0, 0, 1);
+ 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.Row0.W = 0;
+ result.Row1.X = tXY + sinZ;
+ result.Row1.Y = tYY + cos;
+ result.Row1.Z = tYZ - sinX;
+ result.Row1.W = 0;
+ result.Row2.X = tXZ - sinY;
+ result.Row2.Y = tYZ + sinX;
+ result.Row2.Z = tZZ + cos;
+ result.Row2.W = 0;
+ result.Row3 = Vector4.UnitW;
}
///
@@ -312,6 +563,35 @@ namespace OpenTK
#endregion
+ #region CreateFromQuaternion
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static void CreateFromQuaternion(ref Quaternion q, out Matrix4 result)
+ {
+ Vector3 axis;
+ float angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);
+ }
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static Matrix4 CreateFromQuaternion(Quaternion q)
+ {
+ Matrix4 result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
#region CreateRotation[XYZ]
///
@@ -324,10 +604,11 @@ namespace OpenTK
float cos = (float)System.Math.Cos(angle);
float sin = (float)System.Math.Sin(angle);
- result.Row0 = Vector4.UnitX;
- result.Row1 = new Vector4(0.0f, cos, sin, 0.0f);
- result.Row2 = new Vector4(0.0f, -sin, cos, 0.0f);
- result.Row3 = Vector4.UnitW;
+ result = Identity;
+ result.Row1.Y = cos;
+ result.Row1.Z = sin;
+ result.Row2.Y = -sin;
+ result.Row2.Z = cos;
}
///
@@ -352,10 +633,11 @@ namespace OpenTK
float cos = (float)System.Math.Cos(angle);
float sin = (float)System.Math.Sin(angle);
- result.Row0 = new Vector4(cos, 0.0f, -sin, 0.0f);
- result.Row1 = Vector4.UnitY;
- result.Row2 = new Vector4(sin, 0.0f, cos, 0.0f);
- result.Row3 = Vector4.UnitW;
+ result = Identity;
+ result.Row0.X = cos;
+ result.Row0.Z = -sin;
+ result.Row2.X = sin;
+ result.Row2.Z = cos;
}
///
@@ -380,10 +662,11 @@ namespace OpenTK
float cos = (float)System.Math.Cos(angle);
float sin = (float)System.Math.Sin(angle);
- result.Row0 = new Vector4(cos, sin, 0.0f, 0.0f);
- result.Row1 = new Vector4(-sin, cos, 0.0f, 0.0f);
- result.Row2 = Vector4.UnitZ;
- result.Row3 = Vector4.UnitW;
+ result = Identity;
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
}
///
@@ -412,7 +695,9 @@ namespace OpenTK
public static void CreateTranslation(float x, float y, float z, out Matrix4 result)
{
result = Identity;
- result.Row3 = new Vector4(x, y, z, 1);
+ result.Row3.X = x;
+ result.Row3.Y = y;
+ result.Row3.Z = z;
}
///
@@ -423,7 +708,9 @@ namespace OpenTK
public static void CreateTranslation(ref Vector3 vector, out Matrix4 result)
{
result = Identity;
- result.Row3 = new Vector4(vector.X, vector.Y, vector.Z, 1);
+ result.Row3.X = vector.X;
+ result.Row3.Y = vector.Y;
+ result.Row3.Z = vector.Z;
}
///
@@ -454,6 +741,89 @@ namespace OpenTK
#endregion
+ #region CreateScale
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x, y, and z axes.
+ /// A scale matrix.
+ public static Matrix4 CreateScale(float scale)
+ {
+ Matrix4 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 Matrix4 CreateScale(Vector3 scale)
+ {
+ Matrix4 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 Matrix4 CreateScale(float x, float y, float z)
+ {
+ Matrix4 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 Matrix4 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 Matrix4 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 Matrix4 result)
+ {
+ result = Identity;
+ result.Row0.X = x;
+ result.Row1.Y = y;
+ result.Row2.Z = z;
+ }
+
+ #endregion
+
#region CreateOrthographic
///
@@ -500,20 +870,19 @@ namespace OpenTK
/// The resulting Matrix4 instance.
public static void CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, out Matrix4 result)
{
- result = new Matrix4();
+ result = Identity;
- float invRL = 1 / (right - left);
- float invTB = 1 / (top - bottom);
- float invFN = 1 / (zFar - zNear);
+ float invRL = 1.0f / (right - left);
+ float invTB = 1.0f / (top - bottom);
+ float invFN = 1.0f / (zFar - zNear);
- result.M11 = 2 * invRL;
- result.M22 = 2 * invTB;
- result.M33 = -2 * invFN;
+ result.Row0.X = 2 * invRL;
+ result.Row1.Y = 2 * invTB;
+ result.Row2.Z = -2 * invFN;
- result.M41 = -(right + left) * invRL;
- result.M42 = -(top + bottom) * invTB;
- result.M43 = -(zFar + zNear) * invFN;
- result.M44 = 1;
+ result.Row3.X = -(right + left) * invRL;
+ result.Row3.Y = -(top + bottom) * invTB;
+ result.Row3.Z = -(zFar + zNear) * invFN;
}
///
@@ -636,11 +1005,23 @@ namespace OpenTK
float b = (top + bottom) / (top - bottom);
float c = -(zFar + zNear) / (zFar - zNear);
float d = -(2.0f * zFar * zNear) / (zFar - zNear);
-
- result = new Matrix4(x, 0, 0, 0,
- 0, y, 0, 0,
- a, b, c, -1,
- 0, 0, d, 0);
+
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row0.W = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row1.W = 0;
+ result.Row2.X = a;
+ result.Row2.Y = b;
+ result.Row2.Z = c;
+ result.Row2.W = -1;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = d;
+ result.Row3.W = 0;
}
///
@@ -667,7 +1048,7 @@ namespace OpenTK
CreatePerspectiveOffCenter(left, right, bottom, top, zNear, zFar, out result);
return result;
}
-
+
#endregion
#region Obsolete Functions
@@ -682,7 +1063,7 @@ namespace OpenTK
[Obsolete("Use CreateTranslation instead.")]
public static Matrix4 Translation(Vector3 trans)
{
- return Translation(trans.X, trans.Y, trans.Z);
+ return CreateTranslation(trans);
}
///
@@ -695,52 +1076,7 @@ namespace OpenTK
[Obsolete("Use CreateTranslation instead.")]
public static Matrix4 Translation(float x, float y, float z)
{
- Matrix4 result = Identity;
- result.Row3 = new Vector4(x, y, z, 1.0f);
- return result;
- }
-
- #endregion
-
- #endregion
-
- #region Scale Functions
-
- ///
- /// Build a scaling matrix
- ///
- /// Single scale factor for x,y and z axes
- /// A scaling matrix
- public static Matrix4 Scale(float scale)
- {
- return Scale(scale, scale, scale);
- }
-
- ///
- /// Build a scaling matrix
- ///
- /// Scale factors for x,y and z axes
- /// A scaling matrix
- public static Matrix4 Scale(Vector3 scale)
- {
- return Scale(scale.X, scale.Y, scale.Z);
- }
-
- ///
- /// Build a scaling matrix
- ///
- /// Scale factor for x-axis
- /// Scale factor for y-axis
- /// Scale factor for z-axis
- /// A scaling matrix
- public static Matrix4 Scale(float x, float y, float z)
- {
- Matrix4 result;
- result.Row0 = Vector4.UnitX * x;
- result.Row1 = Vector4.UnitY * y;
- result.Row2 = Vector4.UnitZ * z;
- result.Row3 = Vector4.UnitW;
- return result;
+ return CreateTranslation(x, y, z);
}
#endregion
@@ -755,15 +1091,7 @@ namespace OpenTK
[Obsolete("Use CreateRotationX instead.")]
public static Matrix4 RotateX(float angle)
{
- float cos = (float)System.Math.Cos(angle);
- float sin = (float)System.Math.Sin(angle);
-
- Matrix4 result;
- result.Row0 = Vector4.UnitX;
- result.Row1 = new Vector4(0.0f, cos, sin, 0.0f);
- result.Row2 = new Vector4(0.0f, -sin, cos, 0.0f);
- result.Row3 = Vector4.UnitW;
- return result;
+ return CreateRotationX(angle);
}
///
@@ -774,15 +1102,7 @@ namespace OpenTK
[Obsolete("Use CreateRotationY instead.")]
public static Matrix4 RotateY(float angle)
{
- float cos = (float)System.Math.Cos(angle);
- float sin = (float)System.Math.Sin(angle);
-
- Matrix4 result;
- result.Row0 = new Vector4(cos, 0.0f, -sin, 0.0f);
- result.Row1 = Vector4.UnitY;
- result.Row2 = new Vector4(sin, 0.0f, cos, 0.0f);
- result.Row3 = Vector4.UnitW;
- return result;
+ return CreateRotationY(angle);
}
///
@@ -793,15 +1113,7 @@ namespace OpenTK
[Obsolete("Use CreateRotationZ instead.")]
public static Matrix4 RotateZ(float angle)
{
- float cos = (float)System.Math.Cos(angle);
- float sin = (float)System.Math.Sin(angle);
-
- Matrix4 result;
- result.Row0 = new Vector4(cos, sin, 0.0f, 0.0f);
- result.Row1 = new Vector4(-sin, cos, 0.0f, 0.0f);
- result.Row2 = Vector4.UnitZ;
- result.Row3 = Vector4.UnitW;
- return result;
+ return CreateRotationZ(angle);
}
///
@@ -813,18 +1125,7 @@ namespace OpenTK
[Obsolete("Use CreateFromAxisAngle instead.")]
public static Matrix4 Rotate(Vector3 axis, float angle)
{
- float cos = (float)System.Math.Cos(-angle);
- float sin = (float)System.Math.Sin(-angle);
- float t = 1.0f - cos;
-
- axis.Normalize();
-
- Matrix4 result;
- result.Row0 = new Vector4(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0.0f);
- result.Row1 = new Vector4(t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0.0f);
- result.Row2 = new Vector4(t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0.0f);
- result.Row3 = Vector4.UnitW;
- return result;
+ return CreateFromAxisAngle(axis, angle);
}
///
@@ -832,59 +1133,60 @@ namespace OpenTK
///
/// the quaternion
/// A rotation matrix
+ [Obsolete("Use CreateRotation instead.")]
public static Matrix4 Rotate(Quaternion q)
{
- Vector3 axis;
- float angle;
- q.ToAxisAngle(out axis, out angle);
- return CreateFromAxisAngle(axis, angle);
+ return CreateFromQuaternion(q);
+ }
+
+ #endregion
+
+ #region Scale Functions
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Single scale factor for x,y and z axes
+ /// A scaling matrix
+ [Obsolete("Use CreateScale instead.")]
+ public static Matrix4 Scale(float scale)
+ {
+ return Scale(scale, scale, scale);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factors for x,y and z axes
+ /// A scaling matrix
+ [Obsolete("Use CreateScale instead.")]
+ public static Matrix4 Scale(Vector3 scale)
+ {
+ return Scale(scale.X, scale.Y, scale.Z);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factor for x-axis
+ /// Scale factor for y-axis
+ /// Scale factor for z-axis
+ /// A scaling matrix
+ [Obsolete("Use CreateScale instead.")]
+ public static Matrix4 Scale(float x, float y, float z)
+ {
+ Matrix4 result;
+ result.Row0 = Vector4.UnitX * x;
+ result.Row1 = Vector4.UnitY * y;
+ result.Row2 = Vector4.UnitZ * z;
+ result.Row3 = Vector4.UnitW;
+ return result;
}
#endregion
#region Camera Helper Functions
- ///
- /// Build a world space to camera space matrix
- ///
- /// Eye (camera) position in world space
- /// Target position in world space
- /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
- /// A Matrix4 that transforms world space to camera space
- public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up)
- {
- Vector3 z = Vector3.Normalize(eye - target);
- Vector3 x = Vector3.Normalize(Vector3.Cross(up, z));
- Vector3 y = Vector3.Normalize(Vector3.Cross(z, x));
-
- Matrix4 rot = new Matrix4(new Vector4(x.X, y.X, z.X, 0.0f),
- new Vector4(x.Y, y.Y, z.Y, 0.0f),
- new Vector4(x.Z, y.Z, z.Z, 0.0f),
- Vector4.UnitW);
-
- Matrix4 trans = Matrix4.CreateTranslation(-eye);
-
- return trans * rot;
- }
-
- ///
- /// Build a world space to camera space matrix
- ///
- /// Eye (camera) position in world space
- /// Eye (camera) position in world space
- /// Eye (camera) position in world space
- /// Target position in world space
- /// Target position in world space
- /// Target position in world space
- /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
- /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
- /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
- /// A Matrix4 that transforms world space to camera space
- public static Matrix4 LookAt(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ)
- {
- return LookAt(new Vector3(eyeX, eyeY, eyeZ), new Vector3(targetX, targetY, targetZ), new Vector3(upX, upY, upZ));
- }
-
///
/// Build a projection matrix
///
@@ -928,6 +1230,127 @@ namespace OpenTK
#endregion
+ #endregion
+
+ #region Camera Helper Functions
+
+ ///
+ /// Build a world space to camera space matrix
+ ///
+ /// Eye (camera) position in world space
+ /// Target position in world space
+ /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
+ /// A Matrix4 that transforms world space to camera space
+ public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up)
+ {
+ Vector3 z = Vector3.Normalize(eye - target);
+ Vector3 x = Vector3.Normalize(Vector3.Cross(up, z));
+ Vector3 y = Vector3.Normalize(Vector3.Cross(z, x));
+
+ Matrix4 result;
+
+ result.Row0.X = x.X;
+ result.Row0.Y = y.X;
+ result.Row0.Z = z.X;
+ result.Row0.W = 0;
+ result.Row1.X = x.Y;
+ result.Row1.Y = y.Y;
+ result.Row1.Z = z.Y;
+ result.Row1.W = 0;
+ result.Row2.X = x.Z;
+ result.Row2.Y = y.Z;
+ result.Row2.Z = z.Z;
+ result.Row2.W = 0;
+ result.Row3.X = -((x.X * eye.X) + (x.Y * eye.Y) + (x.Z * eye.Z));
+ result.Row3.Y = -((y.X * eye.X) + (y.Y * eye.Y) + (y.Z * eye.Z));
+ result.Row3.Z = -((z.X * eye.X) + (z.Y * eye.Y) + (z.Z * eye.Z));
+ result.Row3.W = 1;
+
+ return result;
+ }
+
+ ///
+ /// Build a world space to camera space matrix
+ ///
+ /// Eye (camera) position in world space
+ /// Eye (camera) position in world space
+ /// Eye (camera) position in world space
+ /// Target position in world space
+ /// Target position in world space
+ /// Target position in world space
+ /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
+ /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
+ /// Up vector in world space (should not be parallel to the camera direction, that is target - eye)
+ /// A Matrix4 that transforms world space to camera space
+ public static Matrix4 LookAt(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ)
+ {
+ return LookAt(new Vector3(eyeX, eyeY, eyeZ), new Vector3(targetX, targetY, targetZ), new Vector3(upX, upY, upZ));
+ }
+
+ #endregion
+
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4 Add(Matrix4 left, Matrix4 right)
+ {
+ Matrix4 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4 left, ref Matrix4 right, out Matrix4 result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ result.Row3 = left.Row3 + right.Row3;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix4 Subtract(Matrix4 left, Matrix4 right)
+ {
+ Matrix4 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix4 left, ref Matrix4 right, out Matrix4 result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ result.Row3 = left.Row3 - right.Row3;
+ }
+
+ #endregion
+
#region Multiply Functions
///
@@ -935,7 +1358,7 @@ namespace OpenTK
///
/// The left operand of the multiplication.
/// The right operand of the multiplication.
- /// A new instance that is the result of the multiplication
+ /// A new instance that is the result of the multiplication.
public static Matrix4 Mult(Matrix4 left, Matrix4 right)
{
Matrix4 result;
@@ -948,7 +1371,7 @@ namespace OpenTK
///
/// The left operand of the multiplication.
/// The right operand of the multiplication.
- /// A new instance that is the result of the multiplication
+ /// A new instance that is the result of the multiplication.
public static void Mult(ref Matrix4 left, ref Matrix4 right, out Matrix4 result)
{
float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W,
@@ -978,6 +1401,33 @@ namespace OpenTK
result.Row3.W = (((lM41 * rM14) + (lM42 * rM24)) + (lM43 * rM34)) + (lM44 * rM44);
}
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4 Mult(Matrix4 left, float right)
+ {
+ Matrix4 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4 left, float right, out Matrix4 result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ result.Row3 = left.Row3 * right;
+ }
+
#endregion
#region Invert Functions
@@ -986,9 +1436,9 @@ namespace OpenTK
/// 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
+ /// 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 Matrix4 Invert(Matrix4 mat)
+ public static void Invert(ref Matrix4 mat, out Matrix4 result)
{
int[] colIdx = { 0, 0, 0, 0 };
int[] rowIdx = { 0, 0, 0, 0 };
@@ -1023,7 +1473,8 @@ namespace OpenTK
}
else if (pivotIdx[k] > 0)
{
- return mat;
+ result = mat;
+ return;
}
}
}
@@ -1050,7 +1501,6 @@ namespace OpenTK
if (pivot == 0.0f)
{
throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
- //return mat;
}
// Scale row so it has a unit diagonal
@@ -1085,11 +1535,35 @@ namespace OpenTK
}
}
- mat.Row0 = new Vector4(inverse[0, 0], inverse[0, 1], inverse[0, 2], inverse[0, 3]);
- mat.Row1 = new Vector4(inverse[1, 0], inverse[1, 1], inverse[1, 2], inverse[1, 3]);
- mat.Row2 = new Vector4(inverse[2, 0], inverse[2, 1], inverse[2, 2], inverse[2, 3]);
- mat.Row3 = new Vector4(inverse[3, 0], inverse[3, 1], inverse[3, 2], inverse[3, 3]);
- return mat;
+ result.Row0.X = inverse[0, 0];
+ result.Row0.Y = inverse[0, 1];
+ result.Row0.Z = inverse[0, 2];
+ result.Row0.W = inverse[0, 3];
+ result.Row1.X = inverse[1, 0];
+ result.Row1.Y = inverse[1, 1];
+ result.Row1.Z = inverse[1, 2];
+ result.Row1.W = inverse[1, 3];
+ result.Row2.X = inverse[2, 0];
+ result.Row2.Y = inverse[2, 1];
+ result.Row2.Z = inverse[2, 2];
+ result.Row2.W = inverse[2, 3];
+ result.Row3.X = inverse[3, 0];
+ result.Row3.Y = inverse[3, 1];
+ result.Row3.Z = inverse[3, 2];
+ result.Row3.W = inverse[3, 3];
+ }
+
+ ///
+ /// 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 Matrix4 Invert(Matrix4 mat)
+ {
+ Matrix4 result;
+ Invert(ref mat, out result);
+ return result;
}
#endregion
@@ -1131,12 +1605,45 @@ namespace OpenTK
///
/// left-hand operand
/// right-hand operand
- /// A new Matrix44 which holds the result of the multiplication
+ /// A new Matrix4 which holds the result of the multiplication
public static Matrix4 operator *(Matrix4 left, Matrix4 right)
{
return Matrix4.Mult(left, right);
}
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4 which holds the result of the multiplication
+ public static Matrix4 operator *(Matrix4 left, float right)
+ {
+ return Matrix4.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4 which holds the result of the addition
+ public static Matrix4 operator +(Matrix4 left, Matrix4 right)
+ {
+ return Matrix4.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4 which holds the result of the subtraction
+ public static Matrix4 operator -(Matrix4 left, Matrix4 right)
+ {
+ return Matrix4.Subtract(left, right);
+ }
+
///
/// Compares two instances for equality.
///
@@ -1166,9 +1673,9 @@ namespace OpenTK
#region public override string ToString()
///
- /// Returns a System.String that represents the current Matrix44.
+ /// Returns a System.String that represents the current Matrix4.
///
- ///
+ /// The string representation of the matrix.
public override string ToString()
{
return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3);
diff --git a/Source/OpenTK/Math/Matrix4d.cs b/Source/OpenTK/Math/Matrix4d.cs
index 3a0b7d3b..c4b9387d 100644
--- a/Source/OpenTK/Math/Matrix4d.cs
+++ b/Source/OpenTK/Math/Matrix4d.cs
@@ -28,8 +28,9 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 4x4 Matrix with double-precision components.
+ /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection with double-precision components.
///
+ ///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4d : IEquatable
@@ -137,6 +138,7 @@ namespace OpenTK
public Vector4d Column0
{
get { return new Vector4d (Row0.X, Row1.X, Row2.X, Row3.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; }
}
///
@@ -145,6 +147,7 @@ namespace OpenTK
public Vector4d Column1
{
get { return new Vector4d (Row0.Y, Row1.Y, Row2.Y, Row3.Y); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; }
}
///
@@ -153,6 +156,7 @@ namespace OpenTK
public Vector4d Column2
{
get { return new Vector4d (Row0.Z, Row1.Z, Row2.Z, Row3.Z); }
+ set { Row0.Z = value.X; Row1.Z = value.Y; Row2.Z = value.Z; Row3.Z = value.W; }
}
///
@@ -161,6 +165,7 @@ namespace OpenTK
public Vector4d Column3
{
get { return new Vector4d (Row0.W, Row1.W, Row2.W, Row3.W); }
+ set { Row0.W = value.X; Row1.W = value.Y; Row2.W = value.Z; Row3.W = value.W; }
}
///
@@ -243,6 +248,56 @@ namespace OpenTK
///
public double M44 { get { return Row3.W; } set { Row3.W = value; } }
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector4d Diagonal
+ {
+ get
+ {
+ return new Vector4d(Row0.X, Row1.Y, Row2.Z, Row3.W);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ Row3.W = value.W;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y + Row2.Z + Row3.W; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
#endregion
#region Instance
@@ -271,6 +326,166 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix4d Normalized()
+ {
+ Matrix4d m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ Row3 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix4d Inverted()
+ {
+ Matrix4d m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns a copy of this Matrix4d without translation.
+ ///
+ public Matrix4d ClearTranslation()
+ {
+ Matrix4d m = this;
+ m.Row3.Xyz = Vector3d.Zero;
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4d without scale.
+ ///
+ public Matrix4d ClearScale()
+ {
+ Matrix4d m = this;
+ m.Row0.Xyz = m.Row0.Xyz.Normalized();
+ m.Row1.Xyz = m.Row1.Xyz.Normalized();
+ m.Row2.Xyz = m.Row2.Xyz.Normalized();
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4d without rotation.
+ ///
+ public Matrix4d ClearRotation()
+ {
+ Matrix4d m = this;
+ m.Row0.Xyz = new Vector3d(m.Row0.Xyz.Length, 0, 0);
+ m.Row1.Xyz = new Vector3d(0, m.Row1.Xyz.Length, 0);
+ m.Row2.Xyz = new Vector3d(0, 0, m.Row2.Xyz.Length);
+ return m;
+ }
+ ///
+ /// Returns a copy of this Matrix4d without projection.
+ ///
+ public Matrix4d ClearProjection()
+ {
+ Matrix4d m = this;
+ m.Column3 = Vector4d.Zero;
+ return m;
+ }
+
+ ///
+ /// Returns the translation component of this instance.
+ ///
+ public Vector3d ExtractTranslation() { return Row3.Xyz; }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3d ExtractScale() { return new Vector3d(Row0.Xyz.Length, Row1.Xyz.Length, Row2.Xyz.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaterniond ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0.Xyz;
+ var row1 = Row1.Xyz;
+ var row2 = Row2.Xyz;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaterniond q = new Quaterniond();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (row1[2] - row2[1]) * sq;
+ q.Y = (row2[0] - row0[2]) * sq;
+ q.Z = (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 = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[1] - row1[2]) * sq;
+ q.Y = (row1[0] + row0[1]) * sq;
+ q.Z = (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 = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[0] - row0[2]) * sq;
+ q.X = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[1] + row1[2]) * sq;
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row1[0] - row0[1]) * sq;
+ q.X = (row2[0] + row0[2]) * sq;
+ q.Y = (row2[1] + row1[2]) * sq;
+ }
+
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Returns the projection component of this instance.
+ ///
+ public Vector4d ExtractProjection()
+ {
+ return Column3;
+ }
+
+
#endregion
#region Static
@@ -318,7 +533,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the x-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static void CreateRotationX(double angle, out Matrix4d result)
{
double cos = System.Math.Cos(angle);
@@ -334,7 +549,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the x-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static Matrix4d CreateRotationX(double angle)
{
Matrix4d result;
@@ -346,7 +561,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the y-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static void CreateRotationY(double angle, out Matrix4d result)
{
double cos = System.Math.Cos(angle);
@@ -362,7 +577,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the y-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static Matrix4d CreateRotationY(double angle)
{
Matrix4d result;
@@ -374,7 +589,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the z-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static void CreateRotationZ(double angle, out Matrix4d result)
{
double cos = System.Math.Cos(angle);
@@ -390,7 +605,7 @@ namespace OpenTK
/// Builds a rotation matrix for a rotation around the z-axis.
///
/// The counter-clockwise angle in radians.
- /// The resulting Matrix4 instance.
+ /// The resulting Matrix4d instance.
public static Matrix4d CreateRotationZ(double angle)
{
Matrix4d result;
@@ -670,6 +885,80 @@ namespace OpenTK
#endregion
+ #region CreateFromQuaternion
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// Matrix result.
+ public static void CreateFromQuaternion(ref Quaternion q,ref Matrix4 m)
+ {
+ m = Matrix4.Identity;
+
+ float X = q.X;
+ float Y = q.Y;
+ float Z = q.Z;
+ float W = q.W;
+
+ float xx = X * X;
+ float xy = X * Y;
+ float xz = X * Z;
+ float xw = X * W;
+ float yy = Y * Y;
+ float yz = Y * Z;
+ float yw = Y * W;
+ float zz = Z * Z;
+ float zw = Z * W;
+
+ m.M11 = 1 - 2 * (yy + zz);
+ m.M21 = 2 * (xy - zw);
+ m.M31 = 2 * (xz + yw);
+ m.M12 = 2 * (xy + zw);
+ m.M22 = 1 - 2 * (xx + zz);
+ m.M32 = 2 * (yz - xw);
+ m.M13 = 2 * (xz - yw);
+ m.M23 = 2 * (yz + xw);
+ m.M33 = 1 - 2 * (xx + yy);
+ }
+
+ ///
+ /// Build a rotation matrix from the specified quaternion.
+ ///
+ /// Quaternion to translate.
+ /// A matrix instance.
+ public static Matrix4 CreateFromQuaternion(ref Quaternion q)
+ {
+ Matrix4 result = Matrix4.Identity;
+
+ float X = q.X;
+ float Y = q.Y;
+ float Z = q.Z;
+ float W = q.W;
+
+ float xx = X * X;
+ float xy = X * Y;
+ float xz = X * Z;
+ float xw = X * W;
+ float yy = Y * Y;
+ float yz = Y * Z;
+ float yw = Y * W;
+ float zz = Z * Z;
+ float zw = Z * W;
+
+ result.M11 = 1 - 2 * (yy + zz);
+ result.M21 = 2 * (xy - zw);
+ result.M31 = 2 * (xz + yw);
+ result.M12 = 2 * (xy + zw);
+ result.M22 = 1 - 2 * (xx + zz);
+ result.M32 = 2 * (yz - xw);
+ result.M13 = 2 * (xz - yw);
+ result.M23 = 2 * (yz + xw);
+ result.M33 = 1 - 2 * (xx + yy);
+ return result;
+ }
+
+ #endregion
+
#region Obsolete Functions
#region Translation Functions
@@ -922,6 +1211,68 @@ namespace OpenTK
#endregion
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4d Add(Matrix4d left, Matrix4d right)
+ {
+ Matrix4d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ result.Row3 = left.Row3 + right.Row3;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix4d Subtract(Matrix4d left, Matrix4d right)
+ {
+ Matrix4d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ result.Row3 = left.Row3 - right.Row3;
+ }
+
+ #endregion
+
#region Multiply Functions
///
@@ -972,6 +1323,33 @@ namespace OpenTK
result.Row3.W = (((lM41 * rM14) + (lM42 * rM24)) + (lM43 * rM34)) + (lM44 * rM44);
}
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4d Mult(Matrix4d left, double right)
+ {
+ Matrix4d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4d left, double right, out Matrix4d result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ result.Row3 = left.Row3 * right;
+ }
+
#endregion
#region Invert Functions
@@ -1125,12 +1503,45 @@ namespace OpenTK
///
/// left-hand operand
/// right-hand operand
- /// A new Matrix44 which holds the result of the multiplication
+ /// A new Matrix4d which holds the result of the multiplication
public static Matrix4d operator *(Matrix4d left, Matrix4d right)
{
return Matrix4d.Mult(left, right);
}
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4d which holds the result of the multiplication
+ public static Matrix4d operator *(Matrix4d left, float right)
+ {
+ return Matrix4d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4d which holds the result of the addition
+ public static Matrix4d operator +(Matrix4d left, Matrix4d right)
+ {
+ return Matrix4d.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4d which holds the result of the subtraction
+ public static Matrix4d operator -(Matrix4d left, Matrix4d right)
+ {
+ return Matrix4d.Subtract(left, right);
+ }
+
///
/// Compares two instances for equality.
///
@@ -1207,7 +1618,7 @@ namespace OpenTK
#region IEquatable Members
/// Indicates whether the current matrix is equal to another matrix.
- /// An matrix to compare with this matrix.
+ /// A matrix to compare with this matrix.
/// true if the current matrix is equal to the matrix parameter; otherwise, false.
public bool Equals(Matrix4d other)
{
diff --git a/Source/OpenTK/Math/Matrix4x2.cs b/Source/OpenTK/Math/Matrix4x2.cs
new file mode 100644
index 00000000..d548efda
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix4x2.cs
@@ -0,0 +1,786 @@
+#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 4x2 matrix.
+ ///
+ public struct Matrix4x2 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2 Row0;
+
+ ///
+ /// Second row of the matrix.
+ ///
+ public Vector2 Row1;
+
+ ///
+ /// Third row of the matrix.
+ ///
+ public Vector2 Row2;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2 Row3;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix4x2 Zero = new Matrix4x2(Vector2.Zero, Vector2.Zero, Vector2.Zero, Vector2.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Second row of the matrix.
+ /// Third row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix4x2(Vector2 row0, Vector2 row1, Vector2 row2, Vector2 row3)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ Row2 = row2;
+ Row3 = row3;
+ }
+
+
+ ///
+ /// Constructs a new instance
+ ///
+ /// First item of the first row of the matrix.
+ /// Second 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.
+ /// First item of the third row of the matrix.
+ /// Second item of the third row of the matrix.
+ /// First item of the fourth row of the matrix.
+ /// Second item of the fourth row of the matrix.
+ public Matrix4x2(
+ float m00, float m01,
+ float m10, float m11,
+ float m20, float m21,
+ float m30, float m31)
+ {
+ Row0 = new Vector2(m00, m01);
+ Row1 = new Vector2(m10, m11);
+ Row2 = new Vector2(m20, m21);
+ Row3 = new Vector2(m30, m31);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector4 Column0
+ {
+ get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector4 Column1
+ {
+ get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.X); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; }
+ }
+
+ ///
+ /// 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 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 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 4, column 1 of this instance.
+ ///
+ public float M41 { get { return Row3.X; } set { Row3.X = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 2 of this instance.
+ ///
+ public float M42 { get { return Row3.Y; } set { Row3.Y = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector2 Diagonal
+ {
+ get
+ {
+ return new Vector2(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static void CreateRotation(float angle, out Matrix4x2 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static Matrix4x2 CreateRotation(float angle)
+ {
+ Matrix4x2 result;
+ CreateRotation(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 void CreateScale(float scale, out Matrix4x2 result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix4x2 CreateScale(float scale)
+ {
+ Matrix4x2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2 scale, out Matrix4x2 result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix4x2 CreateScale(Vector2 scale)
+ {
+ Matrix4x2 result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(float x, float y, out Matrix4x2 result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix4x2 CreateScale(float x, float y)
+ {
+ Matrix4x2 result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2 left, float right, out Matrix4x2 result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row2.X = left.Row2.X * right;
+ result.Row2.Y = left.Row2.Y * right;
+ result.Row3.X = left.Row3.X * right;
+ result.Row3.Y = left.Row3.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x2 Mult(Matrix4x2 left, float right)
+ {
+ Matrix4x2 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2 left, ref Matrix2 right, out Matrix4x2 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x2 Mult(Matrix4x2 left, Matrix2 right)
+ {
+ Matrix4x2 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2 left, ref Matrix2x3 right, out Matrix4x3 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x3 Mult(Matrix4x2 left, Matrix2x3 right)
+ {
+ Matrix4x3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2 left, ref Matrix2x4 right, out Matrix4 result)
+ {
+ float lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23);
+ result.Row3.W = (lM41 * rM14) + (lM42 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4 Mult(Matrix4x2 left, Matrix2x4 right)
+ {
+ Matrix4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4x2 left, ref Matrix4x2 right, out Matrix4x2 result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row2.X = left.Row2.X + right.Row2.X;
+ result.Row2.Y = left.Row2.Y + right.Row2.Y;
+ result.Row3.X = left.Row3.X + right.Row3.X;
+ result.Row3.Y = left.Row3.Y + right.Row3.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4x2 Add(Matrix4x2 left, Matrix4x2 right)
+ {
+ Matrix4x2 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix4x2 left, ref Matrix4x2 right, out Matrix4x2 result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row2.X = left.Row2.X - right.Row2.X;
+ result.Row2.Y = left.Row2.Y - right.Row2.Y;
+ result.Row3.X = left.Row3.X - right.Row3.X;
+ result.Row3.Y = left.Row3.Y - right.Row3.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix4x2 Subtract(Matrix4x2 left, Matrix4x2 right)
+ {
+ Matrix4x2 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix4x2 mat, out Matrix2x4 result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row0.Z = mat.Row2.X;
+ result.Row0.W = mat.Row3.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row1.Z = mat.Row2.Y;
+ result.Row1.W = mat.Row3.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2x4 Transpose(Matrix4x2 mat)
+ {
+ Matrix2x4 result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2 which holds the result of the multiplication
+ public static Matrix4x2 operator *(float left, Matrix4x2 right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2 which holds the result of the multiplication
+ public static Matrix4x2 operator *(Matrix4x2 left, float right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2 which holds the result of the multiplication
+ public static Matrix4x2 operator *(Matrix4x2 left, Matrix2 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3 which holds the result of the multiplication
+ public static Matrix4x3 operator *(Matrix4x2 left, Matrix2x3 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4 which holds the result of the multiplication
+ public static Matrix4 operator *(Matrix4x2 left, Matrix2x4 right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2 which holds the result of the addition
+ public static Matrix4x2 operator +(Matrix4x2 left, Matrix4x2 right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2 which holds the result of the subtraction
+ public static Matrix4x2 operator -(Matrix4x2 left, Matrix4x2 right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix4x2 left, Matrix4x2 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix4x2 left, Matrix4x2 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}\n{3}", Row0, Row1, Row2, Row3);
+ }
+
+ #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() ^ Row3.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 Matrix4x2))
+ return false;
+
+ return this.Equals((Matrix4x2)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix4x2 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2 &&
+ Row3 == other.Row3;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix4x2d.cs b/Source/OpenTK/Math/Matrix4x2d.cs
new file mode 100644
index 00000000..bf494a19
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix4x2d.cs
@@ -0,0 +1,786 @@
+#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 4x2 matrix.
+ ///
+ public struct Matrix4x2d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix.
+ ///
+ public Vector2d Row0;
+
+ ///
+ /// Second row of the matrix.
+ ///
+ public Vector2d Row1;
+
+ ///
+ /// Third row of the matrix.
+ ///
+ public Vector2d Row2;
+
+ ///
+ /// Bottom row of the matrix.
+ ///
+ public Vector2d Row3;
+
+ ///
+ /// The zero matrix.
+ ///
+ public static readonly Matrix4x2d Zero = new Matrix4x2d(Vector2d.Zero, Vector2d.Zero, Vector2d.Zero, Vector2d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix.
+ /// Second row of the matrix.
+ /// Third row of the matrix.
+ /// Bottom row of the matrix.
+ public Matrix4x2d(Vector2d row0, Vector2d row1, Vector2d row2, Vector2d row3)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ Row2 = row2;
+ Row3 = row3;
+ }
+
+
+ ///
+ /// Constructs a new instance
+ ///
+ /// First item of the first row of the matrix.
+ /// Second 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.
+ /// First item of the third row of the matrix.
+ /// Second item of the third row of the matrix.
+ /// First item of the fourth row of the matrix.
+ /// Second item of the fourth row of the matrix.
+ public Matrix4x2d(
+ double m00, double m01,
+ double m10, double m11,
+ double m20, double m21,
+ double m30, double m31)
+ {
+ Row0 = new Vector2d(m00, m01);
+ Row1 = new Vector2d(m10, m11);
+ Row2 = new Vector2d(m20, m21);
+ Row3 = new Vector2d(m30, m31);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets or sets the first column of this matrix.
+ ///
+ public Vector4d Column0
+ {
+ get { return new Vector4d(Row0.X, Row1.X, Row2.X, Row3.X); }
+ set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; }
+ }
+
+ ///
+ /// Gets or sets the second column of this matrix.
+ ///
+ public Vector4d Column1
+ {
+ get { return new Vector4d(Row0.Y, Row1.Y, Row2.Y, Row3.X); }
+ set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; }
+ }
+
+ ///
+ /// 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 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 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 4, column 1 of this instance.
+ ///
+ public double M41 { get { return Row3.X; } set { Row3.X = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 2 of this instance.
+ ///
+ public double M42 { get { return Row3.Y; } set { Row3.Y = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector2d Diagonal
+ {
+ get
+ {
+ return new Vector2d(Row0.X, Row1.Y);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Static
+
+ #region CreateRotation
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static void CreateRotation(double angle, out Matrix4x2d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix3x2 instance.
+ public static Matrix4x2d CreateRotation(double angle)
+ {
+ Matrix4x2d result;
+ CreateRotation(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 void CreateScale(double scale, out Matrix4x2d result)
+ {
+ result.Row0.X = scale;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Single scale factor for the x and y axes.
+ /// A scale matrix.
+ public static Matrix4x2d CreateScale(double scale)
+ {
+ Matrix4x2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static void CreateScale(Vector2d scale, out Matrix4x2d result)
+ {
+ result.Row0.X = scale.X;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = scale.Y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factors for the x and y axes.
+ /// A scale matrix.
+ public static Matrix4x2d CreateScale(Vector2d scale)
+ {
+ Matrix4x2d result;
+ CreateScale(scale, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static void CreateScale(double x, double y, out Matrix4x2d result)
+ {
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ }
+
+ ///
+ /// Creates a scale matrix.
+ ///
+ /// Scale factor for the x axis.
+ /// Scale factor for the y axis.
+ /// A scale matrix.
+ public static Matrix4x2d CreateScale(double x, double y)
+ {
+ Matrix4x2d result;
+ CreateScale(x, y, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2d left, double right, out Matrix4x2d result)
+ {
+ result.Row0.X = left.Row0.X * right;
+ result.Row0.Y = left.Row0.Y * right;
+ result.Row1.X = left.Row1.X * right;
+ result.Row1.Y = left.Row1.Y * right;
+ result.Row2.X = left.Row2.X * right;
+ result.Row2.Y = left.Row2.Y * right;
+ result.Row3.X = left.Row3.X * right;
+ result.Row3.Y = left.Row3.Y * right;
+ }
+
+ ///
+ /// Multiplies and instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x2d Mult(Matrix4x2d left, double right)
+ {
+ Matrix4x2d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2d left, ref Matrix2d right, out Matrix4x2d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x2d Mult(Matrix4x2d left, Matrix2d right)
+ {
+ Matrix4x2d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2d left, ref Matrix2x3d right, out Matrix4x3d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4x3d Mult(Matrix4x2d left, Matrix2x3d right)
+ {
+ Matrix4x3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static void Mult(ref Matrix4x2d left, ref Matrix2x4d right, out Matrix4d result)
+ {
+ double lM11 = left.Row0.X, lM12 = left.Row0.Y,
+ lM21 = left.Row1.X, lM22 = left.Row1.Y,
+ lM31 = left.Row2.X, lM32 = left.Row2.Y,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21);
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22);
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23);
+ result.Row0.W = (lM11 * rM14) + (lM12 * rM24);
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21);
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22);
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23);
+ result.Row1.W = (lM21 * rM14) + (lM22 * rM24);
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21);
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22);
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23);
+ result.Row3.W = (lM41 * rM14) + (lM42 * rM24);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication.
+ public static Matrix4d Mult(Matrix4x2d left, Matrix2x4d right)
+ {
+ Matrix4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Add
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4x2d left, ref Matrix4x2d right, out Matrix4x2d result)
+ {
+ result.Row0.X = left.Row0.X + right.Row0.X;
+ result.Row0.Y = left.Row0.Y + right.Row0.Y;
+ result.Row1.X = left.Row1.X + right.Row1.X;
+ result.Row1.Y = left.Row1.Y + right.Row1.Y;
+ result.Row2.X = left.Row2.X + right.Row2.X;
+ result.Row2.Y = left.Row2.Y + right.Row2.Y;
+ result.Row3.X = left.Row3.X + right.Row3.X;
+ result.Row3.Y = left.Row3.Y + right.Row3.Y;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4x2d Add(Matrix4x2d left, Matrix4x2d right)
+ {
+ Matrix4x2d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static void Subtract(ref Matrix4x2d left, ref Matrix4x2d right, out Matrix4x2d result)
+ {
+ result.Row0.X = left.Row0.X - right.Row0.X;
+ result.Row0.Y = left.Row0.Y - right.Row0.Y;
+ result.Row1.X = left.Row1.X - right.Row1.X;
+ result.Row1.Y = left.Row1.Y - right.Row1.Y;
+ result.Row2.X = left.Row2.X - right.Row2.X;
+ result.Row2.Y = left.Row2.Y - right.Row2.Y;
+ result.Row3.X = left.Row3.X - right.Row3.X;
+ result.Row3.Y = left.Row3.Y - right.Row3.Y;
+ }
+
+ ///
+ /// Subtracts two instances.
+ ///
+ /// The left operand of the subtraction.
+ /// The right operand of the subtraction.
+ /// A new instance that is the result of the subtraction.
+ public static Matrix4x2d Subtract(Matrix4x2d left, Matrix4x2d right)
+ {
+ Matrix4x2d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static void Transpose(ref Matrix4x2d mat, out Matrix2x4d result)
+ {
+ result.Row0.X = mat.Row0.X;
+ result.Row0.Y = mat.Row1.X;
+ result.Row0.Z = mat.Row2.X;
+ result.Row0.W = mat.Row3.X;
+ result.Row1.X = mat.Row0.Y;
+ result.Row1.Y = mat.Row1.Y;
+ result.Row1.Z = mat.Row2.Y;
+ result.Row1.W = mat.Row3.Y;
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix.
+ ///
+ /// The matrix to transpose.
+ /// The transpose of the given matrix.
+ public static Matrix2x4d Transpose(Matrix4x2d mat)
+ {
+ Matrix2x4d result;
+ Transpose(ref mat, out result);
+ return result;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2d which holds the result of the multiplication
+ public static Matrix4x2d operator *(double left, Matrix4x2d right)
+ {
+ return Mult(right, left);
+ }
+
+ ///
+ /// Scalar multiplication.
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2d which holds the result of the multiplication
+ public static Matrix4x2d operator *(Matrix4x2d left, double right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix2d which holds the result of the multiplication
+ public static Matrix4x2d operator *(Matrix4x2d left, Matrix2d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3d which holds the result of the multiplication
+ public static Matrix4x3d operator *(Matrix4x2d left, Matrix2x3d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4d which holds the result of the multiplication
+ public static Matrix4d operator *(Matrix4x2d left, Matrix2x4d right)
+ {
+ return Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2d which holds the result of the addition
+ public static Matrix4x2d operator +(Matrix4x2d left, Matrix4x2d right)
+ {
+ return Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x2d which holds the result of the subtraction
+ public static Matrix4x2d operator -(Matrix4x2d left, Matrix4x2d right)
+ {
+ return Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix4x2d left, Matrix4x2d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix4x2d left, Matrix4x2d 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}\n{3}", Row0, Row1, Row2, Row3);
+ }
+
+ #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() ^ Row3.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 Matrix4x2d))
+ return false;
+
+ return this.Equals((Matrix4x2d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ ///
+ /// Indicates whether the current matrix is equal to another matrix.
+ ///
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix4x2d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2 &&
+ Row3 == other.Row3;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix4x3.cs b/Source/OpenTK/Math/Matrix4x3.cs
new file mode 100644
index 00000000..e7fd6788
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix4x3.cs
@@ -0,0 +1,1007 @@
+#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 3x4 matrix.
+ ///
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Matrix4x3 : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix
+ ///
+ public Vector3 Row0;
+
+ ///
+ /// 2nd row of the matrix
+ ///
+ public Vector3 Row1;
+
+ ///
+ /// 3rd row of the matrix
+ ///
+ public Vector3 Row2;
+
+ ///
+ /// Bottom row of the matrix
+ ///
+ public Vector3 Row3;
+
+ ///
+ /// The zero matrix
+ ///
+ public static readonly Matrix4x3 Zero = new Matrix4x3(Vector3.Zero, Vector3.Zero, Vector3.Zero, Vector3.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix
+ /// Second row of the matrix
+ /// Third row of the matrix
+ /// Bottom row of the matrix
+ public Matrix4x3(Vector3 row0, Vector3 row1, Vector3 row2, Vector3 row3)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ Row2 = row2;
+ Row3 = row3;
+ }
+
+ ///
+ /// 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.
+ /// First item of the fourth row of the matrix.
+ /// Second item of the fourth row of the matrix.
+ /// Third item of the fourth row of the matrix.
+ public Matrix4x3(
+ float m00, float m01, float m02,
+ float m10, float m11, float m12,
+ float m20, float m21, float m22,
+ float m30, float m31, float m32)
+ {
+ Row0 = new Vector3(m00, m01, m02);
+ Row1 = new Vector3(m10, m11, m12);
+ Row2 = new Vector3(m20, m21, m22);
+ Row3 = new Vector3(m30, m31, m32);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets the first column of this matrix.
+ ///
+ public Vector4 Column0
+ {
+ get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); }
+ }
+
+ ///
+ /// Gets the second column of this matrix.
+ ///
+ public Vector4 Column1
+ {
+ get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y); }
+ }
+
+ ///
+ /// Gets the third column of this matrix.
+ ///
+ public Vector4 Column2
+ {
+ get { return new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.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; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 1 of this instance.
+ ///
+ public float M41 { get { return Row3.X; } set { Row3.X = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 2 of this instance.
+ ///
+ public float M42 { get { return Row3.Y; } set { Row3.Y = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 3 of this instance.
+ ///
+ public float M43 { get { return Row3.Z; } set { Row3.Z = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3 Diagonal
+ {
+ get
+ {
+ return new Vector3(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public float this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into it's inverse by inverting the upper-left 3x3 and replacing Row3.
+ ///
+ public void Invert()
+ {
+ this = Matrix4x3.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4x3 result)
+ {
+ axis.Normalize();
+ float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z;
+
+ float cos = (float)System.Math.Cos(-angle);
+ float sin = (float)System.Math.Sin(-angle);
+ float t = 1.0f - cos;
+
+ 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;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix4x3 CreateFromAxisAngle(Vector3 axis, float angle)
+ {
+ Matrix4x3 result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateFromQuaternion
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static void CreateFromQuaternion(ref Quaternion q, out Matrix4x3 result)
+ {
+ float x = q.X, y = q.Y, z = q.Z, w = q.W,
+ tx = 2 * x, ty = 2 * y, tz = 2 * z,
+ txx = tx * x, tyy = ty * y, tzz = tz * z,
+ txy = tx * y, txz = tx * z, tyz = ty * z,
+ twx = w * tx, twy = w * ty, twz = w * tz;
+
+ result.Row0.X = 1f - tyy - tzz;
+ result.Row0.Y = txy - twz;
+ result.Row0.Z = txz + twy;
+ result.Row1.X = txy + twz;
+ result.Row1.Y = 1f - txx - tzz;
+ result.Row1.Z = tyz - twx;
+ result.Row2.X = txz - twy;
+ result.Row2.Y = tyz + twx;
+ result.Row2.Z = 1f - txx - tyy;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+
+ /*Vector3 axis;
+ float angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);*/
+ }
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static Matrix4x3 CreateFromQuaternion(Quaternion q)
+ {
+ Matrix4x3 result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateRotation[XYZ]
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationX(float angle, out Matrix4x3 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = cos;
+ result.Row1.Z = sin;
+ result.Row2.X = 0;
+ result.Row2.Y = -sin;
+ result.Row2.Z = cos;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix4x3 CreateRotationX(float angle)
+ {
+ Matrix4x3 result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationY(float angle, out Matrix4x3 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = 0;
+ result.Row0.Z = -sin;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = sin;
+ result.Row2.Y = 0;
+ result.Row2.Z = cos;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix4x3 CreateRotationY(float angle)
+ {
+ Matrix4x3 result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static void CreateRotationZ(float angle, out Matrix4x3 result)
+ {
+ float cos = (float)System.Math.Cos(angle);
+ float sin = (float)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4 instance.
+ public static Matrix4x3 CreateRotationZ(float angle)
+ {
+ Matrix4x3 result;
+ CreateRotationZ(angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateTranslation
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(float x, float y, float z, out Matrix4x3 result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = x;
+ result.Row3.Y = y;
+ result.Row3.Z = z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static void CreateTranslation(ref Vector3 vector, out Matrix4x3 result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = vector.X;
+ result.Row3.Y = vector.Y;
+ result.Row3.Z = vector.Z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4 instance.
+ public static Matrix4x3 CreateTranslation(float x, float y, float z)
+ {
+ Matrix4x3 result;
+ CreateTranslation(x, y, z, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4 instance.
+ public static Matrix4x3 CreateTranslation(Vector3 vector)
+ {
+ Matrix4x3 result;
+ CreateTranslation(vector.X, vector.Y, vector.Z, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateScale
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Single scale factor for x,y and z axes
+ /// A scaling matrix
+ public static Matrix4x3 CreateScale(float scale)
+ {
+ return CreateScale(scale, scale, scale);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factors for x,y and z axes
+ /// A scaling matrix
+ public static Matrix4x3 CreateScale(Vector3 scale)
+ {
+ return CreateScale(scale.X, scale.Y, scale.Z);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factor for x-axis
+ /// Scale factor for y-axis
+ /// Scale factor for z-axis
+ /// A scaling matrix
+ public static Matrix4x3 CreateScale(float x, float y, float z)
+ {
+ Matrix4x3 result;
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = z;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// This isn't quite a multiply, but the result may be useful in some situations.
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4 Mult(Matrix4x3 left, Matrix3x4 right)
+ {
+ Matrix4 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// This isn't quite a multiply, but the result may be useful in some situations.
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3 left, ref Matrix3x4 right, out Matrix4 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,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34);
+ 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.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34);
+ 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);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33);
+ result.Row3.W = (lM41 * rM14) + (lM42 * rM24) + (lM43 * rM34);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4x3 Mult(Matrix4x3 left, Matrix4x3 right)
+ {
+ Matrix4x3 result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// This isn't quite a multiply, but the result may be useful in some situations.
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 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,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + rM41;
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + rM42;
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + rM43;
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + rM41;
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + rM42;
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + rM43;
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + rM41;
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + rM42;
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + rM43;
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31) + rM41;
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32) + rM42;
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33) + rM43;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4x3 Mult(Matrix4x3 left, float right)
+ {
+ Matrix4x3 result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3 left, float right, out Matrix4x3 result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ result.Row3 = left.Row3 * right;
+ }
+
+ #endregion
+
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4x3 Add(Matrix4x3 left, Matrix4x3 right)
+ {
+ Matrix4x3 result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ result.Row3 = left.Row3 + right.Row3;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix4x3 Subtract(Matrix4x3 left, Matrix4x3 right)
+ {
+ Matrix4x3 result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ result.Row3 = left.Row3 - right.Row3;
+ }
+
+ #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 Matrix4 is singular.
+ public static Matrix4x3 Invert(Matrix4x3 mat)
+ {
+ Matrix4x3 result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ ///
+ /// 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 void Invert(ref Matrix4x3 mat, out Matrix4x3 result)
+ {
+ Matrix3 inverseRotation = new Matrix3(mat.Column0.Xyz, mat.Column1.Xyz, mat.Column2.Xyz);
+ inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared;
+ inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared;
+ inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared;
+
+ Vector3 translation = mat.Row3;
+
+ result.Row0 = inverseRotation.Row0;
+ result.Row1 = inverseRotation.Row1;
+ result.Row2 = inverseRotation.Row2;
+ result.Row3 = new Vector3(-Vector3.Dot(inverseRotation.Row0, translation), -Vector3.Dot(inverseRotation.Row1, translation), -Vector3.Dot(inverseRotation.Row2, translation));
+ }
+
+ #endregion
+
+ #region Transpose
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix3x4 Transpose(Matrix4x3 mat)
+ {
+ return new Matrix3x4(mat.Column0, mat.Column1, mat.Column2);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ public static void Transpose(ref Matrix4x3 mat, out Matrix3x4 result)
+ {
+ result.Row0 = mat.Column0;
+ result.Row1 = mat.Column1;
+ result.Row2 = mat.Column2;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4 which holds the result of the multiplication
+ public static Matrix4 operator *(Matrix4x3 left, Matrix3x4 right)
+ {
+ return Matrix4x3.Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3 which holds the result of the multiplication
+ public static Matrix4x3 operator *(Matrix4x3 left, Matrix4x3 right)
+ {
+ return Matrix4x3.Mult(left, right);
+ }
+
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3 which holds the result of the multiplication
+ public static Matrix4x3 operator *(Matrix4x3 left, float right)
+ {
+ return Matrix4x3.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3 which holds the result of the addition
+ public static Matrix4x3 operator +(Matrix4x3 left, Matrix4x3 right)
+ {
+ return Matrix4x3.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3 which holds the result of the subtraction
+ public static Matrix4x3 operator -(Matrix4x3 left, Matrix4x3 right)
+ {
+ return Matrix4x3.Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix4x3 left, Matrix4x3 right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix4x3 left, Matrix4x3 right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4x3.
+ ///
+ /// 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 tresult.
+ /// True if the instances are equal; false otherwise.
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Matrix4x3))
+ return false;
+
+ return this.Equals((Matrix4x3)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix4x3 other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2 &&
+ Row3 == other.Row3;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Matrix4x3d.cs b/Source/OpenTK/Math/Matrix4x3d.cs
new file mode 100644
index 00000000..908477fd
--- /dev/null
+++ b/Source/OpenTK/Math/Matrix4x3d.cs
@@ -0,0 +1,1007 @@
+#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 3x4 matrix.
+ ///
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Matrix4x3d : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Top row of the matrix
+ ///
+ public Vector3d Row0;
+
+ ///
+ /// 2nd row of the matrix
+ ///
+ public Vector3d Row1;
+
+ ///
+ /// 3rd row of the matrix
+ ///
+ public Vector3d Row2;
+
+ ///
+ /// Bottom row of the matrix
+ ///
+ public Vector3d Row3;
+
+ ///
+ /// The zero matrix
+ ///
+ public static Matrix4x3d Zero = new Matrix4x3d(Vector3d.Zero, Vector3d.Zero, Vector3d.Zero, Vector3d.Zero);
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new instance.
+ ///
+ /// Top row of the matrix
+ /// Second row of the matrix
+ /// Third row of the matrix
+ /// Bottom row of the matrix
+ public Matrix4x3d(Vector3d row0, Vector3d row1, Vector3d row2, Vector3d row3)
+ {
+ Row0 = row0;
+ Row1 = row1;
+ Row2 = row2;
+ Row3 = row3;
+ }
+
+ ///
+ /// 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.
+ /// First item of the fourth row of the matrix.
+ /// Second item of the fourth row of the matrix.
+ /// Third item of the fourth row of the matrix.
+ public Matrix4x3d(
+ double m00, double m01, double m02,
+ double m10, double m11, double m12,
+ double m20, double m21, double m22,
+ double m30, double m31, double m32)
+ {
+ Row0 = new Vector3d(m00, m01, m02);
+ Row1 = new Vector3d(m10, m11, m12);
+ Row2 = new Vector3d(m20, m21, m22);
+ Row3 = new Vector3d(m30, m31, m32);
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region Properties
+
+ ///
+ /// Gets the first column of this matrix.
+ ///
+ public Vector4d Column0
+ {
+ get { return new Vector4d(Row0.X, Row1.X, Row2.X, Row3.X); }
+ }
+
+ ///
+ /// Gets the second column of this matrix.
+ ///
+ public Vector4d Column1
+ {
+ get { return new Vector4d(Row0.Y, Row1.Y, Row2.Y, Row3.Y); }
+ }
+
+ ///
+ /// Gets the third column of this matrix.
+ ///
+ public Vector4d Column2
+ {
+ get { return new Vector4d(Row0.Z, Row1.Z, Row2.Z, Row3.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; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 1 of this instance.
+ ///
+ public double M41 { get { return Row3.X; } set { Row3.X = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 2 of this instance.
+ ///
+ public double M42 { get { return Row3.Y; } set { Row3.Y = value; } }
+
+ ///
+ /// Gets or sets the value at row 4, column 3 of this instance.
+ ///
+ public double M43 { get { return Row3.Z; } set { Row3.Z = value; } }
+
+ ///
+ /// Gets or sets the values along the main diagonal of the matrix.
+ ///
+ public Vector3d Diagonal
+ {
+ get
+ {
+ return new Vector3d(Row0.X, Row1.Y, Row2.Z);
+ }
+ set
+ {
+ Row0.X = value.X;
+ Row1.Y = value.Y;
+ Row2.Z = value.Z;
+ }
+ }
+
+ ///
+ /// Gets the trace of the matrix, the sum of the values along the diagonal.
+ ///
+ public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Gets or sets the value at a specified row and column.
+ ///
+ public double this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ if (rowIndex == 0) return Row0[columnIndex];
+ else if (rowIndex == 1) return Row1[columnIndex];
+ else if (rowIndex == 2) return Row2[columnIndex];
+ else if (rowIndex == 3) return Row3[columnIndex];
+ throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ set
+ {
+ if (rowIndex == 0) Row0[columnIndex] = value;
+ else if (rowIndex == 1) Row1[columnIndex] = value;
+ else if (rowIndex == 2) Row2[columnIndex] = value;
+ else if (rowIndex == 3) Row3[columnIndex] = value;
+ else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
+ }
+ }
+
+ #endregion
+
+ #region Instance
+
+ #region public void Invert()
+
+ ///
+ /// Converts this instance into its inverse.
+ ///
+ public void Invert()
+ {
+ this = Matrix4x3d.Invert(this);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Static
+
+ #region CreateFromAxisAngle
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix4x3d result)
+ {
+ axis.Normalize();
+ double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z;
+
+ double cos = (double)System.Math.Cos(-angle);
+ double sin = (double)System.Math.Sin(-angle);
+ double t = 1.0f - cos;
+
+ 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;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Build a rotation matrix from the specified axis/angle rotation.
+ ///
+ /// The axis to rotate about.
+ /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).
+ /// A matrix instance.
+ public static Matrix4x3d CreateFromAxisAngle(Vector3d axis, double angle)
+ {
+ Matrix4x3d result;
+ CreateFromAxisAngle(axis, angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateFromQuaternion
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static void CreateFromQuaternion(ref Quaternion q, out Matrix4x3d result)
+ {
+ double x = q.X, y = q.Y, z = q.Z, w = q.W,
+ tx = 2 * x, ty = 2 * y, tz = 2 * z,
+ txx = tx * x, tyy = ty * y, tzz = tz * z,
+ txy = tx * y, txz = tx * z, tyz = ty * z,
+ twx = w * tx, twy = w * ty, twz = w * tz;
+
+ result.Row0.X = 1f - tyy - tzz;
+ result.Row0.Y = txy - twz;
+ result.Row0.Z = txz + twy;
+ result.Row1.X = txy + twz;
+ result.Row1.Y = 1f - txx - tzz;
+ result.Row1.Z = tyz - twx;
+ result.Row2.X = txz - twy;
+ result.Row2.Y = tyz + twx;
+ result.Row2.Z = 1f - txx - tyy;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+
+ /*Vector3d axis;
+ double angle;
+ q.ToAxisAngle(out axis, out angle);
+ CreateFromAxisAngle(axis, angle, out result);*/
+ }
+
+ ///
+ /// Builds a rotation matrix from a quaternion.
+ ///
+ /// The quaternion to rotate by.
+ /// A matrix instance.
+ public static Matrix4x3d CreateFromQuaternion(Quaternion q)
+ {
+ Matrix4x3d result;
+ CreateFromQuaternion(ref q, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateRotation[XYZ]
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static void CreateRotationX(double angle, out Matrix4x3d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = cos;
+ result.Row1.Z = sin;
+ result.Row2.X = 0;
+ result.Row2.Y = -sin;
+ result.Row2.Z = cos;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the x-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static Matrix4x3d CreateRotationX(double angle)
+ {
+ Matrix4x3d result;
+ CreateRotationX(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static void CreateRotationY(double angle, out Matrix4x3d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = 0;
+ result.Row0.Z = -sin;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = sin;
+ result.Row2.Y = 0;
+ result.Row2.Z = cos;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the y-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static Matrix4x3d CreateRotationY(double angle)
+ {
+ Matrix4x3d result;
+ CreateRotationY(angle, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static void CreateRotationZ(double angle, out Matrix4x3d result)
+ {
+ double cos = (double)System.Math.Cos(angle);
+ double sin = (double)System.Math.Sin(angle);
+
+ result.Row0.X = cos;
+ result.Row0.Y = sin;
+ result.Row0.Z = 0;
+ result.Row1.X = -sin;
+ result.Row1.Y = cos;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ }
+
+ ///
+ /// Builds a rotation matrix for a rotation around the z-axis.
+ ///
+ /// The counter-clockwise angle in radians.
+ /// The resulting Matrix4dinstance.
+ public static Matrix4x3d CreateRotationZ(double angle)
+ {
+ Matrix4x3d result;
+ CreateRotationZ(angle, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateTranslation
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4dinstance.
+ public static void CreateTranslation(double x, double y, double z, out Matrix4x3d result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = x;
+ result.Row3.Y = y;
+ result.Row3.Z = z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4dinstance.
+ public static void CreateTranslation(ref Vector3d vector, out Matrix4x3d result)
+ {
+ result.Row0.X = 1;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = 1;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = 1;
+ result.Row3.X = vector.X;
+ result.Row3.Y = vector.Y;
+ result.Row3.Z = vector.Z;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// X translation.
+ /// Y translation.
+ /// Z translation.
+ /// The resulting Matrix4dinstance.
+ public static Matrix4x3d CreateTranslation(double x, double y, double z)
+ {
+ Matrix4x3d result;
+ CreateTranslation(x, y, z, out result);
+ return result;
+ }
+
+ ///
+ /// Creates a translation matrix.
+ ///
+ /// The translation vector.
+ /// The resulting Matrix4dinstance.
+ public static Matrix4x3d CreateTranslation(Vector3d vector)
+ {
+ Matrix4x3d result;
+ CreateTranslation(vector.X, vector.Y, vector.Z, out result);
+ return result;
+ }
+
+ #endregion
+
+ #region CreateScale
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Single scale factor for x,y and z axes
+ /// A scaling matrix
+ public static Matrix4x3d CreateScale(double scale)
+ {
+ return CreateScale(scale, scale, scale);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factors for x,y and z axes
+ /// A scaling matrix
+ public static Matrix4x3d CreateScale(Vector3d scale)
+ {
+ return CreateScale(scale.X, scale.Y, scale.Z);
+ }
+
+ ///
+ /// Build a scaling matrix
+ ///
+ /// Scale factor for x-axis
+ /// Scale factor for y-axis
+ /// Scale factor for z-axis
+ /// A scaling matrix
+ public static Matrix4x3d CreateScale(double x, double y, double z)
+ {
+ Matrix4x3d result;
+ result.Row0.X = x;
+ result.Row0.Y = 0;
+ result.Row0.Z = 0;
+ result.Row1.X = 0;
+ result.Row1.Y = y;
+ result.Row1.Z = 0;
+ result.Row2.X = 0;
+ result.Row2.Y = 0;
+ result.Row2.Z = z;
+ result.Row3.X = 0;
+ result.Row3.Y = 0;
+ result.Row3.Z = 0;
+ return result;
+ }
+
+ #endregion
+
+ #region Multiply Functions
+
+ ///
+ /// This isn't quite a multiply, but the result may be useful in some situations.
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4d Mult(Matrix4x3d left, Matrix3x4d right)
+ {
+ Matrix4d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// This isn't quite a multiply, but the result may be useful in some situations.
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3d left, ref Matrix3x4d right, out Matrix4d 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,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z,
+ rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W,
+ rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W,
+ rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W;
+
+ 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.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34);
+ 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.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34);
+ 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);
+ result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34);
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31);
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32);
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33);
+ result.Row3.W = (lM41 * rM14) + (lM42 * rM24) + (lM43 * rM34);
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4x3d Mult(Matrix4x3d left, Matrix4x3d right)
+ {
+ Matrix4x3d result;
+ Mult(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies two instances.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d 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,
+ lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.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,
+ rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z;
+
+ result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + rM41;
+ result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + rM42;
+ result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + rM43;
+ result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + rM41;
+ result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + rM42;
+ result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + rM43;
+ result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + rM41;
+ result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + rM42;
+ result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + rM43;
+ result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31) + rM41;
+ result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32) + rM42;
+ result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33) + rM43;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static Matrix4x3d Mult(Matrix4x3d left, double right)
+ {
+ Matrix4x3d result;
+ Mult(ref left, right, out result);
+ return result;
+ }
+
+ ///
+ /// Multiplies an instance by a scalar.
+ ///
+ /// The left operand of the multiplication.
+ /// The right operand of the multiplication.
+ /// A new instance that is the result of the multiplication
+ public static void Mult(ref Matrix4x3d left, double right, out Matrix4x3d result)
+ {
+ result.Row0 = left.Row0 * right;
+ result.Row1 = left.Row1 * right;
+ result.Row2 = left.Row2 * right;
+ result.Row3 = left.Row3 * right;
+ }
+
+ #endregion
+
+ #region Add Functions
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static Matrix4x3d Add(Matrix4x3d left, Matrix4x3d right)
+ {
+ Matrix4x3d result;
+ Add(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Adds two instances.
+ ///
+ /// The left operand of the addition.
+ /// The right operand of the addition.
+ /// A new instance that is the result of the addition.
+ public static void Add(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d result)
+ {
+ result.Row0 = left.Row0 + right.Row0;
+ result.Row1 = left.Row1 + right.Row1;
+ result.Row2 = left.Row2 + right.Row2;
+ result.Row3 = left.Row3 + right.Row3;
+ }
+
+ #endregion
+
+ #region Subtract Functions
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static Matrix4x3d Subtract(Matrix4x3d left, Matrix4x3d right)
+ {
+ Matrix4x3d result;
+ Subtract(ref left, ref right, out result);
+ return result;
+ }
+
+ ///
+ /// Subtracts one instance from another.
+ ///
+ /// The left operand of the subraction.
+ /// The right operand of the subraction.
+ /// A new instance that is the result of the subraction.
+ public static void Subtract(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d result)
+ {
+ result.Row0 = left.Row0 - right.Row0;
+ result.Row1 = left.Row1 - right.Row1;
+ result.Row2 = left.Row2 - right.Row2;
+ result.Row3 = left.Row3 - right.Row3;
+ }
+
+ #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 Matrix4 is singular.
+ public static Matrix4x3d Invert(Matrix4x3d mat)
+ {
+ Matrix4x3d result;
+ Invert(ref mat, out result);
+ return result;
+ }
+
+ ///
+ /// 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 void Invert(ref Matrix4x3d mat, out Matrix4x3d result)
+ {
+ Matrix3d inverseRotation = new Matrix3d(mat.Column0.Xyz, mat.Column1.Xyz, mat.Column2.Xyz);
+ inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared;
+ inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared;
+ inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared;
+
+ Vector3d translation = mat.Row3;
+
+ result.Row0 = inverseRotation.Row0;
+ result.Row1 = inverseRotation.Row1;
+ result.Row2 = inverseRotation.Row2;
+ result.Row3 = new Vector3d(-Vector3d.Dot(inverseRotation.Row0, translation), -Vector3d.Dot(inverseRotation.Row1, translation), -Vector3d.Dot(inverseRotation.Row2, translation));
+ }
+
+ #endregion
+
+ #region Transpose
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The transpose of the given matrix
+ public static Matrix3x4d Transpose(Matrix4x3d mat)
+ {
+ return new Matrix3x4d(mat.Column0, mat.Column1, mat.Column2);
+ }
+
+ ///
+ /// Calculate the transpose of the given matrix
+ ///
+ /// The matrix to transpose
+ /// The result of the calculation
+ public static void Transpose(ref Matrix4x3d mat, out Matrix3x4d result)
+ {
+ result.Row0 = mat.Column0;
+ result.Row1 = mat.Column1;
+ result.Row2 = mat.Column2;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4d which holds the result of the multiplication
+ public static Matrix4d operator *(Matrix4x3d left, Matrix3x4d right)
+ {
+ return Matrix4x3d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3d which holds the result of the multiplication
+ public static Matrix4x3d operator *(Matrix4x3d left, Matrix4x3d right)
+ {
+ return Matrix4x3d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix-scalar multiplication
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3d which holds the result of the multiplication
+ public static Matrix4x3d operator *(Matrix4x3d left, double right)
+ {
+ return Matrix4x3d.Mult(left, right);
+ }
+
+ ///
+ /// Matrix addition
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3d which holds the result of the addition
+ public static Matrix4x3d operator +(Matrix4x3d left, Matrix4x3d right)
+ {
+ return Matrix4x3d.Add(left, right);
+ }
+
+ ///
+ /// Matrix subtraction
+ ///
+ /// left-hand operand
+ /// right-hand operand
+ /// A new Matrix4x3d which holds the result of the subtraction
+ public static Matrix4x3d operator -(Matrix4x3d left, Matrix4x3d right)
+ {
+ return Matrix4x3d.Subtract(left, right);
+ }
+
+ ///
+ /// Compares two instances for equality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left equals right; false otherwise.
+ public static bool operator ==(Matrix4x3d left, Matrix4x3d right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares two instances for inequality.
+ ///
+ /// The first instance.
+ /// The second instance.
+ /// True, if left does not equal right; false otherwise.
+ public static bool operator !=(Matrix4x3d left, Matrix4x3d right)
+ {
+ return !left.Equals(right);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ #region public override string ToString()
+
+ ///
+ /// Returns a System.String that represents the current Matrix4x3d.
+ ///
+ /// 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 tresult.
+ /// True if the instances are equal; false otherwise.
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Matrix4x3d))
+ return false;
+
+ return this.Equals((Matrix4x3d)obj);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+
+ #region IEquatable Members
+
+ /// Indicates whether the current matrix is equal to another matrix.
+ /// An matrix to compare with this matrix.
+ /// true if the current matrix is equal to the matrix parameter; otherwise, false.
+ public bool Equals(Matrix4x3d other)
+ {
+ return
+ Row0 == other.Row0 &&
+ Row1 == other.Row1 &&
+ Row2 == other.Row2 &&
+ Row3 == other.Row3;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Math/Quaternion.cs b/Source/OpenTK/Math/Quaternion.cs
index 8ee0fc01..5913e1dd 100644
--- a/Source/OpenTK/Math/Quaternion.cs
+++ b/Source/OpenTK/Math/Quaternion.cs
@@ -189,6 +189,34 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Quaternion scaled to unit length.
+ ///
+ public Quaternion Normalized()
+ {
+ Quaternion q = this;
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Reverses the rotation angle of this Quaterniond.
+ ///
+ public void Invert()
+ {
+ W = -W;
+ }
+
+ ///
+ /// Returns a copy of this Quaterniond with its rotation angle reversed.
+ ///
+ public Quaternion Inverted()
+ {
+ var q = this;
+ q.Invert();
+ return q;
+ }
+
#region public void Normalize()
///
@@ -206,7 +234,7 @@ namespace OpenTK
#region public void Conjugate()
///
- /// Convert this quaternion to its conjugate
+ /// Inverts the Vector3 component of this Quaternion.
///
public void Conjugate()
{
@@ -224,7 +252,7 @@ namespace OpenTK
///
/// Defines the identity quaternion.
///
- public static Quaternion Identity = new Quaternion(0, 0, 0, 1);
+ public static readonly Quaternion Identity = new Quaternion(0, 0, 0, 1);
#endregion
@@ -461,7 +489,7 @@ namespace OpenTK
///
/// The axis to rotate about
/// The rotation angle in radians
- ///
+ /// The equivalent quaternion
public static Quaternion FromAxisAngle(Vector3 axis, float angle)
{
if (axis.LengthSquared == 0.0f)
@@ -479,6 +507,78 @@ namespace OpenTK
#endregion
+ #region FromMatrix
+
+ ///
+ /// Builds a quaternion from the given rotation matrix
+ ///
+ /// A rotation matrix
+ /// The equivalent quaternion
+ public static Quaternion FromMatrix(Matrix3 matrix)
+ {
+ Quaternion result;
+ FromMatrix(ref matrix, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a quaternion from the given rotation matrix
+ ///
+ /// A rotation matrix
+ /// The equivalent quaternion
+ public static void FromMatrix(ref Matrix3 matrix, out Quaternion result)
+ {
+ float trace = matrix.Trace;
+
+ if (trace > 0)
+ {
+ float s = (float)Math.Sqrt(trace + 1) * 2;
+ float invS = 1f / s;
+
+ result.w = s * 0.25f;
+ result.xyz.X = (matrix.Row2.Y - matrix.Row1.Z) * invS;
+ result.xyz.Y = (matrix.Row0.Z - matrix.Row2.X) * invS;
+ result.xyz.Z = (matrix.Row1.X - matrix.Row0.Y) * invS;
+ }
+ else
+ {
+ float m00 = matrix.Row0.X, m11 = matrix.Row1.Y, m22 = matrix.Row2.Z;
+
+ if (m00 > m11 && m00 > m22)
+ {
+ float s = (float)Math.Sqrt(1 + m00 - m11 - m22) * 2;
+ float invS = 1f / s;
+
+ result.w = (matrix.Row2.Y - matrix.Row1.Z) * invS;
+ result.xyz.X = s * 0.25f;
+ result.xyz.Y = (matrix.Row0.Y + matrix.Row1.X) * invS;
+ result.xyz.Z = (matrix.Row0.Z + matrix.Row2.X) * invS;
+ }
+ else if (m11 > m22)
+ {
+ float s = (float)Math.Sqrt(1 + m11 - m00 - m22) * 2;
+ float invS = 1f / s;
+
+ result.w = (matrix.Row0.Z - matrix.Row2.X) * invS;
+ result.xyz.X = (matrix.Row0.Y + matrix.Row1.X) * invS;
+ result.xyz.Y = s * 0.25f;
+ result.xyz.Z = (matrix.Row1.Z + matrix.Row2.Y) * invS;
+ }
+ else
+ {
+ float s = (float)Math.Sqrt(1 + m22 - m00 - m11) * 2;
+ float invS = 1f / s;
+
+ result.w = (matrix.Row1.X - matrix.Row0.Y) * invS;
+ result.xyz.X = (matrix.Row0.Z + matrix.Row2.X) * invS;
+ result.xyz.Y = (matrix.Row1.Z + matrix.Row2.Y) * invS;
+ result.xyz.Z = s * 0.25f;
+ }
+ }
+ }
+
+ #endregion
+
#region Slerp
///
diff --git a/Source/OpenTK/Math/Quaterniond.cs b/Source/OpenTK/Math/Quaterniond.cs
index 46aec949..9806f694 100644
--- a/Source/OpenTK/Math/Quaterniond.cs
+++ b/Source/OpenTK/Math/Quaterniond.cs
@@ -189,6 +189,34 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Quaterniond scaled to unit length.
+ ///
+ public Quaterniond Normalized()
+ {
+ Quaterniond q = this;
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Reverses the rotation angle of this Quaterniond.
+ ///
+ public void Invert()
+ {
+ W = -W;
+ }
+
+ ///
+ /// Returns a copy of this Quaterniond with its rotation angle reversed.
+ ///
+ public Quaterniond Inverted()
+ {
+ var q = this;
+ q.Invert();
+ return q;
+ }
+
#region public void Normalize()
///
@@ -206,7 +234,7 @@ namespace OpenTK
#region public void Conjugate()
///
- /// Convert this Quaterniond to its conjugate
+ /// Inverts the Vector3d component of this Quaterniond.
///
public void Conjugate()
{
@@ -479,6 +507,78 @@ namespace OpenTK
#endregion
+ #region FromMatrix
+
+ ///
+ /// Builds a quaternion from the given rotation matrix
+ ///
+ /// A rotation matrix
+ /// The equivalent quaternion
+ public static Quaterniond FromMatrix(Matrix3d matrix)
+ {
+ Quaterniond result;
+ FromMatrix(ref matrix, out result);
+ return result;
+ }
+
+ ///
+ /// Builds a quaternion from the given rotation matrix
+ ///
+ /// A rotation matrix
+ /// The equivalent quaternion
+ public static void FromMatrix(ref Matrix3d matrix, out Quaterniond result)
+ {
+ double trace = matrix.Trace;
+
+ if (trace > 0)
+ {
+ double s = Math.Sqrt(trace + 1) * 2;
+ double invS = 1.0 / s;
+
+ result.w = s * 0.25;
+ result.xyz.X = (matrix.Row2.Y - matrix.Row1.Z) * invS;
+ result.xyz.Y = (matrix.Row0.Z - matrix.Row2.X) * invS;
+ result.xyz.Z = (matrix.Row1.X - matrix.Row0.Y) * invS;
+ }
+ else
+ {
+ double m00 = matrix.Row0.X, m11 = matrix.Row1.Y, m22 = matrix.Row2.Z;
+
+ if (m00 > m11 && m00 > m22)
+ {
+ double s = Math.Sqrt(1 + m00 - m11 - m22) * 2;
+ double invS = 1.0 / s;
+
+ result.w = (matrix.Row2.Y - matrix.Row1.Z) * invS;
+ result.xyz.X = s * 0.25;
+ result.xyz.Y = (matrix.Row0.Y + matrix.Row1.X) * invS;
+ result.xyz.Z = (matrix.Row0.Z + matrix.Row2.X) * invS;
+ }
+ else if (m11 > m22)
+ {
+ double s = Math.Sqrt(1 + m11 - m00 - m22) * 2;
+ double invS = 1.0 / s;
+
+ result.w = (matrix.Row0.Z - matrix.Row2.X) * invS;
+ result.xyz.X = (matrix.Row0.Y + matrix.Row1.X) * invS;
+ result.xyz.Y = s * 0.25;
+ result.xyz.Z = (matrix.Row1.Z + matrix.Row2.Y) * invS;
+ }
+ else
+ {
+ double s = Math.Sqrt(1 + m22 - m00 - m11) * 2;
+ double invS = 1.0 / s;
+
+ result.w = (matrix.Row1.X - matrix.Row0.Y) * invS;
+ result.xyz.X = (matrix.Row0.Z + matrix.Row2.X) * invS;
+ result.xyz.Y = (matrix.Row1.Z + matrix.Row2.Y) * invS;
+ result.xyz.Z = s * 0.25;
+ }
+ }
+ }
+
+ #endregion
+
#region Slerp
///
diff --git a/Source/OpenTK/Math/Vector2.cs b/Source/OpenTK/Math/Vector2.cs
index 7c8dabf8..1ccc885e 100644
--- a/Source/OpenTK/Math/Vector2.cs
+++ b/Source/OpenTK/Math/Vector2.cs
@@ -24,6 +24,8 @@ SOFTWARE.
using System;
using System.Runtime.InteropServices;
+using System.Xml.Serialization;
+
namespace OpenTK
{
/// Represents a 2D vector using two single-precision floating-point numbers.
@@ -108,6 +110,21 @@ namespace OpenTK
#region Public Members
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public float this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
+
#region Instance
#region public void Add()
@@ -272,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()
///
@@ -824,6 +851,32 @@ namespace OpenTK
#endregion
+ #region PerpDot
+
+ ///
+ /// Calculate the perpendicular dot (scalar) product of two vectors
+ ///
+ /// First operand
+ /// Second operand
+ /// The perpendicular dot product of the two inputs
+ public static float PerpDot(Vector2 left, Vector2 right)
+ {
+ return left.X * right.Y - left.Y * right.X;
+ }
+
+ ///
+ /// Calculate the perpendicular dot (scalar) product of two vectors
+ ///
+ /// First operand
+ /// Second operand
+ /// The perpendicular dot product of the two inputs
+ public static void PerpDot(ref Vector2 left, ref Vector2 right, out float result)
+ {
+ result = left.X * right.Y - left.Y * right.X;
+ }
+
+ #endregion
+
#region Lerp
///
@@ -930,6 +983,16 @@ namespace OpenTK
#endregion
+ #region Swizzle
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ #endregion
+
#region Operators
///
@@ -1038,13 +1101,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current Vector2.
///
///
public override string ToString()
{
- return String.Format("({0}, {1})", X, Y);
+ return String.Format("({0}{2} {1})", X, Y, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector2d.cs b/Source/OpenTK/Math/Vector2d.cs
index 5305a185..76140079 100644
--- a/Source/OpenTK/Math/Vector2d.cs
+++ b/Source/OpenTK/Math/Vector2d.cs
@@ -24,6 +24,7 @@ SOFTWARE.
using System;
using System.Runtime.InteropServices;
+using System.Xml.Serialization;
namespace OpenTK
{
@@ -43,17 +44,17 @@ namespace OpenTK
///
/// Defines a unit-length Vector2d that points towards the X-axis.
///
- public static Vector2d UnitX = new Vector2d(1, 0);
+ public static readonly Vector2d UnitX = new Vector2d(1, 0);
///
/// Defines a unit-length Vector2d that points towards the Y-axis.
///
- public static Vector2d UnitY = new Vector2d(0, 1);
+ public static readonly Vector2d UnitY = new Vector2d(0, 1);
///
/// Defines a zero-length Vector2d.
///
- public static Vector2d Zero = new Vector2d(0, 0);
+ public static readonly Vector2d Zero = new Vector2d(0, 0);
///
/// Defines an instance with all components set to 1.
@@ -92,6 +93,21 @@ namespace OpenTK
#region Public Members
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public double this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
+
#region Instance
#region public void Add()
@@ -233,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()
///
@@ -818,6 +845,16 @@ namespace OpenTK
#endregion
+ #region Swizzle
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ #endregion
+
#region Operators
///
@@ -942,13 +979,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current instance.
///
///
public override string ToString()
{
- return String.Format("({0}, {1})", X, Y);
+ return String.Format("({0}{2} {1})", X, Y, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector2h.cs b/Source/OpenTK/Math/Vector2h.cs
index 0ac6d509..57ab67ad 100644
--- a/Source/OpenTK/Math/Vector2h.cs
+++ b/Source/OpenTK/Math/Vector2h.cs
@@ -26,6 +26,7 @@ using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
+using System.Xml.Serialization;
namespace OpenTK
{
@@ -192,6 +193,16 @@ namespace OpenTK
#endregion Constructors
+ #region Swizzle
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ #endregion
+
#region Half -> Single
///
@@ -312,10 +323,11 @@ namespace OpenTK
#region ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
/// Returns a string that contains this Half2's numbers in human-legible form.
public override string ToString()
{
- return String.Format("({0}, {1})", X.ToString(), Y.ToString());
+ return String.Format("({0}{2} {1})", X, Y, listSeparator);
}
#endregion ToString()
diff --git a/Source/OpenTK/Math/Vector3.cs b/Source/OpenTK/Math/Vector3.cs
index 5ce13d85..8ec3565d 100644
--- a/Source/OpenTK/Math/Vector3.cs
+++ b/Source/OpenTK/Math/Vector3.cs
@@ -119,6 +119,24 @@ namespace OpenTK
#region Public Members
+
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public float this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ else if(index == 2) return Z;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else if(index == 2) Z = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
+
#region Instance
#region public void Add()
@@ -259,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()
///
@@ -1195,12 +1223,80 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
///
[XmlIgnore]
public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ #endregion
+
#endregion
#region Operators
@@ -1317,13 +1413,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current Vector3.
///
///
public override string ToString()
{
- return String.Format("({0}, {1}, {2})", X, Y, Z);
+ return String.Format("({0}{3} {1}{3} {2})", X, Y, Z, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector3d.cs b/Source/OpenTK/Math/Vector3d.cs
index 5af1aeb5..70acdb88 100644
--- a/Source/OpenTK/Math/Vector3d.cs
+++ b/Source/OpenTK/Math/Vector3d.cs
@@ -118,6 +118,23 @@ namespace OpenTK
#region Public Members
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public double this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ else if(index == 2) return Z;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else if(index == 2) Z = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
+
#region Instance
#region public void Add()
@@ -258,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()
///
@@ -1193,12 +1221,80 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2d with the X and Y components of this instance.
///
[XmlIgnore]
public Vector2d Xy { get { return new Vector2d(X, Y); } set { X = value.X; Y = value.Y; } }
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Xz { get { return new Vector2d(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yz { get { return new Vector2d(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Zx { get { return new Vector2d(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Zy { get { return new Vector2d(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xzy { get { return new Vector3d(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yxz { get { return new Vector3d(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yzx { get { return new Vector3d(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zxy { get { return new Vector3d(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zyx { get { return new Vector3d(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ #endregion
+
#endregion
#region Operators
@@ -1331,13 +1427,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current Vector3.
///
///
public override string ToString()
{
- return String.Format("({0}, {1}, {2})", X, Y, Z);
+ return String.Format("({0}{3} {1}{3} {2})", X, Y, Z, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector3h.cs b/Source/OpenTK/Math/Vector3h.cs
index 7f417808..ec910cdc 100644
--- a/Source/OpenTK/Math/Vector3h.cs
+++ b/Source/OpenTK/Math/Vector3h.cs
@@ -215,12 +215,80 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance.
///
[XmlIgnore]
public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } }
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Xz { get { return new Vector2h(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yz { get { return new Vector2h(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Zx { get { return new Vector2h(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Zy { get { return new Vector2h(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xzy { get { return new Vector3h(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yxz { get { return new Vector3h(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yzx { get { return new Vector3h(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zxy { get { return new Vector3h(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zyx { get { return new Vector3h(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ #endregion
+
#endregion
#region Half -> Single
@@ -355,10 +423,11 @@ namespace OpenTK
#region ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
/// Returns a string that contains this Half3's numbers in human-legible form.
public override string ToString()
{
- return String.Format("({0}, {1}, {2})", X.ToString(), Y.ToString(), Z.ToString());
+ return String.Format("({0}{3} {1}{3} {2})", X.ToString(), Y.ToString(), Z.ToString(), listSeparator);
}
#endregion ToString()
diff --git a/Source/OpenTK/Math/Vector4.cs b/Source/OpenTK/Math/Vector4.cs
index 384fdf74..5cb57992 100644
--- a/Source/OpenTK/Math/Vector4.cs
+++ b/Source/OpenTK/Math/Vector4.cs
@@ -60,27 +60,27 @@ namespace OpenTK
///
/// Defines a unit-length Vector4 that points towards the X-axis.
///
- public static Vector4 UnitX = new Vector4(1, 0, 0, 0);
+ public static readonly Vector4 UnitX = new Vector4(1, 0, 0, 0);
///
/// Defines a unit-length Vector4 that points towards the Y-axis.
///
- public static Vector4 UnitY = new Vector4(0, 1, 0, 0);
+ public static readonly Vector4 UnitY = new Vector4(0, 1, 0, 0);
///
/// Defines a unit-length Vector4 that points towards the Z-axis.
///
- public static Vector4 UnitZ = new Vector4(0, 0, 1, 0);
+ public static readonly Vector4 UnitZ = new Vector4(0, 0, 1, 0);
///
/// Defines a unit-length Vector4 that points towards the W-axis.
///
- public static Vector4 UnitW = new Vector4(0, 0, 0, 1);
+ public static readonly Vector4 UnitW = new Vector4(0, 0, 0, 1);
///
/// Defines a zero-length Vector4.
///
- public static Vector4 Zero = new Vector4(0, 0, 0, 0);
+ public static readonly Vector4 Zero = new Vector4(0, 0, 0, 0);
///
/// Defines an instance with all components set to 1.
@@ -178,6 +178,25 @@ namespace OpenTK
#region Public Members
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public float this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ else if(index == 2) return Z;
+ else if(index == 3) return W;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else if(index == 2) Z = value;
+ else if(index == 3) W = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
+
#region Instance
#region public void Add()
@@ -324,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()
///
@@ -991,6 +1020,8 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
///
@@ -998,11 +1029,387 @@ namespace OpenTK
public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
///
- /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
+ /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the X and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Xw { get { return new Vector2(X, W); } set { X = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Y and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Yw { get { return new Vector2(Y, W); } set { Y = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets an OpenTK.Vector2 with the Z and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Zw { get { return new Vector2(Z, W); } set { Z = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the W and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Wx { get { return new Vector2(W, X); } set { W = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the W and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Wy { get { return new Vector2(W, Y); } set { W = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2 with the W and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2 Wz { get { return new Vector2(W, Z); } set { W = value.X; Z = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
///
[XmlIgnore]
public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xyw { get { return new Vector3(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xzw { get { return new Vector3(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xwy { get { return new Vector3(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Xwz { get { return new Vector3(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yxw { get { return new Vector3(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Yzw { get { return new Vector3(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Ywx { get { return new Vector3(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets an OpenTK.Vector3 with the Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Ywz { get { return new Vector3(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zxw { get { return new Vector3(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zyw { get { return new Vector3(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zwx { get { return new Vector3(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Zwy { get { return new Vector3(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wxy { get { return new Vector3(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wxz { get { return new Vector3(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wyx { get { return new Vector3(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wyz { get { return new Vector3(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wzx { get { return new Vector3(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3 with the W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3 Wzy { get { return new Vector3(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } }
+
+ #endregion
+
+ #region 4-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the X, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Xywz { get { return new Vector4(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the X, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Xzyw { get { return new Vector4(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the X, Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Xzwy { get { return new Vector4(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the X, W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Xwyz { get { return new Vector4(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the X, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Xwzy { get { return new Vector4(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yxzw { get { return new Vector4(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yxwz { get { return new Vector4(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4 with the Y, Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yyzw { get { return new Vector4(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4 with the Y, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yywz { get { return new Vector4(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yzxw { get { return new Vector4(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Yzwx { get { return new Vector4(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Ywxz { get { return new Vector4(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Y, W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Ywzx { get { return new Vector4(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zxyw { get { return new Vector4(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zxwy { get { return new Vector4(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zyxw { get { return new Vector4(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zywx { get { return new Vector4(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zwxy { get { return new Vector4(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the Z, W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zwyx { get { return new Vector4(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4 with the Z, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Zwzy { get { return new Vector4(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wxyz { get { return new Vector4(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wxzy { get { return new Vector4(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wyxz { get { return new Vector4(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wyzx { get { return new Vector4(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wzxy { get { return new Vector4(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4 with the W, Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wzyx { get { return new Vector4(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4 with the W, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4 Wzyw { get { return new Vector4(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ #endregion
+
#endregion
#region Operators
@@ -1149,13 +1556,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current Vector4.
///
///
public override string ToString()
{
- return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
+ return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector4d.cs b/Source/OpenTK/Math/Vector4d.cs
index 95eec840..6389e48b 100644
--- a/Source/OpenTK/Math/Vector4d.cs
+++ b/Source/OpenTK/Math/Vector4d.cs
@@ -58,27 +58,27 @@ namespace OpenTK
///
/// Defines a unit-length Vector4d that points towards the X-axis.
///
- public static Vector4d UnitX = new Vector4d(1, 0, 0, 0);
+ public static readonly Vector4d UnitX = new Vector4d(1, 0, 0, 0);
///
/// Defines a unit-length Vector4d that points towards the Y-axis.
///
- public static Vector4d UnitY = new Vector4d(0, 1, 0, 0);
+ public static readonly Vector4d UnitY = new Vector4d(0, 1, 0, 0);
///
/// Defines a unit-length Vector4d that points towards the Z-axis.
///
- public static Vector4d UnitZ = new Vector4d(0, 0, 1, 0);
+ public static readonly Vector4d UnitZ = new Vector4d(0, 0, 1, 0);
///
/// Defines a unit-length Vector4d that points towards the W-axis.
///
- public static Vector4d UnitW = new Vector4d(0, 0, 0, 1);
+ public static readonly Vector4d UnitW = new Vector4d(0, 0, 0, 1);
///
/// Defines a zero-length Vector4d.
///
- public static Vector4d Zero = new Vector4d(0, 0, 0, 0);
+ public static readonly Vector4d Zero = new Vector4d(0, 0, 0, 0);
///
/// Defines an instance with all components set to 1.
@@ -175,6 +175,25 @@ namespace OpenTK
#endregion
#region Public Members
+
+ ///
+ /// Gets or sets the value at the index of the Vector.
+ ///
+ public double this[int index] {
+ get{
+ if(index == 0) return X;
+ else if(index == 1) return Y;
+ else if(index == 2) return Z;
+ else if(index == 3) return W;
+ throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
+ } set{
+ if(index == 0) X = value;
+ else if(index == 1) Y = value;
+ else if(index == 2) Z = value;
+ else if(index == 3) W = value;
+ else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
+ }
+ }
#region Instance
@@ -321,6 +340,16 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector4d scaled to unit length.
+ ///
+ public Vector4d Normalized()
+ {
+ Vector4d v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
@@ -994,6 +1023,8 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2d with the X and Y components of this instance.
///
@@ -1001,11 +1032,387 @@ namespace OpenTK
public Vector2d Xy { get { return new Vector2d(X, Y); } set { X = value.X; Y = value.Y; } }
///
- /// Gets or sets an OpenTK.Vector3d with the X, Y and Z components of this instance.
+ /// Gets or sets an OpenTK.Vector2d with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Xz { get { return new Vector2d(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the X and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Xw { get { return new Vector2d(X, W); } set { X = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yz { get { return new Vector2d(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Y and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Yw { get { return new Vector2d(Y, W); } set { Y = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Zx { get { return new Vector2d(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Zy { get { return new Vector2d(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets an OpenTK.Vector2d with the Z and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Zw { get { return new Vector2d(Z, W); } set { Z = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the W and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Wx { get { return new Vector2d(W, X); } set { W = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the W and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Wy { get { return new Vector2d(W, Y); } set { W = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2d with the W and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2d Wz { get { return new Vector2d(W, Z); } set { W = value.X; Z = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, Y, and Z components of this instance.
///
[XmlIgnore]
public Vector3d Xyz { get { return new Vector3d(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xyw { get { return new Vector3d(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xzy { get { return new Vector3d(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xzw { get { return new Vector3d(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xwy { get { return new Vector3d(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Xwz { get { return new Vector3d(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yxz { get { return new Vector3d(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yxw { get { return new Vector3d(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yzx { get { return new Vector3d(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Yzw { get { return new Vector3d(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Ywx { get { return new Vector3d(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets an OpenTK.Vector3d with the Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Ywz { get { return new Vector3d(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zxy { get { return new Vector3d(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zxw { get { return new Vector3d(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zyx { get { return new Vector3d(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zyw { get { return new Vector3d(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zwx { get { return new Vector3d(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Zwy { get { return new Vector3d(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wxy { get { return new Vector3d(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wxz { get { return new Vector3d(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wyx { get { return new Vector3d(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wyz { get { return new Vector3d(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wzx { get { return new Vector3d(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3d with the W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3d Wzy { get { return new Vector3d(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } }
+
+ #endregion
+
+ #region 4-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the X, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Xywz { get { return new Vector4d(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the X, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Xzyw { get { return new Vector4d(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the X, Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Xzwy { get { return new Vector4d(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the X, W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Xwyz { get { return new Vector4d(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the X, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Xwzy { get { return new Vector4d(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yxzw { get { return new Vector4d(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yxwz { get { return new Vector4d(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4d with the Y, Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yyzw { get { return new Vector4d(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4d with the Y, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yywz { get { return new Vector4d(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yzxw { get { return new Vector4d(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Yzwx { get { return new Vector4d(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Ywxz { get { return new Vector4d(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Y, W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Ywzx { get { return new Vector4d(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zxyw { get { return new Vector4d(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zxwy { get { return new Vector4d(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zyxw { get { return new Vector4d(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zywx { get { return new Vector4d(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zwxy { get { return new Vector4d(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the Z, W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zwyx { get { return new Vector4d(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4d with the Z, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Zwzy { get { return new Vector4d(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wxyz { get { return new Vector4d(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wxzy { get { return new Vector4d(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wyxz { get { return new Vector4d(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wyzx { get { return new Vector4d(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wzxy { get { return new Vector4d(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4d with the W, Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wzyx { get { return new Vector4d(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4d with the W, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4d Wzyw { get { return new Vector4d(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ #endregion
+
#endregion
#region Operators
@@ -1168,13 +1575,14 @@ namespace OpenTK
#region public override string ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
///
/// Returns a System.String that represents the current Vector4d.
///
///
public override string ToString()
{
- return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
+ return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator);
}
#endregion
diff --git a/Source/OpenTK/Math/Vector4h.cs b/Source/OpenTK/Math/Vector4h.cs
index 4a7f83a6..26e547fb 100644
--- a/Source/OpenTK/Math/Vector4h.cs
+++ b/Source/OpenTK/Math/Vector4h.cs
@@ -234,6 +234,8 @@ namespace OpenTK
#region Swizzle
+ #region 2-component
+
///
/// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance.
///
@@ -241,11 +243,387 @@ namespace OpenTK
public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } }
///
- /// Gets or sets an OpenTK.Vector3h with the X, Y and Z components of this instance.
+ /// Gets or sets an OpenTK.Vector2h with the X and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Xz { get { return new Vector2h(X, Z); } set { X = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the X and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Xw { get { return new Vector2h(X, W); } set { X = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yz { get { return new Vector2h(Y, Z); } set { Y = value.X; Z = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Y and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Yw { get { return new Vector2h(Y, W); } set { Y = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Z and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Zx { get { return new Vector2h(Z, X); } set { Z = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the Z and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Zy { get { return new Vector2h(Z, Y); } set { Z = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets an OpenTK.Vector2h with the Z and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Zw { get { return new Vector2h(Z, W); } set { Z = value.X; W = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the W and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Wx { get { return new Vector2h(W, X); } set { W = value.X; X = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the W and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Wy { get { return new Vector2h(W, Y); } set { W = value.X; Y = value.Y; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector2h with the W and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector2h Wz { get { return new Vector2h(W, Z); } set { W = value.X; Z = value.Y; } }
+
+ #endregion
+
+ #region 3-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, Y, and Z components of this instance.
///
[XmlIgnore]
public Vector3h Xyz { get { return new Vector3h(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xyw { get { return new Vector3h(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xzy { get { return new Vector3h(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xzw { get { return new Vector3h(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xwy { get { return new Vector3h(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Xwz { get { return new Vector3h(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yxz { get { return new Vector3h(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yxw { get { return new Vector3h(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yzx { get { return new Vector3h(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Yzw { get { return new Vector3h(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Ywx { get { return new Vector3h(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets an OpenTK.Vector3h with the Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Ywz { get { return new Vector3h(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zxy { get { return new Vector3h(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zxw { get { return new Vector3h(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zyx { get { return new Vector3h(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zyw { get { return new Vector3h(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zwx { get { return new Vector3h(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Zwy { get { return new Vector3h(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wxy { get { return new Vector3h(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wxz { get { return new Vector3h(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wyx { get { return new Vector3h(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wyz { get { return new Vector3h(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wzx { get { return new Vector3h(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector3h with the W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector3h Wzy { get { return new Vector3h(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } }
+
+ #endregion
+
+ #region 4-component
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the X, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Xywz { get { return new Vector4h(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the X, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Xzyw { get { return new Vector4h(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the X, Z, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Xzwy { get { return new Vector4h(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the X, W, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Xwyz { get { return new Vector4h(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the X, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Xwzy { get { return new Vector4h(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, X, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yxzw { get { return new Vector4h(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, X, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yxwz { get { return new Vector4h(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4h with the Y, Y, Z, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yyzw { get { return new Vector4h(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4h with the Y, Y, W, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yywz { get { return new Vector4h(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, Z, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yzxw { get { return new Vector4h(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, Z, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Yzwx { get { return new Vector4h(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, W, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Ywxz { get { return new Vector4h(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Y, W, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Ywzx { get { return new Vector4h(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zxyw { get { return new Vector4h(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, X, W, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zxwy { get { return new Vector4h(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, Y, X, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zyxw { get { return new Vector4h(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, Y, W, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zywx { get { return new Vector4h(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, W, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zwxy { get { return new Vector4h(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the Z, W, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zwyx { get { return new Vector4h(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4h with the Z, W, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Zwzy { get { return new Vector4h(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, X, Y, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wxyz { get { return new Vector4h(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, X, Z, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wxzy { get { return new Vector4h(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, Y, X, and Z components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wyxz { get { return new Vector4h(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, Y, Z, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wyzx { get { return new Vector4h(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, Z, X, and Y components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wzxy { get { return new Vector4h(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } }
+
+ ///
+ /// Gets or sets an OpenTK.Vector4h with the W, Z, Y, and X components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wzyx { get { return new Vector4h(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } }
+
+ ///
+ /// Gets an OpenTK.Vector4h with the W, Z, Y, and W components of this instance.
+ ///
+ [XmlIgnore]
+ public Vector4h Wzyw { get { return new Vector4h(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
+
+ #endregion
+
#endregion
#region Half -> Single
@@ -386,10 +764,11 @@ namespace OpenTK
#region ToString()
+ private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
/// Returns a string that contains this Half4's numbers in human-legible form.
public override string ToString()
{
- return String.Format("({0}, {1}, {2}, {3})", X.ToString(), Y.ToString(), Z.ToString(), W.ToString());
+ return String.Format("({0}{4} {1}{4} {2}{4} {3})", X.ToString(), Y.ToString(), Z.ToString(), W.ToString(), listSeparator);
}
#endregion ToString()
diff --git a/Source/OpenTK/NativeWindow.cs b/Source/OpenTK/NativeWindow.cs
index 3d67c4bb..38ab3cc6 100644
--- a/Source/OpenTK/NativeWindow.cs
+++ b/Source/OpenTK/NativeWindow.cs
@@ -821,7 +821,7 @@ namespace OpenTK
///
/// Called when a keybord key is released.
///
- /// The for this event.
+ /// The for this event.
protected virtual void OnKeyUp(KeyboardKeyEventArgs e)
{
KeyUp(this, e);
diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj
index 9cd3f603..1e1d14f1 100644
--- a/Source/OpenTK/OpenTK.csproj
+++ b/Source/OpenTK/OpenTK.csproj
@@ -1,4 +1,4 @@
-
+
Local
@@ -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
@@ -136,6 +132,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -769,6 +780,8 @@
+
+
diff --git a/Source/OpenTK/Platform/Factory.cs b/Source/OpenTK/Platform/Factory.cs
index cb9ab3d9..2ce77edf 100644
--- a/Source/OpenTK/Platform/Factory.cs
+++ b/Source/OpenTK/Platform/Factory.cs
@@ -124,6 +124,11 @@ namespace OpenTK.Platform
return default_implementation.CreateMouseDriver();
}
+ public OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ return default_implementation.CreateGamePadDriver();
+ }
+
class UnsupportedPlatform : IPlatformFactory
{
#region Fields
@@ -178,7 +183,12 @@ namespace OpenTK.Platform
{
throw new PlatformNotSupportedException(error_string);
}
-
+
+ public OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ throw new PlatformNotSupportedException(error_string);
+ }
+
#endregion
}
diff --git a/Source/OpenTK/Platform/IPlatformFactory.cs b/Source/OpenTK/Platform/IPlatformFactory.cs
index 94761623..4b968cc9 100644
--- a/Source/OpenTK/Platform/IPlatformFactory.cs
+++ b/Source/OpenTK/Platform/IPlatformFactory.cs
@@ -50,5 +50,7 @@ namespace OpenTK.Platform
OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver();
OpenTK.Input.IMouseDriver2 CreateMouseDriver();
+
+ OpenTK.Input.IGamePadDriver CreateGamePadDriver();
}
}
diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs
index cb6548a3..9dc17fc4 100644
--- a/Source/OpenTK/Platform/MacOS/AglContext.cs
+++ b/Source/OpenTK/Platform/MacOS/AglContext.cs
@@ -475,6 +475,9 @@ namespace OpenTK.Platform.MacOS
// I do not know MacOS allows us to destroy a context from a separate thread,
// like the finalizer thread. It's untested, but worst case is probably
// an exception on application exit, which would be logged to the console.
+
+ // Actually, it seems to crash the mono runtime. -AMK 2013
+
Debug.Print("Destroying context");
if (Agl.aglDestroyContext(Handle.Handle) == true)
{
diff --git a/Source/OpenTK/Platform/MacOS/Application.cs b/Source/OpenTK/Platform/MacOS/Application.cs
index c419a079..a972f1c1 100644
--- a/Source/OpenTK/Platform/MacOS/Application.cs
+++ b/Source/OpenTK/Platform/MacOS/Application.cs
@@ -85,10 +85,26 @@ namespace OpenTK.Platform.MacOS.Carbon
static void ConnectEvents()
{
- EventTypeSpec[] eventTypes = new EventTypeSpec[] { new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited), new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
+ EventTypeSpec[] eventTypes = new EventTypeSpec[] {
+ new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated),
+ new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated),
+ new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
+ new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelScroll),
- new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged), new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent) };
+ new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown),
+ new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
+ new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
+ new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
+ new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent),
+ };
MacOSEventHandler handler = EventHandler;
uppHandler = API.NewEventHandlerUPP(handler);
diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs
index 3b96ae07..be079f95 100644
--- a/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs
+++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs
@@ -246,6 +246,7 @@ namespace OpenTK.Platform.MacOS.Carbon
MouseEntered = 8,
MouseExited = 9,
WheelMoved = 10,
+ WheelScroll = 11,
}
internal enum MouseButton : short
{
@@ -286,8 +287,11 @@ namespace OpenTK.Platform.MacOS.Carbon
WindowMouseLocation = 0x776d6f75, // typeHIPoint
MouseButton = 0x6d62746e, // typeMouseButton
ClickCount = 0x63636e74, // typeUInt32
- MouseWheelAxis = 0x6d776178, // typeMouseWheelAxis
- MouseWheelDelta = 0x6d77646c, // typeSInt32
+ MouseWheelAxis = 0x6d776178, // typeMouseWheelAxis 'mwax'
+ MouseWheelDelta = 0x6d77646c, // typeSInt32 'mwdl'
+ MouseWheelSmoothVerticalDelta = 0x73617879, // typeSInt32 'saxy'
+ MouseWheelSmoothHorizontalDelta = 0x73617878, // typeSInt32 'saxx'
+
MouseDelta = 0x6d647461, // typeHIPoint
// Keyboard events
@@ -712,6 +716,52 @@ namespace OpenTK.Platform.MacOS.Carbon
return (MouseButton)button;
}
+
+ internal struct ScrollDelta {
+ internal float deltaX;
+ internal float deltaY;
+ }
+
+ static internal ScrollDelta GetEventWheelScroll(IntPtr inEvent)
+ {
+ ScrollDelta scrolldelta = new ScrollDelta();
+ Int32 delta;
+
+ unsafe
+ {
+ Int32* d = δ
+ OSStatus result;
+
+ // vertical scroll Delta in pixels
+ result = API.GetEventParameter(inEvent,
+ EventParamName.MouseWheelSmoothVerticalDelta, EventParamType.typeSInt32,
+ IntPtr.Zero, (uint)sizeof(int), IntPtr.Zero, (IntPtr)d);
+
+ if (result == OSStatus.EventParameterNotFound) {
+ // it's okay for it to be simply missing...
+ } else if (result != OSStatus.NoError) {
+ throw new MacOSException(result);
+ } else {
+ scrolldelta.deltaY = delta / 20.0f;
+ }
+
+ // horizontal scroll Delta in pixels
+ result = API.GetEventParameter(inEvent,
+ EventParamName.MouseWheelSmoothHorizontalDelta, EventParamType.typeSInt32,
+ IntPtr.Zero, (uint)sizeof(int), IntPtr.Zero, (IntPtr)d);
+
+ if (result == OSStatus.EventParameterNotFound) {
+ // it's okay for it to be simply missing...
+ } else if (result != OSStatus.NoError) {
+ throw new MacOSException(result);
+ } else {
+ scrolldelta.deltaY = delta / 20.0f;
+ }
+ }
+
+ return scrolldelta;
+ }
+
static internal int GetEventMouseWheelDelta(IntPtr inEvent)
{
int delta;
diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs
index b7fab61b..cd7eaf96 100644
--- a/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs
+++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs
@@ -31,6 +31,9 @@ using System.Text;
namespace OpenTK.Platform.MacOS.Carbon
{
+ //
+ // http://web.archive.org/web/20100501161453/http://www.classicteck.com/rbarticles/mackeyboard.php
+
enum MacOSKeyCode
{
A = 0,
@@ -90,6 +93,13 @@ namespace OpenTK.Platform.MacOS.Carbon
Backspace = 51,
Return = 52,
Esc = 53,
+
+ Command = 55,
+ Shift = 56,
+ CapsLock = 57,
+ OptionAlt = 58,
+ Control = 59,
+
KeyPad_Decimal = 65,
KeyPad_Multiply = 67,
KeyPad_Add = 69,
@@ -107,6 +117,7 @@ namespace OpenTK.Platform.MacOS.Carbon
KeyPad_7 = 89,
KeyPad_8 = 91,
KeyPad_9 = 92,
+
F1 = 122,
F2 = 120,
F3 = 99,
diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
index 01696252..a3fd3b7a 100644
--- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
+++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
@@ -368,6 +368,7 @@ namespace OpenTK.Platform.MacOS
break;
}
+ OpenTK.Input.Key key;
switch (evt.KeyboardEventKind)
{
case KeyboardEventKind.RawKeyRepeat:
@@ -376,25 +377,15 @@ namespace OpenTK.Platform.MacOS
break;
case KeyboardEventKind.RawKeyDown:
- {
- OpenTK.Input.Key key;
- if (Keymap.TryGetValue(code, out key))
- {
- InputDriver.Keyboard[0][key] = true;
- OnKeyPress(mKeyPressArgs);
- }
+ Keymap.TryGetValue(code, out key);
+ InputDriver.Keyboard[0].SetKey(key, (uint)code, true);
+ OnKeyPress(mKeyPressArgs);
return OSStatus.NoError;
- }
case KeyboardEventKind.RawKeyUp:
- {
- OpenTK.Input.Key key;
- if (Keymap.TryGetValue(code, out key))
- {
- InputDriver.Keyboard[0][key] = false;
- }
+ Keymap.TryGetValue(code, out key);
+ InputDriver.Keyboard[0].SetKey(key, (uint)code, false);
return OSStatus.NoError;
- }
case KeyboardEventKind.RawKeyModifiersChanged:
ProcessModifierKey(inEvent);
@@ -519,9 +510,19 @@ namespace OpenTK.Platform.MacOS
}
return OSStatus.NoError;
- case MouseEventKind.WheelMoved:
- float delta = API.GetEventMouseWheelDelta(inEvent);
- InputDriver.Mouse[0].WheelPrecise += delta;
+ case MouseEventKind.WheelMoved: // older, integer resolution only
+ {
+ // this is really an int, we use a float to avoid clipping the wheel value
+ float delta = API.GetEventMouseWheelDelta (inEvent);
+ InputDriver.Mouse[0].WheelPrecise += delta;
+ }
+ return OSStatus.NoError;
+
+ case MouseEventKind.WheelScroll: // newer, more precise X and Y scroll
+ {
+ API.ScrollDelta delta = API.GetEventWheelScroll(inEvent);
+ InputDriver.Mouse[0].WheelPrecise += delta.deltaY;
+ }
return OSStatus.NoError;
case MouseEventKind.MouseMoved:
@@ -614,21 +615,21 @@ namespace OpenTK.Platform.MacOS
Debug.Print("Modifiers Changed: {0}", modifiers);
Input.KeyboardDevice keyboard = InputDriver.Keyboard[0];
-
+
if (keyboard[OpenTK.Input.Key.AltLeft] ^ option)
- keyboard[OpenTK.Input.Key.AltLeft] = option;
+ keyboard.SetKey(OpenTK.Input.Key.AltLeft, (uint)MacOSKeyCode.OptionAlt, option);
if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift)
- keyboard[OpenTK.Input.Key.ShiftLeft] = shift;
+ keyboard.SetKey(OpenTK.Input.Key.ShiftLeft, (uint)MacOSKeyCode.Shift, shift);
if (keyboard[OpenTK.Input.Key.WinLeft] ^ command)
- keyboard[OpenTK.Input.Key.WinLeft] = command;
+ keyboard.SetKey(OpenTK.Input.Key.WinLeft, (uint)MacOSKeyCode.Command, command);
if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control)
- keyboard[OpenTK.Input.Key.ControlLeft] = control;
+ keyboard.SetKey(OpenTK.Input.Key.ControlLeft, (uint)MacOSKeyCode.Control, control);
if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps)
- keyboard[OpenTK.Input.Key.CapsLock] = caps;
+ keyboard.SetKey(OpenTK.Input.Key.CapsLock, (uint)MacOSKeyCode.CapsLock, caps);
}
diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs
index 1a5759a7..c040ff6d 100755
--- a/Source/OpenTK/Platform/MacOS/HIDInput.cs
+++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs
@@ -50,7 +50,7 @@ namespace OpenTK.Platform.MacOS
// Requires Mac OS X 10.5 or higher.
// Todo: create a driver for older installations. Maybe use CGGetLastMouseDelta for that?
- class HIDInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2
+ class HIDInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2/*, IGamePadDriver*/
{
#region Fields
@@ -124,7 +124,7 @@ namespace OpenTK.Platform.MacOS
{
if (!MouseDevices.ContainsKey(device))
{
- Debug.Print("Mouse device {0} discovered", device);
+ Debug.Print("Mouse device {0:x} discovered, sender is {1:x}", device, sender);
MouseState state = new MouseState();
state.IsConnected = true;
MouseIndexToDevice.Add(MouseDevices.Count, device);
@@ -132,7 +132,7 @@ namespace OpenTK.Platform.MacOS
}
else
{
- Debug.Print("Mouse device {0} reconnected", device);
+ Debug.Print("Mouse device {0:x} reconnected, sender is {1:x}", device, sender);
MouseState state = MouseDevices[device];
state.IsConnected = true;
MouseDevices[device] = state;
@@ -144,7 +144,7 @@ namespace OpenTK.Platform.MacOS
{
if (!KeyboardDevices.ContainsKey(device))
{
- Debug.Print("Keyboard device {0} discovered", device);
+ Debug.Print("Keyboard device {0:x} discovered, sender is {1:x}", device, sender);
KeyboardState state = new KeyboardState();
state.IsConnected = true;
KeyboardIndexToDevice.Add(KeyboardDevices.Count, device);
@@ -152,15 +152,18 @@ namespace OpenTK.Platform.MacOS
}
else
{
- Debug.Print("Keyboard device {0} reconnected", device);
+ Debug.Print("Keyboard device {0:x} reconnected, sender is {1:x}", device, sender);
KeyboardState state = KeyboardDevices[device];
state.IsConnected = true;
KeyboardDevices[device] = state;
}
}
+ // The device is not normally available in the InputValueCallback (HandleDeviceValueReceived), so we include
+ // the device identifier as the context variable, so we can identify it and figure out the device later.
+ // Thanks to Jase: http://www.opentk.com/node/2800
NativeMethods.IOHIDDeviceRegisterInputValueCallback(device,
- HandleDeviceValueReceived, IntPtr.Zero);
+ HandleDeviceValueReceived, device);
NativeMethods.IOHIDDeviceScheduleWithRunLoop(device, RunLoop, InputLoopMode);
}
}
@@ -170,7 +173,7 @@ namespace OpenTK.Platform.MacOS
if (NativeMethods.IOHIDDeviceConformsTo(device, HIDPage.GenericDesktop, (int)HIDUsageGD.Mouse) &&
MouseDevices.ContainsKey(device))
{
- Debug.Print("Mouse device {0} disconnected", device);
+ Debug.Print("Mouse device {0:x} disconnected, sender is {1:x}", device, sender);
// Keep the device in case it comes back later on
MouseState state = MouseDevices[device];
@@ -181,7 +184,7 @@ namespace OpenTK.Platform.MacOS
if (NativeMethods.IOHIDDeviceConformsTo(device, HIDPage.GenericDesktop, (int)HIDUsageGD.Keyboard) &&
KeyboardDevices.ContainsKey(device))
{
- Debug.Print("Keyboard device {0} disconnected", device);
+ Debug.Print("Keyboard device {0:x} disconnected, sender is {1:x}", device, sender);
// Keep the device in case it comes back later on
KeyboardState state = KeyboardDevices[device];
@@ -197,13 +200,15 @@ namespace OpenTK.Platform.MacOS
{
MouseState mouse;
KeyboardState keyboard;
- if (MouseDevices.TryGetValue(sender, out mouse))
+ if (MouseDevices.TryGetValue(context, out mouse))
{
- MouseDevices[sender] = UpdateMouse(mouse, val);
+ MouseDevices[context] = UpdateMouse(mouse, val);
}
- else if (KeyboardDevices.TryGetValue(sender, out keyboard))
+ else if (KeyboardDevices.TryGetValue(context, out keyboard))
{
- KeyboardDevices[sender] = UpdateKeyboard(keyboard, val);
+ KeyboardDevices[context] = UpdateKeyboard(keyboard, val);
+ }else{
+ //Debug.Print ("Device {0:x} not found in list of keyboards or mice", sender);
}
}
@@ -249,19 +254,21 @@ namespace OpenTK.Platform.MacOS
int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32();
HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem);
int usage = NativeMethods.IOHIDElementGetUsage(elem);
+
+ // This will supress the debug printing below. Seems like it generates a lot of -1s.
+ // Couldn't find any details in USB spec or Apple docs for this behavior.
+ if(usage < 0 ) return state;
- switch (page)
+ switch (page)
{
case HIDPage.GenericDesktop:
case HIDPage.KeyboardOrKeypad:
- int raw = (int)usage;
- if (raw >= RawKeyMap.Length || raw < 0)
+ if (usage >= RawKeyMap.Length)
{
- Debug.Print("[Warning] Key {0} not mapped.", raw);
+ Debug.Print("[Warning] Key {0} not mapped.", usage);
return state;
}
- Key key = RawKeyMap[raw];
- state[key] = v_int != 0;
+ state.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0);
break;
}
diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
index 066e2879..3bae0c4c 100644
--- a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
+++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
@@ -86,6 +86,11 @@ namespace OpenTK.Platform.MacOS
{
return InputDriver.MouseDriver;
}
+
+ public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ return InputDriver.GamePadDriver;
+ }
#endregion
}
diff --git a/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs
index 49e86033..e80aee52 100644
--- a/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs
+++ b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs
@@ -118,10 +118,10 @@ namespace OpenTK.Platform.MacOS
Add(MacOSKeyCode.Key_2, Key.Number2);
Add(MacOSKeyCode.Key_3, Key.Number3);
Add(MacOSKeyCode.Key_4, Key.Number4);
- Add(MacOSKeyCode.Key_5, Key.Number4);
- Add(MacOSKeyCode.Key_6, Key.Number5);
- Add(MacOSKeyCode.Key_7, Key.Number6);
- Add(MacOSKeyCode.Key_8, Key.Number7);
+ Add(MacOSKeyCode.Key_5, Key.Number5);
+ Add(MacOSKeyCode.Key_6, Key.Number6);
+ Add(MacOSKeyCode.Key_7, Key.Number7);
+ Add(MacOSKeyCode.Key_8, Key.Number8);
Add(MacOSKeyCode.Key_9, Key.Number9);
// Numlock
Add(MacOSKeyCode.O, Key.O);
diff --git a/Source/OpenTK/Platform/Windows/WMInput.cs b/Source/OpenTK/Platform/Windows/WMInput.cs
index 5d3d2ee3..084f20fb 100644
--- a/Source/OpenTK/Platform/Windows/WMInput.cs
+++ b/Source/OpenTK/Platform/Windows/WMInput.cs
@@ -42,7 +42,7 @@ namespace OpenTK.Platform.Windows
// Input driver for legacy (pre XP) Windows platforms.
// Supports a single mouse and keyboard through async input.
// Supports multiple joysticks through WinMM.
- sealed class WMInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2, IGamePadDriver
+ sealed class WMInput : IInputDriver2, IMouseDriver2, IKeyboardDriver2/*, IGamePadDriver*/ //HACK uncomment and implement
{
#region Fields
@@ -70,14 +70,12 @@ namespace OpenTK.Platform.Windows
void UpdateKeyboard()
{
- for (int i = 0; i < 256; i++)
+ for (byte i = 0; i < byte.MaxValue; i++)
{
- VirtualKeys key = (VirtualKeys)i;
- bool pressed = (Functions.GetAsyncKeyState(key) >> 8) != 0;
- if (KeyMap.ContainsKey(key))
- {
- keyboard[KeyMap[key]] = pressed;
- }
+ bool pressed = (Functions.GetAsyncKeyState((VirtualKeys)i) >> 8) != 0;
+ Key key;
+ KeyMap.TryGetValue((VirtualKeys)i,out key);
+ keyboard.SetKeyState(key, i, pressed);
}
}
@@ -111,7 +109,7 @@ namespace OpenTK.Platform.Windows
public IGamePadDriver GamePadDriver
{
- get { return this; }
+ get { return null; } //HACK return this when implemented.
}
#endregion
diff --git a/Source/OpenTK/Platform/Windows/WinFactory.cs b/Source/OpenTK/Platform/Windows/WinFactory.cs
index aa802fdf..c5d8fcc3 100644
--- a/Source/OpenTK/Platform/Windows/WinFactory.cs
+++ b/Source/OpenTK/Platform/Windows/WinFactory.cs
@@ -83,6 +83,11 @@ namespace OpenTK.Platform.Windows
{
return InputDriver.MouseDriver;
}
+
+ public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ return InputDriver.GamePadDriver;
+ }
#endregion
diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs
index 261cfacf..1d8d7498 100644
--- a/Source/OpenTK/Platform/Windows/WinGLNative.cs
+++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs
@@ -89,7 +89,13 @@ namespace OpenTK.Platform.Windows
IList keyboards = new List(1);
IList mice = new List(1);
const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys.
- static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0); // Used to distinguish left and right shift keys.
+
+ public static readonly uint ShiftLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LSHIFT, 0);
+ public static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0);
+ public static readonly uint ControlLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LCONTROL, 0);
+ public static readonly uint ControlRightScanCode = Functions.MapVirtualKey(VirtualKeys.RCONTROL, 0);
+ public static readonly uint AltLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LMENU, 0);
+ public static readonly uint AltRightScanCode = Functions.MapVirtualKey(VirtualKeys.RMENU, 0);
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
@@ -369,6 +375,8 @@ namespace OpenTK.Platform.Windows
// In this case, both keys will be reported as pressed.
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
+ uint scancode = (uint)((lParam.ToInt64() >> 16) & 0xFF);
+ Key key = Key.Unknown;
switch ((VirtualKeys)wParam)
{
case VirtualKeys.SHIFT:
@@ -382,55 +390,50 @@ namespace OpenTK.Platform.Windows
// Otherwise, the state of one key might be stuck to pressed.
if (ShiftRightScanCode != 0 && pressed)
{
- unchecked
- {
- if (((lParam.ToInt64() >> 16) & 0xFF) == ShiftRightScanCode)
- keyboard[Input.Key.ShiftRight] = pressed;
- else
- keyboard[Input.Key.ShiftLeft] = pressed;
- }
+ if (scancode == ShiftRightScanCode)
+ key = Input.Key.ShiftRight;
+ else
+ key = Input.Key.ShiftLeft;
}
else
{
// Windows 9x and NT4.0 or key release event.
- keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
+ keyboard.SetKey(Input.Key.ShiftLeft, ShiftLeftScanCode, pressed);
+ keyboard.SetKey(Input.Key.ShiftRight, ShiftRightScanCode, pressed);
}
- return IntPtr.Zero;
+ break;
case VirtualKeys.CONTROL:
if (extended)
- keyboard[Input.Key.ControlRight] = pressed;
+ key = Input.Key.ControlRight;
else
- keyboard[Input.Key.ControlLeft] = pressed;
- return IntPtr.Zero;
+ key = Input.Key.ControlLeft;
+ break;
case VirtualKeys.MENU:
if (extended)
- keyboard[Input.Key.AltRight] = pressed;
+ key = Input.Key.AltRight;
else
- keyboard[Input.Key.AltLeft] = pressed;
- return IntPtr.Zero;
+ key = Input.Key.AltLeft;
+ break;
case VirtualKeys.RETURN:
if (extended)
- keyboard[Key.KeypadEnter] = pressed;
+ key = Key.KeypadEnter;
else
- keyboard[Key.Enter] = pressed;
- return IntPtr.Zero;
+ key = Key.Enter;
+ break;
default:
if (!KeyMap.ContainsKey((VirtualKeys)wParam))
- {
Debug.Print("Virtual key {0} ({1}) not mapped.", (VirtualKeys)wParam, (long)lParam);
- break;
- }
else
- {
- keyboard[KeyMap[(VirtualKeys)wParam]] = pressed;
- }
- return IntPtr.Zero;
+ key = KeyMap[(VirtualKeys)wParam];
+ break;
}
- break;
+
+ keyboard.SetKey(key, scancode, pressed);
+ return IntPtr.Zero;
case WindowMessage.SYSCHAR:
return IntPtr.Zero;
@@ -727,7 +730,11 @@ namespace OpenTK.Platform.Windows
}
set
{
- ClientSize = value.Size;
+ WindowStyle style = (WindowStyle)Functions.GetWindowLong(window.WindowHandle, GetWindowLongOffsets.STYLE);
+ Win32Rectangle rect = Win32Rectangle.From(value);
+ Functions.AdjustWindowRect(ref rect, style, false);
+ Location = new Point(rect.left, rect.top);
+ Size = new Size(rect.Width, rect.Height);
}
}
diff --git a/Source/OpenTK/Platform/Windows/WinMMJoystick.cs b/Source/OpenTK/Platform/Windows/WinMMJoystick.cs
index ea3c2a5e..32a00c7a 100644
--- a/Source/OpenTK/Platform/Windows/WinMMJoystick.cs
+++ b/Source/OpenTK/Platform/Windows/WinMMJoystick.cs
@@ -87,7 +87,7 @@ namespace OpenTK.Platform.Windows
if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
num_axes += 2;
- stick = new JoystickDevice(number, num_axes, caps.NumButtons);
+ stick = new JoystickDevice(number, num_axes, caps.NumButtons);
stick.Details = new WinMMJoyDetails(num_axes);
// Make sure to reverse the vertical axes, so that +1 points up and -1 points down.
@@ -427,5 +427,21 @@ namespace OpenTK.Platform.Windows
}
#endregion
+
+ //HACK implement
+ public GamePadState GetState()
+ {
+ throw new NotImplementedException();
+ }
+
+ public GamePadState GetState(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetDeviceName(int index)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
index 9b2a1989..f439a361 100644
--- a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
+++ b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
@@ -102,7 +102,16 @@ namespace OpenTK.Platform.Windows
// keyboard device by qeurying the registry.
RegistryKey regkey = GetRegistryKey(name);
string deviceDesc = (string)regkey.GetValue("DeviceDesc");
+
string deviceClass = (string)regkey.GetValue("Class");
+
+ string deviceClassGUID = (string)regkey.GetValue("ClassGUID"); // for windows 8 support via OpenTK issue 3198
+
+ // making a guess at backwards compatability. Not sure what older windows returns in these cases...
+ if(deviceClass == null || deviceClass.Equals(string.Empty)){
+ RegistryKey classGUIDKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\" + deviceClassGUID);
+ deviceClass = classGUIDKey != null ? (string) classGUIDKey.GetValue("Class") : string.Empty;
+ }
if (String.IsNullOrEmpty(deviceDesc))
{
@@ -171,31 +180,30 @@ namespace OpenTK.Platform.Windows
switch (rin.Data.Keyboard.VKey)
{
case VirtualKeys.SHIFT:
- keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
+ keyboard.SetKeyState(Key.ShiftLeft, (byte)WinGLNative.ShiftLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.ShiftRight, (byte)WinGLNative.ShiftRightScanCode, pressed);
processed = true;
break;
case VirtualKeys.CONTROL:
- keyboard[Input.Key.ControlLeft] = keyboard[Input.Key.ControlRight] = pressed;
+ keyboard.SetKeyState(Key.ControlLeft, (byte)WinGLNative.ControlLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.ControlRight, (byte)WinGLNative.ControlRightScanCode, pressed);
processed = true;
break;
case VirtualKeys.MENU:
- keyboard[Input.Key.AltLeft] = keyboard[Input.Key.AltRight] = pressed;
+ keyboard.SetKeyState(Key.AltLeft, (byte)WinGLNative.AltLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.AltRight, (byte)WinGLNative.AltRightScanCode, pressed);
processed = true;
break;
default:
- if (!KeyMap.ContainsKey(rin.Data.Keyboard.VKey))
- {
- Debug.Print("Virtual key {0} ({1}) not mapped.",
- rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
- }
- else
- {
- keyboard[KeyMap[rin.Data.Keyboard.VKey]] = pressed;
- processed = true;
- }
+ Key key;
+ KeyMap.TryGetValue(rin.Data.Keyboard.VKey, out key);
+ if (key == Key.Unknown)
+ Debug.Print("Virtual key {0} ({1}) not mapped.", rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
+ keyboard.SetKeyState(key, BitConverter.GetBytes(rin.Data.Keyboard.MakeCode)[0], pressed);
+ processed = true;
break;
}
diff --git a/Source/OpenTK/Platform/Windows/WinRawMouse.cs b/Source/OpenTK/Platform/Windows/WinRawMouse.cs
index 38e8a371..82ad21a9 100644
--- a/Source/OpenTK/Platform/Windows/WinRawMouse.cs
+++ b/Source/OpenTK/Platform/Windows/WinRawMouse.cs
@@ -111,7 +111,15 @@ namespace OpenTK.Platform.Windows
// mouse device by qeurying the registry.
RegistryKey regkey = FindRegistryKey(name);
string deviceDesc = (string)regkey.GetValue("DeviceDesc");
- string deviceClass = (string)regkey.GetValue("Class");
+
+
+ string deviceClass = (string)regkey.GetValue("Class") as string;
+ if(deviceClass == null){
+ // Added to address OpenTK issue 3198 with mouse on Windows 8
+ string deviceClassGUID = (string)regkey.GetValue("ClassGUID");
+ RegistryKey classGUIDKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\" + deviceClassGUID);
+ deviceClass = classGUIDKey != null ? (string) classGUIDKey.GetValue("Class") : string.Empty;
+ }
deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
@@ -158,16 +166,56 @@ namespace OpenTK.Platform.Windows
int mouse_handle = rawids.ContainsKey(handle) ? rawids[handle] : 0;
mouse = mice[mouse_handle];
- if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Left);
- if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Left);
- if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Right);
- if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Right);
- if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Middle);
- if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Middle);
- if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0) mouse.EnableBit((int)MouseButton.Button1);
- if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0) mouse.DisableBit((int)MouseButton.Button1);
- if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0) mouse.EnableBit((int)MouseButton.Button2);
- if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0) mouse.DisableBit((int)MouseButton.Button2);
+ // Set and release capture of the mouse to fix http://www.opentk.com/node/2133, Patch by Artfunkel
+ if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0){
+ mouse.EnableBit((int)MouseButton.Left);
+ Functions.SetCapture(Window);
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0)
+ {
+ mouse.DisableBit((int)MouseButton.Left);
+ Functions.ReleaseCapture();
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0)
+ {
+ mouse.EnableBit((int)MouseButton.Right);
+ Functions.SetCapture(Window);
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0)
+ {
+ mouse.DisableBit((int)MouseButton.Right);
+ Functions.ReleaseCapture();
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0)
+ {
+ mouse.EnableBit((int)MouseButton.Middle);
+ Functions.SetCapture(Window);
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0)
+ {
+ mouse.DisableBit((int)MouseButton.Middle);
+ Functions.ReleaseCapture();
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0)
+ {
+ mouse.EnableBit((int)MouseButton.Button1);
+ Functions.SetCapture(Window);
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0)
+ {
+ mouse.DisableBit((int)MouseButton.Button1);
+ Functions.ReleaseCapture();
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0)
+ {
+ mouse.EnableBit((int)MouseButton.Button2);
+ Functions.SetCapture(Window);
+ }
+ if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0)
+ {
+ mouse.DisableBit((int)MouseButton.Button2);
+ Functions.ReleaseCapture();
+ }
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
mouse.WheelPrecise += (short)raw.ButtonData / 120.0f;
diff --git a/Source/OpenTK/Platform/X11/X11Factory.cs b/Source/OpenTK/Platform/X11/X11Factory.cs
index 6fd9c5eb..e437e119 100644
--- a/Source/OpenTK/Platform/X11/X11Factory.cs
+++ b/Source/OpenTK/Platform/X11/X11Factory.cs
@@ -91,6 +91,11 @@ namespace OpenTK.Platform.X11
return new X11Mouse(); // Always supported.
}
+ public virtual OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ return new X11Joystick();
+ }
+
#endregion
}
}
diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs
index c64ea7c6..ce5154a0 100644
--- a/Source/OpenTK/Platform/X11/X11GLNative.cs
+++ b/Source/OpenTK/Platform/X11/X11GLNative.cs
@@ -994,6 +994,8 @@ namespace OpenTK.Platform.X11
{
using (new XLock(window.Display))
{
+ Functions.XMoveWindow(window.Display, window.WindowHandle,
+ value.X, value.Y);
Functions.XResizeWindow(window.Display, window.WindowHandle,
value.Width, value.Height);
}
diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs
index 10978019..a9193a40 100644
--- a/Source/OpenTK/Platform/X11/X11Input.cs
+++ b/Source/OpenTK/Platform/X11/X11Input.cs
@@ -157,20 +157,22 @@ namespace OpenTK.Platform.X11
case XEventName.KeyPress:
case XEventName.KeyRelease:
bool pressed = e.type == XEventName.KeyPress;
+ XKey keysym = (XKey)API.LookupKeysym(ref e.KeyEvent, 0);
+ XKey keysym2 = (XKey)API.LookupKeysym(ref e.KeyEvent, 1);
+ Key key = Key.Unknown;
- IntPtr keysym = API.LookupKeysym(ref e.KeyEvent, 0);
- IntPtr keysym2 = API.LookupKeysym(ref e.KeyEvent, 1);
-
- if (keymap.ContainsKey((XKey)keysym))
- keyboard[keymap[(XKey)keysym]] = pressed;
- else if (keymap.ContainsKey((XKey)keysym2))
- keyboard[keymap[(XKey)keysym2]] = pressed;
+ if (keymap.ContainsKey(keysym))
+ key = keymap[keysym];
+ else if (keymap.ContainsKey(keysym2))
+ key = keymap[keysym2];
else
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.KeyEvent.keycode, (XKey)keysym, (XKey)keysym2);
+
+ keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed);
break;
case XEventName.ButtonPress:
- if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
+ if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = true;
else if (e.ButtonEvent.button == 4) mouse.Wheel++;
@@ -190,7 +192,7 @@ namespace OpenTK.Platform.X11
break;
case XEventName.ButtonRelease:
- if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false;
+ if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false;
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = false;
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = false;
else if (e.ButtonEvent.button == 6) mouse[OpenTK.Input.MouseButton.Button1] = false;
diff --git a/Source/OpenTK/Platform/X11/X11Joystick.cs b/Source/OpenTK/Platform/X11/X11Joystick.cs
index 0f88d994..85299eb1 100644
--- a/Source/OpenTK/Platform/X11/X11Joystick.cs
+++ b/Source/OpenTK/Platform/X11/X11Joystick.cs
@@ -29,13 +29,14 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Text;
using OpenTK.Input;
namespace OpenTK.Platform.X11
{
struct X11JoyDetails { }
- sealed class X11Joystick : IJoystickDriver
+ sealed class X11Joystick : IJoystickDriver, IGamePadDriver
{
#region Fields
@@ -58,8 +59,8 @@ namespace OpenTK.Platform.X11
JoystickDevice stick = OpenJoystick(JoystickPath, number++);
if (stick != null)
{
- stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons, {3}{0})",
- number, stick.Axis.Count, stick.Button.Count, JoystickPath);
+ //stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons, {3}{0})",
+ //number, stick.Axis.Count, stick.Button.Count, JoystickPath);
sticks.Add(stick);
}
}
@@ -70,8 +71,8 @@ namespace OpenTK.Platform.X11
JoystickDevice stick = OpenJoystick(JoystickPathLegacy, number++);
if (stick != null)
{
- stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons, {3}{0})",
- number, stick.Axis.Count, stick.Button.Count, JoystickPathLegacy);
+ //stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons, {3}{0})",
+ //number, stick.Axis.Count, stick.Button.Count, JoystickPathLegacy);
sticks.Add(stick);
}
}
@@ -88,7 +89,7 @@ namespace OpenTK.Platform.X11
public IList Joysticks
{
- get { return sticks_readonly; }
+ get { Poll(); return sticks_readonly; }
}
public void Poll()
@@ -153,6 +154,11 @@ namespace OpenTK.Platform.X11
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Buttons, ref buttons);
stick = new JoystickDevice(fd, axes, buttons);
+
+ StringBuilder sb = new StringBuilder(128);
+ UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Name128, sb);
+ stick.Description = sb.ToString();
+
Debug.Print("Found joystick on path {0}", path);
}
finally
@@ -186,7 +192,8 @@ namespace OpenTK.Platform.X11
{
Version = 0x80046a01,
Axes = 0x80016a11,
- Buttons = 0x80016a12
+ Buttons = 0x80016a12,
+ Name128 = (2u << 30) | (0x6A << 8) | (0x13 << 0) | (128 << 16) //JSIOCGNAME(128), which is _IOC(_IO_READ, 'j', 0x13, len)
}
static readonly string JoystickPath = "/dev/input/js";
@@ -203,6 +210,9 @@ namespace OpenTK.Platform.X11
[DllImport("libc", SetLastError = true)]
public static extern int ioctl(int d, JoystickIoctlCode request, ref int data);
+ [DllImport("libc", SetLastError = true)]
+ public static extern int ioctl(int d, JoystickIoctlCode request, StringBuilder data);
+
[DllImport("libc", SetLastError = true)]
public static extern int open([MarshalAs(UnmanagedType.LPStr)]string pathname, OpenFlags flags);
@@ -248,5 +258,22 @@ namespace OpenTK.Platform.X11
}
#endregion
+
+ //HACK implement
+ public GamePadState GetState()
+ {
+ throw new NotImplementedException();
+ }
+
+ public GamePadState GetState(int index)
+ {
+ Poll();
+ throw new NotImplementedException();
+ }
+
+ public string GetDeviceName(int index)
+ {
+ throw new NotImplementedException();
+ }
}
}