Added OpenTK.Compatibility project to provide an upgrade path from 0.9.8.
This commit is contained in:
parent
245f45c7eb
commit
81304f33b5
32 changed files with 184834 additions and 0 deletions
134
Source/Compatibility/Graphics/GL/ErrorHelper.cs
Normal file
134
Source/Compatibility/Graphics/GL/ErrorHelper.cs
Normal file
|
@ -0,0 +1,134 @@
|
|||
#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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
// Used in debug-mode only, for automatic OpenGL error-checking.
|
||||
//
|
||||
// Works like this: an instance is created before each OpenGL function is called.
|
||||
// The constructor resets the OpenGL error state. Once the native function returns,
|
||||
// the error state is checked again, raising the relevant exceptions.
|
||||
//
|
||||
// A using-region is used to ensure Dispose() is called.
|
||||
//
|
||||
// Make sure that no error checking is added to the GetError function,
|
||||
// as that would cause infinite recursion!
|
||||
struct ErrorHelper : IDisposable
|
||||
{
|
||||
#region Fields
|
||||
|
||||
static readonly object SyncRoot = new object();
|
||||
static readonly Dictionary<GraphicsContext, List<ErrorCode>> ContextErrors =
|
||||
new Dictionary<GraphicsContext, List<ErrorCode>>();
|
||||
readonly GraphicsContext Context;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public ErrorHelper(IGraphicsContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new GraphicsContextMissingException();
|
||||
|
||||
Context = (GraphicsContext)context;
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (!ContextErrors.ContainsKey(Context))
|
||||
ContextErrors.Add(Context, new List<ErrorCode>());
|
||||
}
|
||||
ResetErrors();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
// Retrieve all OpenGL errors to clear the error list.
|
||||
// See http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/geterror.html
|
||||
[Conditional("DEBUG")]
|
||||
internal void ResetErrors()
|
||||
{
|
||||
if (Context.ErrorChecking)
|
||||
{
|
||||
while (GL.GetError() != ErrorCode.NoError)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve all OpenGL errors and throw an exception if anything other than NoError is returned.
|
||||
[Conditional("DEBUG")]
|
||||
internal void CheckErrors()
|
||||
{
|
||||
if (Context.ErrorChecking)
|
||||
{
|
||||
List<ErrorCode> error_list = ContextErrors[Context];
|
||||
error_list.Clear();
|
||||
ErrorCode error;
|
||||
do
|
||||
{
|
||||
error = GL.GetError();
|
||||
error_list.Add(error);
|
||||
} while (error != ErrorCode.NoError);
|
||||
|
||||
if (error_list.Count != 1)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (ErrorCode e in error_list)
|
||||
{
|
||||
if (e != ErrorCode.NoError)
|
||||
{
|
||||
sb.Append(e.ToString());
|
||||
sb.Append(", ");
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
sb.Remove(sb.Length - 2, 2); // Remove the last comma
|
||||
|
||||
throw new GraphicsErrorException(sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CheckErrors();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
144350
Source/Compatibility/Graphics/GL/GL.cs
Normal file
144350
Source/Compatibility/Graphics/GL/GL.cs
Normal file
File diff suppressed because it is too large
Load diff
5743
Source/Compatibility/Graphics/GL/GLCore.cs
Normal file
5743
Source/Compatibility/Graphics/GL/GLCore.cs
Normal file
File diff suppressed because it is too large
Load diff
5742
Source/Compatibility/Graphics/GL/GLDelegates.cs
Normal file
5742
Source/Compatibility/Graphics/GL/GLDelegates.cs
Normal file
File diff suppressed because it is too large
Load diff
11788
Source/Compatibility/Graphics/GL/GLEnums.cs
Normal file
11788
Source/Compatibility/Graphics/GL/GLEnums.cs
Normal file
File diff suppressed because it is too large
Load diff
1320
Source/Compatibility/Graphics/GL/GLHelper.cs
Normal file
1320
Source/Compatibility/Graphics/GL/GLHelper.cs
Normal file
File diff suppressed because it is too large
Load diff
1021
Source/Compatibility/Graphics/Glu/Glu.cs
Normal file
1021
Source/Compatibility/Graphics/Glu/Glu.cs
Normal file
File diff suppressed because it is too large
Load diff
190
Source/Compatibility/Graphics/Glu/GluCore.cs
Normal file
190
Source/Compatibility/Graphics/Glu/GluCore.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
namespace OpenTK.Graphics
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
#pragma warning disable 3019
|
||||
#pragma warning disable 1591
|
||||
|
||||
partial class Glu
|
||||
{
|
||||
[Obsolete]
|
||||
internal static partial class Imports
|
||||
{
|
||||
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBeginCurve", ExactSpelling = true)]
|
||||
internal extern static void BeginCurve(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBeginPolygon", ExactSpelling = true)]
|
||||
internal extern static void BeginPolygon(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBeginSurface", ExactSpelling = true)]
|
||||
internal extern static void BeginSurface(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBeginTrim", ExactSpelling = true)]
|
||||
internal extern static void BeginTrim(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild1DMipmapLevels", ExactSpelling = true)]
|
||||
internal extern static Int32 Build1DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild1DMipmaps", ExactSpelling = true)]
|
||||
internal extern static Int32 Build1DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, PixelFormat format, PixelType type, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild2DMipmapLevels", ExactSpelling = true)]
|
||||
internal extern static Int32 Build2DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild2DMipmaps", ExactSpelling = true)]
|
||||
internal extern static Int32 Build2DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, PixelFormat format, PixelType type, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild3DMipmapLevels", ExactSpelling = true)]
|
||||
internal extern static Int32 Build3DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, Int32 depth, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluBuild3DMipmaps", ExactSpelling = true)]
|
||||
internal extern static Int32 Build3DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, Int32 depth, PixelFormat format, PixelType type, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluCheckExtension", ExactSpelling = true)]
|
||||
internal extern static unsafe bool CheckExtension(Byte* extName, Byte* extString);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluCylinder", ExactSpelling = true)]
|
||||
internal extern static void Cylinder(IntPtr quad, double @base, double top, double height, Int32 slices, Int32 stacks);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluDeleteNurbsRenderer", ExactSpelling = true)]
|
||||
internal extern static void DeleteNurbsRenderer(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluDeleteQuadric", ExactSpelling = true)]
|
||||
internal extern static void DeleteQuadric(IntPtr quad);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluDeleteTess", ExactSpelling = true)]
|
||||
internal extern static void DeleteTess(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluDisk", ExactSpelling = true)]
|
||||
internal extern static void Disk(IntPtr quad, double inner, double outer, Int32 slices, Int32 loops);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluEndCurve", ExactSpelling = true)]
|
||||
internal extern static void EndCurve(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluEndPolygon", ExactSpelling = true)]
|
||||
internal extern static void EndPolygon(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluEndSurface", ExactSpelling = true)]
|
||||
internal extern static void EndSurface(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluEndTrim", ExactSpelling = true)]
|
||||
internal extern static void EndTrim(IntPtr nurb);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluErrorString", ExactSpelling = true)]
|
||||
internal extern static IntPtr ErrorString(OpenTK.Graphics.GluErrorCode error);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluGetString", ExactSpelling = true)]
|
||||
internal extern static IntPtr GetString(OpenTK.Graphics.GluStringName name);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluGetNurbsProperty", ExactSpelling = true)]
|
||||
internal extern static unsafe void GetNurbsProperty(IntPtr nurb, OpenTK.Graphics.NurbsProperty property, [Out] float* data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluGetTessProperty", ExactSpelling = true)]
|
||||
internal extern static unsafe void GetTessProperty(IntPtr tess, OpenTK.Graphics.TessParameter which, [Out] double* data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluLoadSamplingMatrices", ExactSpelling = true)]
|
||||
internal extern static unsafe void LoadSamplingMatrices(IntPtr nurb, float* model, float* perspective, Int32* view);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluLookAt", ExactSpelling = true)]
|
||||
internal extern static void LookAt(double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNewNurbsRenderer", ExactSpelling = true)]
|
||||
internal extern static IntPtr NewNurbsRenderer();
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNewQuadric", ExactSpelling = true)]
|
||||
internal extern static IntPtr NewQuadric();
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNewTess", ExactSpelling = true)]
|
||||
internal extern static IntPtr NewTess();
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNextContour", ExactSpelling = true)]
|
||||
internal extern static void NextContour(IntPtr tess, OpenTK.Graphics.TessContour type);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNurbsCallback", ExactSpelling = true)]
|
||||
internal extern static void NurbsCallback(IntPtr nurb, OpenTK.Graphics.NurbsCallback which, Delegate CallBackFunc);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNurbsCallbackData", ExactSpelling = true)]
|
||||
internal extern static void NurbsCallbackData(IntPtr nurb, IntPtr userData);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNurbsCurve", ExactSpelling = true)]
|
||||
internal extern static unsafe void NurbsCurve(IntPtr nurb, Int32 knotCount, [Out] float* knots, Int32 stride, [Out] float* control, Int32 order, MapTarget type);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNurbsProperty", ExactSpelling = true)]
|
||||
internal extern static void NurbsProperty(IntPtr nurb, OpenTK.Graphics.NurbsProperty property, float value);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluNurbsSurface", ExactSpelling = true)]
|
||||
internal extern static unsafe void NurbsSurface(IntPtr nurb, Int32 sKnotCount, float* sKnots, Int32 tKnotCount, float* tKnots, Int32 sStride, Int32 tStride, float* control, Int32 sOrder, Int32 tOrder, MapTarget type);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluOrtho2D", ExactSpelling = true)]
|
||||
internal extern static void Ortho2D(double left, double right, double bottom, double top);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluPartialDisk", ExactSpelling = true)]
|
||||
internal extern static void PartialDisk(IntPtr quad, double inner, double outer, Int32 slices, Int32 loops, double start, double sweep);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluPerspective", ExactSpelling = true)]
|
||||
internal extern static void Perspective(double fovy, double aspect, double zNear, double zFar);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluPickMatrix", ExactSpelling = true)]
|
||||
internal extern static unsafe void PickMatrix(double x, double y, double delX, double delY, [Out] Int32* viewport);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluProject", ExactSpelling = true)]
|
||||
internal extern static unsafe Int32 Project(double objX, double objY, double objZ, double* model, double* proj, Int32* view, double* winX, double* winY, double* winZ);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluPwlCurve", ExactSpelling = true)]
|
||||
internal extern static unsafe void PwlCurve(IntPtr nurb, Int32 count, float* data, Int32 stride, OpenTK.Graphics.NurbsTrim type);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluQuadricCallback", ExactSpelling = true)]
|
||||
internal extern static void QuadricCallback(IntPtr quad, OpenTK.Graphics.QuadricCallback which, Delegate CallBackFunc);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluQuadricDrawStyle", ExactSpelling = true)]
|
||||
internal extern static void QuadricDrawStyle(IntPtr quad, OpenTK.Graphics.QuadricDrawStyle draw);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluQuadricNormals", ExactSpelling = true)]
|
||||
internal extern static void QuadricNormals(IntPtr quad, OpenTK.Graphics.QuadricNormal normal);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluQuadricOrientation", ExactSpelling = true)]
|
||||
internal extern static void QuadricOrientation(IntPtr quad, OpenTK.Graphics.QuadricOrientation orientation);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluQuadricTexture", ExactSpelling = true)]
|
||||
internal extern static void QuadricTexture(IntPtr quad, bool texture);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluScaleImage", ExactSpelling = true)]
|
||||
internal extern static Int32 ScaleImage(PixelFormat format, Int32 wIn, Int32 hIn, PixelType typeIn, IntPtr dataIn, Int32 wOut, Int32 hOut, PixelType typeOut, [Out] IntPtr dataOut);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluSphere", ExactSpelling = true)]
|
||||
internal extern static void Sphere(IntPtr quad, double radius, Int32 slices, Int32 stacks);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessBeginContour", ExactSpelling = true)]
|
||||
internal extern static void TessBeginContour(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessBeginPolygon", ExactSpelling = true)]
|
||||
internal extern static void TessBeginPolygon(IntPtr tess, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessCallback", ExactSpelling = true)]
|
||||
internal extern static void TessCallback(IntPtr tess, OpenTK.Graphics.TessCallback which, Delegate CallBackFunc);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessEndContour", ExactSpelling = true)]
|
||||
internal extern static void TessEndContour(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessEndPolygon", ExactSpelling = true)]
|
||||
internal extern static void TessEndPolygon(IntPtr tess);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessNormal", ExactSpelling = true)]
|
||||
internal extern static void TessNormal(IntPtr tess, double valueX, double valueY, double valueZ);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessProperty", ExactSpelling = true)]
|
||||
internal extern static void TessProperty(IntPtr tess, OpenTK.Graphics.TessParameter which, double data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluTessVertex", ExactSpelling = true)]
|
||||
internal extern static unsafe void TessVertex(IntPtr tess, double* location, IntPtr data);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluUnProject", ExactSpelling = true)]
|
||||
internal extern static unsafe Int32 UnProject(double winX, double winY, double winZ, double* model, double* proj, Int32* view, double* objX, double* objY, double* objZ);
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
[System.Runtime.InteropServices.DllImport(Glu.Library, EntryPoint = "gluUnProject4", ExactSpelling = true)]
|
||||
internal extern static unsafe Int32 UnProject4(double winX, double winY, double winZ, double clipW, double* model, double* proj, Int32* view, double near, double far, double* objX, double* objY, double* objZ, double* objW);
|
||||
}
|
||||
}
|
||||
}
|
195
Source/Compatibility/Graphics/Glu/GluDelegates.cs
Normal file
195
Source/Compatibility/Graphics/Glu/GluDelegates.cs
Normal file
|
@ -0,0 +1,195 @@
|
|||
namespace OpenTK.Graphics
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
#pragma warning disable 0649
|
||||
#pragma warning disable 3019
|
||||
#pragma warning disable 1591
|
||||
|
||||
partial class Glu
|
||||
{
|
||||
internal static partial class Delegates
|
||||
{
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void BeginCurve(IntPtr nurb);
|
||||
internal static BeginCurve gluBeginCurve;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void BeginPolygon(IntPtr tess);
|
||||
internal static BeginPolygon gluBeginPolygon;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void BeginSurface(IntPtr nurb);
|
||||
internal static BeginSurface gluBeginSurface;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void BeginTrim(IntPtr nurb);
|
||||
internal static BeginTrim gluBeginTrim;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build1DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
internal static Build1DMipmapLevels gluBuild1DMipmapLevels;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build1DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, PixelFormat format, PixelType type, IntPtr data);
|
||||
internal static Build1DMipmaps gluBuild1DMipmaps;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build2DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
internal static Build2DMipmapLevels gluBuild2DMipmapLevels;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build2DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, PixelFormat format, PixelType type, IntPtr data);
|
||||
internal static Build2DMipmaps gluBuild2DMipmaps;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build3DMipmapLevels(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, Int32 depth, PixelFormat format, PixelType type, Int32 level, Int32 @base, Int32 max, IntPtr data);
|
||||
internal static Build3DMipmapLevels gluBuild3DMipmapLevels;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 Build3DMipmaps(TextureTarget target, Int32 internalFormat, Int32 width, Int32 height, Int32 depth, PixelFormat format, PixelType type, IntPtr data);
|
||||
internal static Build3DMipmaps gluBuild3DMipmaps;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate bool CheckExtension(Byte* extName, Byte* extString);
|
||||
internal unsafe static CheckExtension gluCheckExtension;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void Cylinder(IntPtr quad, double @base, double top, double height, Int32 slices, Int32 stacks);
|
||||
internal static Cylinder gluCylinder;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void DeleteNurbsRenderer(IntPtr nurb);
|
||||
internal static DeleteNurbsRenderer gluDeleteNurbsRenderer;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void DeleteQuadric(IntPtr quad);
|
||||
internal static DeleteQuadric gluDeleteQuadric;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void DeleteTess(IntPtr tess);
|
||||
internal static DeleteTess gluDeleteTess;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void Disk(IntPtr quad, double inner, double outer, Int32 slices, Int32 loops);
|
||||
internal static Disk gluDisk;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void EndCurve(IntPtr nurb);
|
||||
internal static EndCurve gluEndCurve;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void EndPolygon(IntPtr tess);
|
||||
internal static EndPolygon gluEndPolygon;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void EndSurface(IntPtr nurb);
|
||||
internal static EndSurface gluEndSurface;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void EndTrim(IntPtr nurb);
|
||||
internal static EndTrim gluEndTrim;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate IntPtr ErrorString(OpenTK.Graphics.GluErrorCode error);
|
||||
internal static ErrorString gluErrorString;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate IntPtr GetString(OpenTK.Graphics.GluStringName name);
|
||||
internal static GetString gluGetString;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void GetNurbsProperty(IntPtr nurb, OpenTK.Graphics.NurbsProperty property, [Out] float* data);
|
||||
internal unsafe static GetNurbsProperty gluGetNurbsProperty;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void GetTessProperty(IntPtr tess, OpenTK.Graphics.TessParameter which, [Out] double* data);
|
||||
internal unsafe static GetTessProperty gluGetTessProperty;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void LoadSamplingMatrices(IntPtr nurb, float* model, float* perspective, Int32* view);
|
||||
internal unsafe static LoadSamplingMatrices gluLoadSamplingMatrices;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void LookAt(double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||
internal static LookAt gluLookAt;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate IntPtr NewNurbsRenderer();
|
||||
internal static NewNurbsRenderer gluNewNurbsRenderer;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate IntPtr NewQuadric();
|
||||
internal static NewQuadric gluNewQuadric;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate IntPtr NewTess();
|
||||
internal static NewTess gluNewTess;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void NextContour(IntPtr tess, OpenTK.Graphics.TessContour type);
|
||||
internal static NextContour gluNextContour;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void NurbsCallback(IntPtr nurb, OpenTK.Graphics.NurbsCallback which, Delegate CallBackFunc);
|
||||
internal static NurbsCallback gluNurbsCallback;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void NurbsCallbackData(IntPtr nurb, IntPtr userData);
|
||||
internal static NurbsCallbackData gluNurbsCallbackData;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void NurbsCallbackDataEXT(IntPtr nurb, IntPtr userData);
|
||||
internal static NurbsCallbackDataEXT gluNurbsCallbackDataEXT;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void NurbsCurve(IntPtr nurb, Int32 knotCount, [Out] float* knots, Int32 stride, [Out] float* control, Int32 order, MapTarget type);
|
||||
internal unsafe static NurbsCurve gluNurbsCurve;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void NurbsProperty(IntPtr nurb, OpenTK.Graphics.NurbsProperty property, float value);
|
||||
internal static NurbsProperty gluNurbsProperty;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void NurbsSurface(IntPtr nurb, Int32 sKnotCount, float* sKnots, Int32 tKnotCount, float* tKnots, Int32 sStride, Int32 tStride, float* control, Int32 sOrder, Int32 tOrder, MapTarget type);
|
||||
internal unsafe static NurbsSurface gluNurbsSurface;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void Ortho2D(double left, double right, double bottom, double top);
|
||||
internal static Ortho2D gluOrtho2D;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void PartialDisk(IntPtr quad, double inner, double outer, Int32 slices, Int32 loops, double start, double sweep);
|
||||
internal static PartialDisk gluPartialDisk;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void Perspective(double fovy, double aspect, double zNear, double zFar);
|
||||
internal static Perspective gluPerspective;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void PickMatrix(double x, double y, double delX, double delY, [Out] Int32* viewport);
|
||||
internal unsafe static PickMatrix gluPickMatrix;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate Int32 Project(double objX, double objY, double objZ, double* model, double* proj, Int32* view, double* winX, double* winY, double* winZ);
|
||||
internal unsafe static Project gluProject;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void PwlCurve(IntPtr nurb, Int32 count, float* data, Int32 stride, OpenTK.Graphics.NurbsTrim type);
|
||||
internal unsafe static PwlCurve gluPwlCurve;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void QuadricCallback(IntPtr quad, OpenTK.Graphics.QuadricCallback which, Delegate CallBackFunc);
|
||||
internal static QuadricCallback gluQuadricCallback;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void QuadricDrawStyle(IntPtr quad, OpenTK.Graphics.QuadricDrawStyle draw);
|
||||
internal static QuadricDrawStyle gluQuadricDrawStyle;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void QuadricNormals(IntPtr quad, OpenTK.Graphics.QuadricNormal normal);
|
||||
internal static QuadricNormals gluQuadricNormals;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void QuadricOrientation(IntPtr quad, OpenTK.Graphics.QuadricOrientation orientation);
|
||||
internal static QuadricOrientation gluQuadricOrientation;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void QuadricTexture(IntPtr quad, bool texture);
|
||||
internal static QuadricTexture gluQuadricTexture;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate Int32 ScaleImage(PixelFormat format, Int32 wIn, Int32 hIn, PixelType typeIn, IntPtr dataIn, Int32 wOut, Int32 hOut, PixelType typeOut, [Out] IntPtr dataOut);
|
||||
internal static ScaleImage gluScaleImage;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void Sphere(IntPtr quad, double radius, Int32 slices, Int32 stacks);
|
||||
internal static Sphere gluSphere;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessBeginContour(IntPtr tess);
|
||||
internal static TessBeginContour gluTessBeginContour;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessBeginPolygon(IntPtr tess, IntPtr data);
|
||||
internal static TessBeginPolygon gluTessBeginPolygon;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessCallback(IntPtr tess, OpenTK.Graphics.TessCallback which, Delegate CallBackFunc);
|
||||
internal static TessCallback gluTessCallback;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessEndContour(IntPtr tess);
|
||||
internal static TessEndContour gluTessEndContour;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessEndPolygon(IntPtr tess);
|
||||
internal static TessEndPolygon gluTessEndPolygon;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessNormal(IntPtr tess, double valueX, double valueY, double valueZ);
|
||||
internal static TessNormal gluTessNormal;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal delegate void TessProperty(IntPtr tess, OpenTK.Graphics.TessParameter which, double data);
|
||||
internal static TessProperty gluTessProperty;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate void TessVertex(IntPtr tess, double* location, IntPtr data);
|
||||
internal unsafe static TessVertex gluTessVertex;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate Int32 TexFilterFuncSGI(TextureTarget target, SgisTextureFilter4 filtertype, float* parms, Int32 n, [Out] float* weights);
|
||||
internal unsafe static TexFilterFuncSGI gluTexFilterFuncSGI;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate Int32 UnProject(double winX, double winY, double winZ, double* model, double* proj, Int32* view, double* objX, double* objY, double* objZ);
|
||||
internal unsafe static UnProject gluUnProject;
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()]
|
||||
internal unsafe delegate Int32 UnProject4(double winX, double winY, double winZ, double clipW, double* model, double* proj, Int32* view, double near, double far, double* objX, double* objY, double* objZ, double* objW);
|
||||
internal unsafe static UnProject4 gluUnProject4;
|
||||
}
|
||||
}
|
||||
}
|
390
Source/Compatibility/Graphics/Glu/GluEnums.cs
Normal file
390
Source/Compatibility/Graphics/Glu/GluEnums.cs
Normal file
|
@ -0,0 +1,390 @@
|
|||
namespace OpenTK.Graphics
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
|
||||
public enum GluVersion
|
||||
{
|
||||
Version11 = ((int)1),
|
||||
Version13 = ((int)1),
|
||||
Version12 = ((int)1),
|
||||
}
|
||||
|
||||
public enum GluStringName
|
||||
{
|
||||
Version = ((int)100800),
|
||||
Extensions = ((int)100801),
|
||||
}
|
||||
|
||||
public enum GluErrorCode
|
||||
{
|
||||
OutOfMemory = ((int)100902),
|
||||
InvalidEnum = ((int)100900),
|
||||
InvalidValue = ((int)100901),
|
||||
InvalidOperation = ((int)100904),
|
||||
}
|
||||
|
||||
public enum Filter4TypeSGIS
|
||||
{
|
||||
MitchellNetravaliSgi = ((int)100301),
|
||||
LagrangianSgi = ((int)100300),
|
||||
}
|
||||
|
||||
public enum NurbsDisplay
|
||||
{
|
||||
OutlinePolygon = ((int)100240),
|
||||
OutlinePatch = ((int)100241),
|
||||
Fill = ((int)QuadricDrawStyle.Fill),
|
||||
}
|
||||
|
||||
public enum NurbsCallback
|
||||
{
|
||||
NurbsColorData = ((int)100173),
|
||||
NurbsVertexData = ((int)100171),
|
||||
NurbsNormal = ((int)100166),
|
||||
NurbsError = ((int)100103),
|
||||
NurbsTextureCoordExt = ((int)100168),
|
||||
Error = ((int)100103),
|
||||
NurbsEndDataExt = ((int)100175),
|
||||
NurbsEnd = ((int)100169),
|
||||
NurbsTextureCoord = ((int)100168),
|
||||
NurbsEndExt = ((int)100169),
|
||||
NurbsNormalDataExt = ((int)100172),
|
||||
NurbsColor = ((int)100167),
|
||||
NurbsColorExt = ((int)100167),
|
||||
NurbsVertexExt = ((int)100165),
|
||||
NurbsBeginExt = ((int)100164),
|
||||
NurbsTextureCoordData = ((int)100174),
|
||||
NurbsBeginData = ((int)100170),
|
||||
NurbsColorDataExt = ((int)100173),
|
||||
NurbsBeginDataExt = ((int)100170),
|
||||
NurbsVertex = ((int)100165),
|
||||
NurbsTextureCoordDataExt = ((int)100174),
|
||||
NurbsNormalExt = ((int)100166),
|
||||
NurbsVertexDataExt = ((int)100171),
|
||||
NurbsBegin = ((int)100164),
|
||||
NurbsEndData = ((int)100175),
|
||||
NurbsNormalData = ((int)100172),
|
||||
}
|
||||
|
||||
public enum NurbsError
|
||||
{
|
||||
NurbsError37 = ((int)100287),
|
||||
NurbsError16 = ((int)100266),
|
||||
NurbsError26 = ((int)100276),
|
||||
NurbsError36 = ((int)100286),
|
||||
NurbsError19 = ((int)100269),
|
||||
NurbsError29 = ((int)100279),
|
||||
NurbsError8 = ((int)100258),
|
||||
NurbsError12 = ((int)100262),
|
||||
NurbsError9 = ((int)100259),
|
||||
NurbsError1 = ((int)100251),
|
||||
NurbsError18 = ((int)100268),
|
||||
NurbsError28 = ((int)100278),
|
||||
NurbsError4 = ((int)100254),
|
||||
NurbsError5 = ((int)100255),
|
||||
NurbsError6 = ((int)100256),
|
||||
NurbsError7 = ((int)100257),
|
||||
NurbsError3 = ((int)100253),
|
||||
NurbsError22 = ((int)100272),
|
||||
NurbsError32 = ((int)100282),
|
||||
NurbsError2 = ((int)100252),
|
||||
NurbsError11 = ((int)100261),
|
||||
NurbsError21 = ((int)100271),
|
||||
NurbsError31 = ((int)100281),
|
||||
NurbsError10 = ((int)100260),
|
||||
NurbsError20 = ((int)100270),
|
||||
NurbsError30 = ((int)100280),
|
||||
NurbsError15 = ((int)100265),
|
||||
NurbsError25 = ((int)100275),
|
||||
NurbsError35 = ((int)100285),
|
||||
NurbsError14 = ((int)100264),
|
||||
NurbsError24 = ((int)100274),
|
||||
NurbsError34 = ((int)100284),
|
||||
NurbsError13 = ((int)100263),
|
||||
NurbsError23 = ((int)100273),
|
||||
NurbsError33 = ((int)100283),
|
||||
NurbsError17 = ((int)100267),
|
||||
NurbsError27 = ((int)100277),
|
||||
}
|
||||
|
||||
public enum NurbsProperty
|
||||
{
|
||||
DisplayMode = ((int)100204),
|
||||
ParametricTolerance = ((int)100202),
|
||||
NurbsRenderer = ((int)100162),
|
||||
NurbsTessellator = ((int)100161),
|
||||
NurbsTessellatorExt = ((int)100161),
|
||||
NurbsModeExt = ((int)100160),
|
||||
UStep = ((int)100206),
|
||||
SamplingMethod = ((int)100205),
|
||||
AutoLoadMatrix = ((int)100200),
|
||||
VStep = ((int)100207),
|
||||
Culling = ((int)100201),
|
||||
NurbsRendererExt = ((int)100162),
|
||||
NurbsMode = ((int)100160),
|
||||
SamplingTolerance = ((int)100203),
|
||||
}
|
||||
|
||||
public enum NurbsSampling
|
||||
{
|
||||
ObjectParametricError = ((int)100208),
|
||||
ObjectPathLength = ((int)100209),
|
||||
PathLength = ((int)100215),
|
||||
DomainDistance = ((int)100217),
|
||||
ObjectPathLengthExt = ((int)100209),
|
||||
ObjectParametricErrorExt = ((int)100208),
|
||||
ParametricError = ((int)100216),
|
||||
}
|
||||
|
||||
public enum NurbsTrim
|
||||
{
|
||||
Map1Trim3 = ((int)100211),
|
||||
Map1Trim2 = ((int)100210),
|
||||
}
|
||||
|
||||
public enum QuadricDrawStyle
|
||||
{
|
||||
Line = ((int)100011),
|
||||
Silhouette = ((int)100013),
|
||||
Point = ((int)100010),
|
||||
Fill = ((int)100012),
|
||||
}
|
||||
|
||||
public enum QuadricCallback
|
||||
{
|
||||
Error = ((int)NurbsCallback.Error),
|
||||
}
|
||||
|
||||
public enum QuadricNormal
|
||||
{
|
||||
None = ((int)100002),
|
||||
Flat = ((int)100001),
|
||||
Smooth = ((int)100000),
|
||||
}
|
||||
|
||||
public enum QuadricOrientation
|
||||
{
|
||||
Outside = ((int)100020),
|
||||
Inside = ((int)100021),
|
||||
}
|
||||
|
||||
public enum TessCallback
|
||||
{
|
||||
TessEdgeFlagData = ((int)100110),
|
||||
Begin = ((int)100100),
|
||||
TessError = ((int)100103),
|
||||
EdgeFlag = ((int)100104),
|
||||
End = ((int)100102),
|
||||
TessCombine = ((int)100105),
|
||||
Error = ((int)100103),
|
||||
TessEndData = ((int)100108),
|
||||
TessBeginData = ((int)100106),
|
||||
TessErrorData = ((int)100109),
|
||||
Vertex = ((int)100101),
|
||||
TessVertexData = ((int)100107),
|
||||
TessVertex = ((int)100101),
|
||||
TessEdgeFlag = ((int)100104),
|
||||
TessEnd = ((int)100102),
|
||||
TessBegin = ((int)100100),
|
||||
TessCombineData = ((int)100111),
|
||||
}
|
||||
|
||||
public enum TessContour
|
||||
{
|
||||
Exterior = ((int)100123),
|
||||
Ccw = ((int)100121),
|
||||
Interior = ((int)100122),
|
||||
Unknown = ((int)100124),
|
||||
Cw = ((int)100120),
|
||||
}
|
||||
|
||||
public enum TessParameter
|
||||
{
|
||||
TessWindingRule = ((int)100140),
|
||||
TessBoundaryOnly = ((int)100141),
|
||||
TessTolerance = ((int)100142),
|
||||
}
|
||||
|
||||
public enum TessError
|
||||
{
|
||||
TessMissingBeginPolygon = ((int)100151),
|
||||
TessMissingEndPolygon = ((int)100153),
|
||||
TessError1 = ((int)100151),
|
||||
TessMissingBeginContour = ((int)100152),
|
||||
TessCoordTooLarge = ((int)100155),
|
||||
TessError7 = ((int)100157),
|
||||
TessError2 = ((int)100152),
|
||||
TessError4 = ((int)100154),
|
||||
TessNeedCombineCallback = ((int)100156),
|
||||
TessError3 = ((int)100153),
|
||||
TessError6 = ((int)100156),
|
||||
TessError5 = ((int)100155),
|
||||
TessError8 = ((int)100158),
|
||||
TessMissingEndContour = ((int)100154),
|
||||
}
|
||||
|
||||
public enum TessWinding
|
||||
{
|
||||
TessWindingNonzero = ((int)100131),
|
||||
TessWindingOdd = ((int)100130),
|
||||
TessWindingPositive = ((int)100132),
|
||||
TessWindingAbsGeqTwo = ((int)100134),
|
||||
TessWindingNegative = ((int)100133),
|
||||
}
|
||||
|
||||
public enum AllGlu
|
||||
{
|
||||
None = ((int)100002),
|
||||
TessWindingRule = ((int)100140),
|
||||
TessWindingPositive = ((int)100132),
|
||||
ObjectPathLength = ((int)100209),
|
||||
NurbsTextureCoordExt = ((int)100168),
|
||||
Vertex = ((int)100101),
|
||||
TessCombine = ((int)100105),
|
||||
AutoLoadMatrix = ((int)100200),
|
||||
TessBoundaryOnly = ((int)100141),
|
||||
NurbsEndExt = ((int)100169),
|
||||
NurbsError17 = ((int)100267),
|
||||
NurbsError27 = ((int)100277),
|
||||
NurbsError37 = ((int)100287),
|
||||
Interior = ((int)100122),
|
||||
TessWindingOdd = ((int)100130),
|
||||
InvalidValue = ((int)100901),
|
||||
ParametricError = ((int)100216),
|
||||
TessError8 = ((int)100158),
|
||||
NurbsError14 = ((int)100264),
|
||||
NurbsError24 = ((int)100274),
|
||||
NurbsError34 = ((int)100284),
|
||||
NurbsTextureCoordDataExt = ((int)100174),
|
||||
TessMissingBeginContour = ((int)100152),
|
||||
Silhouette = ((int)100013),
|
||||
TessError7 = ((int)100157),
|
||||
NurbsNormalDataExt = ((int)100172),
|
||||
NurbsError21 = ((int)100271),
|
||||
NurbsError31 = ((int)100281),
|
||||
PathLength = ((int)100215),
|
||||
OutlinePolygon = ((int)100240),
|
||||
TessVertex = ((int)100101),
|
||||
TessWindingAbsGeqTwo = ((int)100134),
|
||||
Extensions = ((int)100801),
|
||||
TessEdgeFlagData = ((int)100110),
|
||||
EdgeFlag = ((int)100104),
|
||||
TessError1 = ((int)100151),
|
||||
Line = ((int)100011),
|
||||
NurbsBeginExt = ((int)100164),
|
||||
Point = ((int)100010),
|
||||
Begin = ((int)100100),
|
||||
Inside = ((int)100021),
|
||||
Flat = ((int)100001),
|
||||
TessBegin = ((int)100100),
|
||||
NurbsNormal = ((int)100166),
|
||||
NurbsColorData = ((int)100173),
|
||||
NurbsBeginDataExt = ((int)100170),
|
||||
NurbsRenderer = ((int)100162),
|
||||
NurbsBeginData = ((int)100170),
|
||||
Outside = ((int)100020),
|
||||
DisplayMode = ((int)100204),
|
||||
NurbsError15 = ((int)100265),
|
||||
NurbsError25 = ((int)100275),
|
||||
NurbsError35 = ((int)100285),
|
||||
NurbsVertexExt = ((int)100165),
|
||||
TessError5 = ((int)100155),
|
||||
Unknown = ((int)100124),
|
||||
NurbsEndDataExt = ((int)100175),
|
||||
NurbsError12 = ((int)100262),
|
||||
NurbsError22 = ((int)100272),
|
||||
NurbsError32 = ((int)100282),
|
||||
ObjectParametricErrorExt = ((int)100208),
|
||||
NurbsRendererExt = ((int)100162),
|
||||
TessError3 = ((int)100153),
|
||||
Fill = ((int)100012),
|
||||
TessError = ((int)100103),
|
||||
ObjectPathLengthExt = ((int)100209),
|
||||
TessWindingNegative = ((int)100133),
|
||||
NurbsTessellator = ((int)100161),
|
||||
NurbsColor = ((int)100167),
|
||||
NurbsModeExt = ((int)100160),
|
||||
SamplingTolerance = ((int)100203),
|
||||
NurbsColorDataExt = ((int)100173),
|
||||
Exterior = ((int)100123),
|
||||
Ccw = ((int)100121),
|
||||
Cw = ((int)100120),
|
||||
NurbsNormalExt = ((int)100166),
|
||||
NurbsError18 = ((int)100268),
|
||||
NurbsError28 = ((int)100278),
|
||||
LagrangianSgi = ((int)100300),
|
||||
TessEnd = ((int)100102),
|
||||
NurbsTessellatorExt = ((int)100161),
|
||||
NurbsEnd = ((int)100169),
|
||||
TessWindingNonzero = ((int)100131),
|
||||
OutOfMemory = ((int)100902),
|
||||
TessBeginData = ((int)100106),
|
||||
Error = ((int)100103),
|
||||
ObjectParametricError = ((int)100208),
|
||||
NurbsBegin = ((int)100164),
|
||||
TessCombineData = ((int)100111),
|
||||
TessMissingEndPolygon = ((int)100153),
|
||||
NurbsTextureCoord = ((int)100168),
|
||||
Smooth = ((int)100000),
|
||||
TessMissingBeginPolygon = ((int)100151),
|
||||
NurbsEndData = ((int)100175),
|
||||
NurbsVertexData = ((int)100171),
|
||||
TessEndData = ((int)100108),
|
||||
NurbsError11 = ((int)100261),
|
||||
NurbsVertex = ((int)100165),
|
||||
NurbsError30 = ((int)100280),
|
||||
Version11 = ((int)1),
|
||||
TessError6 = ((int)100156),
|
||||
Version13 = ((int)1),
|
||||
Version12 = ((int)1),
|
||||
TessErrorData = ((int)100109),
|
||||
NurbsError36 = ((int)100286),
|
||||
End = ((int)100102),
|
||||
SamplingMethod = ((int)100205),
|
||||
TessNeedCombineCallback = ((int)100156),
|
||||
UStep = ((int)100206),
|
||||
DomainDistance = ((int)100217),
|
||||
TessEdgeFlag = ((int)100104),
|
||||
NurbsColorExt = ((int)100167),
|
||||
NurbsError19 = ((int)100269),
|
||||
NurbsError29 = ((int)100279),
|
||||
InvalidOperation = ((int)100904),
|
||||
TessCoordTooLarge = ((int)100155),
|
||||
TessVertexData = ((int)100107),
|
||||
NurbsMode = ((int)100160),
|
||||
ParametricTolerance = ((int)100202),
|
||||
NurbsError2 = ((int)100252),
|
||||
VStep = ((int)100207),
|
||||
TessMissingEndContour = ((int)100154),
|
||||
Map1Trim2 = ((int)100210),
|
||||
Map1Trim3 = ((int)100211),
|
||||
Culling = ((int)100201),
|
||||
NurbsError16 = ((int)100266),
|
||||
NurbsError26 = ((int)100276),
|
||||
NurbsVertexDataExt = ((int)100171),
|
||||
NurbsNormalData = ((int)100172),
|
||||
TessError2 = ((int)100152),
|
||||
NurbsError13 = ((int)100263),
|
||||
NurbsError23 = ((int)100273),
|
||||
NurbsError33 = ((int)100283),
|
||||
NurbsError8 = ((int)100258),
|
||||
NurbsError9 = ((int)100259),
|
||||
TessError4 = ((int)100154),
|
||||
NurbsError10 = ((int)100260),
|
||||
NurbsError20 = ((int)100270),
|
||||
OutlinePatch = ((int)100241),
|
||||
NurbsError = ((int)100103),
|
||||
NurbsTextureCoordData = ((int)100174),
|
||||
NurbsError1 = ((int)100251),
|
||||
InvalidEnum = ((int)100900),
|
||||
NurbsError3 = ((int)100253),
|
||||
NurbsError4 = ((int)100254),
|
||||
NurbsError5 = ((int)100255),
|
||||
NurbsError6 = ((int)100256),
|
||||
NurbsError7 = ((int)100257),
|
||||
MitchellNetravaliSgi = ((int)100301),
|
||||
Version = ((int)100800),
|
||||
TessTolerance = ((int)100142),
|
||||
}
|
||||
|
||||
}
|
446
Source/Compatibility/Graphics/Glu/GluHelper.cs
Normal file
446
Source/Compatibility/Graphics/Glu/GluHelper.cs
Normal file
|
@ -0,0 +1,446 @@
|
|||
#region --- License ---
|
||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* Contributions by Andy Gill.
|
||||
* See license.txt for license info
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using OpenTK.Platform;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the OpenGL Utilities library.
|
||||
/// Methods i this library are considered deprecated and should be avoided.
|
||||
/// </summary>
|
||||
[Obsolete("Use OpenTK math functions instead.")]
|
||||
public static partial class Glu
|
||||
{
|
||||
private const string Library = "glu32.dll";
|
||||
|
||||
private static Dictionary<string, bool> AvailableExtensions = new Dictionary<string, bool>();
|
||||
private static bool rebuildExtensionList = true;
|
||||
|
||||
private static Type importsClass = typeof(Imports);
|
||||
|
||||
static Glu()
|
||||
{
|
||||
// Glu doesn't have any extensions, so this is safe to call once and be done with it.
|
||||
LoadAll();
|
||||
}
|
||||
|
||||
#region private static Delegate LoadDelegate(string name, Type signature)
|
||||
|
||||
/// <summary>
|
||||
/// Creates a System.Delegate that can be used to call a GLU function, core or extension.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the GLU function (eg. "gluBuild2DMipmaps")</param>
|
||||
/// <param name="signature">The signature of the GLU function.</param>
|
||||
/// <returns>
|
||||
/// A System.Delegate that can be used to call this GLU function, or null if the specified
|
||||
/// function name did not correspond to an GLU function.
|
||||
/// </returns>
|
||||
private static Delegate LoadDelegate(string name, Type signature)
|
||||
{
|
||||
MethodInfo m = importsClass.GetMethod(name.Substring(3), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
return
|
||||
GL.GetExtensionDelegate(name, signature) ??
|
||||
(m != null ? Delegate.CreateDelegate(signature, m) : null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static void LoadAll()
|
||||
|
||||
/// <summary>
|
||||
/// Loads all GLU functions (core and extensions).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Call this function manually whenever you need to update GLU entry points.
|
||||
/// This need will never arise under normal usage patterns.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static void LoadAll()
|
||||
{
|
||||
int supported = 0;
|
||||
Type extensions_class = typeof(Glu).GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (extensions_class == null)
|
||||
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||
|
||||
FieldInfo[] delegates = extensions_class.GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (delegates == null)
|
||||
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||
|
||||
foreach (FieldInfo f in delegates)
|
||||
{
|
||||
Delegate d = LoadDelegate(f.Name, f.FieldType);
|
||||
if (d != null)
|
||||
++supported;
|
||||
|
||||
f.SetValue(null, d);
|
||||
}
|
||||
|
||||
rebuildExtensionList = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static bool Load(string function)
|
||||
|
||||
/// <summary>
|
||||
/// Tries to reload the given GLU function (core or extension).
|
||||
/// </summary>
|
||||
/// <param name="function">The name of the GLU function.</param>
|
||||
/// <returns>True if the function was found and reloaded, false otherwise.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// While the automatic initialisation will load all GLU entry points, in some cases
|
||||
/// the initialization can take place before a render context has been established.
|
||||
/// In this case, use this function to load the entry points for the GLU functions
|
||||
/// you will need, or use LoadAll() to load all available entry points.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This function returns true if the given GLU function is supported, false otherwise.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// To query for supported extensions use the IsExtensionSupported() function instead.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static bool Load(string function)
|
||||
{
|
||||
// Glu does not contain any extensions - this method does nothing.
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static bool SupportsExtension(string name)
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified GLU extension is available in
|
||||
/// the current GLU context.
|
||||
/// </summary>
|
||||
/// <param name="name">The string for the GLU extension.</param>
|
||||
/// <returns>True if the specified extension is available, false otherwise.</returns>
|
||||
public static bool SupportsExtension(string name)
|
||||
{
|
||||
if (rebuildExtensionList)
|
||||
{
|
||||
BuildExtensionList();
|
||||
}
|
||||
|
||||
// Search the cache for the string. Note that the cache substitutes
|
||||
// strings "1.0" to "2.1" with "GL_VERSION_1_0" to "GL_VERSION_2_1"
|
||||
if (AvailableExtensions.ContainsKey(name))
|
||||
{
|
||||
return AvailableExtensions[name];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static void BuildExtensionList()
|
||||
|
||||
/// <summary>
|
||||
/// Builds a cache of the supported extensions to speed up searches.
|
||||
/// </summary>
|
||||
private static void BuildExtensionList()
|
||||
{
|
||||
// Assumes there is an opengl context current.
|
||||
|
||||
AvailableExtensions.Clear();
|
||||
|
||||
string version_string = Glu.GetString(GluStringName.Version);
|
||||
if (String.IsNullOrEmpty(version_string))
|
||||
{
|
||||
throw new ApplicationException("Failed to build extension list. Is there an opengl context current?");
|
||||
}
|
||||
|
||||
string version = version_string.Trim(' ');
|
||||
if (version.StartsWith("1.0"))
|
||||
{
|
||||
AvailableExtensions.Add("VERSION_1_0", true);
|
||||
}
|
||||
else if (version.StartsWith("1.1"))
|
||||
{
|
||||
AvailableExtensions.Add("VERSION_1_0", true);
|
||||
AvailableExtensions.Add("VERSION_1_1", true);
|
||||
}
|
||||
else if (version.StartsWith("1.2"))
|
||||
{
|
||||
AvailableExtensions.Add("VERSION_1_0", true);
|
||||
AvailableExtensions.Add("VERSION_1_1", true);
|
||||
AvailableExtensions.Add("VERSION_1_2", true);
|
||||
}
|
||||
else if (version.StartsWith("1.3"))
|
||||
{
|
||||
AvailableExtensions.Add("VERSION_1_0", true);
|
||||
AvailableExtensions.Add("VERSION_1_1", true);
|
||||
AvailableExtensions.Add("VERSION_1_2", true);
|
||||
AvailableExtensions.Add("VERSION_1_3", true);
|
||||
}
|
||||
|
||||
string extension_string = Glu.GetString(GluStringName.Extensions);
|
||||
if (String.IsNullOrEmpty(extension_string))
|
||||
{ // no extensions are available
|
||||
return;
|
||||
}
|
||||
|
||||
string[] extensions = extension_string.Split(' ');
|
||||
foreach (string ext in extensions)
|
||||
{
|
||||
AvailableExtensions.Add(ext, true);
|
||||
}
|
||||
|
||||
rebuildExtensionList = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overloads
|
||||
|
||||
public static void LookAt(Vector3 eye, Vector3 center, Vector3 up)
|
||||
{
|
||||
Delegates.gluLookAt((double)eye.X, (double)eye.Y, (double)eye.Z, (double)center.X, (double)center.Y, (double)center.Z, (double)up.X, (double)up.Y, (double)up.Z);
|
||||
}
|
||||
|
||||
// One token Project overload, I picked this one because it's CLS compliant, and it
|
||||
// makes reasonably clear which args are inputs and which are outputs.
|
||||
public static Int32 Project(Vector3 obj, double[] model, double[] proj, Int32[] view, out Vector3 win)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
double winX, winY, winZ;
|
||||
double* winX_ptr = &winX;
|
||||
double* winY_ptr = &winY;
|
||||
double* winZ_ptr = &winZ;
|
||||
fixed (double* model_ptr = model)
|
||||
fixed (double* proj_ptr = proj)
|
||||
fixed (Int32* view_ptr = view)
|
||||
{
|
||||
Int32 retval = Delegates.gluProject((double)obj.X, (double)obj.Y, (double)obj.Z, (double*)model_ptr, (double*)proj_ptr, (Int32*)view_ptr, (double*)winX_ptr, (double*)winY_ptr, (double*)winZ_ptr);
|
||||
win = new Vector3((float)*winX_ptr, (float)*winY_ptr, (float)*winZ_ptr);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void TessNormal(IntPtr tess, Vector3 normal)
|
||||
{
|
||||
Delegates.gluTessNormal(tess, (double)normal.X, (double)normal.Y, (double)normal.Z);
|
||||
}
|
||||
|
||||
public static Int32 UnProject(Vector3 win, double[] model, double[] proj, Int32[] view, out Vector3 obj)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
double objX, objY, objZ;
|
||||
double* objX_ptr = &objX;
|
||||
double* objY_ptr = &objY;
|
||||
double* objZ_ptr = &objZ;
|
||||
fixed (double* model_ptr = model)
|
||||
fixed (double* proj_ptr = proj)
|
||||
fixed (Int32* view_ptr = view)
|
||||
{
|
||||
Int32 retval = Delegates.gluUnProject((double)win.X, (double)win.Y, (double)win.Z, (double*)model_ptr, (double*)proj_ptr, (Int32*)view_ptr, (double*)objX_ptr, (double*)objY_ptr, (double*)objZ_ptr);
|
||||
obj = new Vector3((float)*objX_ptr, (float)*objY_ptr, (float)*objZ_ptr);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Int32 UnProject4(Vector4 win, double[] model, double[] proj, Int32[] view, double near, double far, out Vector4 obj)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
double objX, objY, objZ, objW;
|
||||
double* objX_ptr = &objX;
|
||||
double* objY_ptr = &objY;
|
||||
double* objZ_ptr = &objZ;
|
||||
double* objW_ptr = &objW;
|
||||
fixed (double* model_ptr = model)
|
||||
fixed (double* proj_ptr = proj)
|
||||
fixed (Int32* view_ptr = view)
|
||||
{
|
||||
Int32 retval = Delegates.gluUnProject4((double)win.X, (double)win.Y, (double)win.Z, (double)win.W, (double*)model_ptr, (double*)proj_ptr, (Int32*)view_ptr, (double)near, (double)far, (double*)objX_ptr, (double*)objY_ptr, (double*)objZ_ptr, (double*)objW_ptr);
|
||||
obj = new Vector4((float)*objX_ptr, (float)*objY_ptr, (float)*objZ_ptr, (float)*objW_ptr);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ErrorString(ErrorCode error)
|
||||
{
|
||||
return ErrorString((GluErrorCode)error);
|
||||
}
|
||||
|
||||
public static void TessWindingRuleProperty(IntPtr tess, TessWinding property)
|
||||
{
|
||||
Glu.TessProperty(tess, TessParameter.TessWindingRule, (double)property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
//public delegate object
|
||||
|
||||
public delegate void FastVoidInvokeHandler(object target, object[] paramters);
|
||||
public delegate object FastInvokeHandler(object target, object[] paramters);
|
||||
public static class FastInvoker
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this one instead of MethodInfo.Invoke, this way it is 50 times quicker.
|
||||
///
|
||||
/// <example>
|
||||
/// string Filter = "FirstName = 'Ton'"
|
||||
/// MethodInfo mi = typeof(Person).GetMethod("GetAll");
|
||||
/// snoei.net.Reflection.FastInvoker.FastInvokeHandler fi = snoei.net.Reflection.FastInvoker.GetMethodInvoker( mi );
|
||||
// return fi.Invoke( Person, new object[]{Filter} );
|
||||
/// //Calls Person.GetAll(string Filter);
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="methodInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static Delegate GetMethodInvoker(MethodInfo methodInfo)
|
||||
{
|
||||
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, methodInfo.ReturnType, new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
|
||||
ILGenerator il = dynamicMethod.GetILGenerator();
|
||||
ParameterInfo[] ps = methodInfo.GetParameters();
|
||||
Type[] paramTypes = new Type[ps.Length];
|
||||
|
||||
for (int i = 0; i < paramTypes.Length; i++)
|
||||
{
|
||||
if (ps[i].ParameterType.IsByRef)
|
||||
paramTypes[i] = ps[i].ParameterType.GetElementType();
|
||||
else
|
||||
paramTypes[i] = ps[i].ParameterType;
|
||||
}
|
||||
|
||||
LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];
|
||||
|
||||
for (int i = 0; i < paramTypes.Length; i++)
|
||||
locals[i] = il.DeclareLocal(paramTypes[i], true);
|
||||
|
||||
for (int i = 0; i < paramTypes.Length; i++)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
EmitFastInt(il, i);
|
||||
il.Emit(OpCodes.Ldelem_Ref);
|
||||
EmitCastToReference(il, paramTypes[i]);
|
||||
il.Emit(OpCodes.Stloc, locals[i]);
|
||||
}
|
||||
|
||||
if (!methodInfo.IsStatic)
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
|
||||
for (int i = 0; i < paramTypes.Length; i++)
|
||||
{
|
||||
if (ps[i].ParameterType.IsByRef)
|
||||
il.Emit(OpCodes.Ldloca_S, locals[i]);
|
||||
else
|
||||
il.Emit(OpCodes.Ldloc, locals[i]);
|
||||
}
|
||||
|
||||
if (methodInfo.IsStatic)
|
||||
il.EmitCall(OpCodes.Call, methodInfo, null);
|
||||
else
|
||||
il.EmitCall(OpCodes.Callvirt, methodInfo, null);
|
||||
|
||||
if (methodInfo.ReturnType == typeof(void))
|
||||
il.Emit(OpCodes.Ldnull);
|
||||
else
|
||||
EmitBoxIfNeeded(il, methodInfo.ReturnType);
|
||||
|
||||
for (int i = 0; i < paramTypes.Length; i++)
|
||||
{
|
||||
if (ps[i].ParameterType.IsByRef)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
EmitFastInt(il, i);
|
||||
il.Emit(OpCodes.Ldloc, locals[i]);
|
||||
if (locals[i].LocalType.IsValueType)
|
||||
il.Emit(OpCodes.Box, locals[i].LocalType);
|
||||
il.Emit(OpCodes.Stelem_Ref);
|
||||
}
|
||||
}
|
||||
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
if (methodInfo.ReturnType == typeof(void))
|
||||
return dynamicMethod.CreateDelegate(typeof(FastVoidInvokeHandler));
|
||||
else
|
||||
return dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));
|
||||
}
|
||||
|
||||
private static void EmitCastToReference(ILGenerator il, System.Type type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
il.Emit(OpCodes.Unbox_Any, type);
|
||||
else
|
||||
il.Emit(OpCodes.Castclass, type);
|
||||
}
|
||||
|
||||
private static void EmitBoxIfNeeded(ILGenerator il, System.Type type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
il.Emit(OpCodes.Box, type);
|
||||
}
|
||||
|
||||
private static void EmitFastInt(ILGenerator il, int value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case -1:
|
||||
il.Emit(OpCodes.Ldc_I4_M1);
|
||||
return;
|
||||
case 0:
|
||||
il.Emit(OpCodes.Ldc_I4_0);
|
||||
return;
|
||||
case 1:
|
||||
il.Emit(OpCodes.Ldc_I4_1);
|
||||
return;
|
||||
case 2:
|
||||
il.Emit(OpCodes.Ldc_I4_2);
|
||||
return;
|
||||
case 3:
|
||||
il.Emit(OpCodes.Ldc_I4_3);
|
||||
return;
|
||||
case 4:
|
||||
il.Emit(OpCodes.Ldc_I4_4);
|
||||
return;
|
||||
case 5:
|
||||
il.Emit(OpCodes.Ldc_I4_5);
|
||||
return;
|
||||
case 6:
|
||||
il.Emit(OpCodes.Ldc_I4_6);
|
||||
return;
|
||||
case 7:
|
||||
il.Emit(OpCodes.Ldc_I4_7);
|
||||
return;
|
||||
case 8:
|
||||
il.Emit(OpCodes.Ldc_I4_8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > -129 && value < 128)
|
||||
il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
|
||||
else
|
||||
il.Emit(OpCodes.Ldc_I4, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
261
Source/Compatibility/Math/BezierCurve.cs
Normal file
261
Source/Compatibility/Math/BezierCurve.cs
Normal file
|
@ -0,0 +1,261 @@
|
|||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*
|
||||
* Contributions by Georg W<EFBFBD>chter.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a bezier curve with as many points as you want.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct BezierCurve
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private List<Vector2> points;
|
||||
|
||||
/// <summary>
|
||||
/// The parallel value.
|
||||
/// </summary>
|
||||
/// <remarks>This value defines whether the curve should be calculated as a
|
||||
/// parallel curve to the original bezier curve. A value of 0.0f represents
|
||||
/// the original curve, 5.0f i.e. stands for a curve that has always a distance
|
||||
/// of 5.0f to the orignal curve at any point.</remarks>
|
||||
public float Parallel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the points of this curve.
|
||||
/// </summary>
|
||||
/// <remarks>The first point and the last points represent the anchor points.</remarks>
|
||||
public IList<Vector2> Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return points;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurve"/>.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
public BezierCurve(IEnumerable<Vector2> points)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
|
||||
|
||||
this.points = new List<Vector2>(points);
|
||||
this.Parallel = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurve"/>.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
public BezierCurve(params Vector2[] points)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
|
||||
|
||||
this.points = new List<Vector2>(points);
|
||||
this.Parallel = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurve"/>.
|
||||
/// </summary>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <param name="points">The points.</param>
|
||||
public BezierCurve(float parallel, params Vector2[] points)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
|
||||
|
||||
this.Parallel = parallel;
|
||||
this.points = new List<Vector2>(points);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurve"/>.
|
||||
/// </summary>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <param name="points">The points.</param>
|
||||
public BezierCurve(float parallel, IEnumerable<Vector2> points)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures.");
|
||||
|
||||
this.Parallel = parallel;
|
||||
this.points = new List<Vector2>(points);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t.
|
||||
/// </summary>
|
||||
/// <param name="t">The t value, between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
public Vector2 CalculatePoint(float t)
|
||||
{
|
||||
return BezierCurve.CalculatePoint(points, t, Parallel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of this bezier curve.
|
||||
/// </summary>
|
||||
/// <param name="precision">The precision.</param>
|
||||
/// <returns>Length of curve.</returns>
|
||||
/// <remarks>The precision gets better as the <paramref name="precision"/>
|
||||
/// value gets smaller.</remarks>
|
||||
public float CalculateLength(float precision)
|
||||
{
|
||||
return BezierCurve.CalculateLength(points, precision, Parallel);
|
||||
}
|
||||
|
||||
#region Static methods
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of the specified bezier curve.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="precision">The precision value.</param>
|
||||
/// <returns>The precision gets better as the <paramref name="precision"/>
|
||||
/// value gets smaller.</returns>
|
||||
public static float CalculateLength(IList<Vector2> points, float precision)
|
||||
{
|
||||
return BezierCurve.CalculateLength(points, precision, 0.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of the specified bezier curve.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="precision">The precision value.</param>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <returns>Length of curve.</returns>
|
||||
/// <remarks><para>The precision gets better as the <paramref name="precision"/>
|
||||
/// value gets smaller.</para>
|
||||
/// <para>The <paramref name="parallel"/> parameter defines whether the curve should be calculated as a
|
||||
/// parallel curve to the original bezier curve. A value of 0.0f represents
|
||||
/// the original curve, 5.0f represents a curve that has always a distance
|
||||
/// of 5.0f to the orignal curve.</para></remarks>
|
||||
public static float CalculateLength(IList<Vector2> points, float precision, float parallel)
|
||||
{
|
||||
float length = 0.0f;
|
||||
Vector2 old = BezierCurve.CalculatePoint(points, 0.0f, parallel);
|
||||
|
||||
for (float i = precision; i < (1.0f + precision); i += precision)
|
||||
{
|
||||
Vector2 n = CalculatePoint(points, i, parallel);
|
||||
length += (n - old).Length;
|
||||
old = n;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point on the given bezier curve with the specified t parameter.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="t">The t parameter, a value between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
public static Vector2 CalculatePoint(IList<Vector2> points, float t)
|
||||
{
|
||||
return BezierCurve.CalculatePoint(points, t, 0.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point on the given bezier curve with the specified t parameter.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="t">The t parameter, a value between 0.0f and 1.0f.</param>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
/// <remarks>The <paramref name="parallel"/> parameter defines whether the curve should be calculated as a
|
||||
/// parallel curve to the original bezier curve. A value of 0.0f represents
|
||||
/// the original curve, 5.0f represents a curve that has always a distance
|
||||
/// of 5.0f to the orignal curve.</remarks>
|
||||
public static Vector2 CalculatePoint(IList<Vector2> points, float t, float parallel)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
double c = 1.0d - (double)t;
|
||||
float temp;
|
||||
int i = 0;
|
||||
|
||||
foreach (Vector2 pt in points)
|
||||
{
|
||||
temp = (float)Functions.BinomialCoefficient(points.Count - 1, i) * (float)(System.Math.Pow(t, i) *
|
||||
System.Math.Pow(c, (points.Count - 1) - i));
|
||||
|
||||
r.X += temp * pt.X;
|
||||
r.Y += temp * pt.Y;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (parallel == 0.0f)
|
||||
return r;
|
||||
|
||||
Vector2 perpendicular = new Vector2();
|
||||
|
||||
if (t != 0.0f)
|
||||
perpendicular = r - BezierCurve.CalculatePointOfDerivative(points, t);
|
||||
else
|
||||
perpendicular = points[1] - points[0];
|
||||
|
||||
return r + Vector2.Normalize(perpendicular).PerpendicularRight * parallel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t of the derivative of the given bezier function.
|
||||
/// </summary>
|
||||
/// <param name="points">The points.</param>
|
||||
/// <param name="t">The t parameter, value between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
private static Vector2 CalculatePointOfDerivative(IList<Vector2> points, float t)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
double c = 1.0d - (double)t;
|
||||
float temp;
|
||||
int i = 0;
|
||||
|
||||
foreach (Vector2 pt in points)
|
||||
{
|
||||
temp = (float)Functions.BinomialCoefficient(points.Count - 2, i) * (float)(System.Math.Pow(t, i) *
|
||||
System.Math.Pow(c, (points.Count - 2) - i));
|
||||
|
||||
r.X += temp * pt.X;
|
||||
r.Y += temp * pt.Y;
|
||||
i++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
163
Source/Compatibility/Math/BezierCurveCubic.cs
Normal file
163
Source/Compatibility/Math/BezierCurveCubic.cs
Normal file
|
@ -0,0 +1,163 @@
|
|||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*
|
||||
* Contributions by Georg W<EFBFBD>chter.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cubic bezier curve with two anchor and two control points.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct BezierCurveCubic
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Start anchor point.
|
||||
/// </summary>
|
||||
public Vector2 StartAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// End anchor point.
|
||||
/// </summary>
|
||||
public Vector2 EndAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// First control point, controls the direction of the curve start.
|
||||
/// </summary>
|
||||
public Vector2 FirstControlPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Second control point, controls the direction of the curve end.
|
||||
/// </summary>
|
||||
public Vector2 SecondControlPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parallel value.
|
||||
/// </summary>
|
||||
/// <remarks>This value defines whether the curve should be calculated as a
|
||||
/// parallel curve to the original bezier curve. A value of 0.0f represents
|
||||
/// the original curve, 5.0f i.e. stands for a curve that has always a distance
|
||||
/// of 5.f to the orignal curve at any point.</remarks>
|
||||
public float Parallel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurveCubic"/>.
|
||||
/// </summary>
|
||||
/// <param name="startAnchor">The start anchor point.</param>
|
||||
/// <param name="endAnchor">The end anchor point.</param>
|
||||
/// <param name="firstControlPoint">The first control point.</param>
|
||||
/// <param name="secondControlPoint">The second control point.</param>
|
||||
public BezierCurveCubic(Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint)
|
||||
{
|
||||
this.StartAnchor = startAnchor;
|
||||
this.EndAnchor = endAnchor;
|
||||
this.FirstControlPoint = firstControlPoint;
|
||||
this.SecondControlPoint = secondControlPoint;
|
||||
this.Parallel = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurveCubic"/>.
|
||||
/// </summary>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <param name="startAnchor">The start anchor point.</param>
|
||||
/// <param name="endAnchor">The end anchor point.</param>
|
||||
/// <param name="firstControlPoint">The first control point.</param>
|
||||
/// <param name="secondControlPoint">The second control point.</param>
|
||||
public BezierCurveCubic(float parallel, Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint)
|
||||
{
|
||||
this.Parallel = parallel;
|
||||
this.StartAnchor = startAnchor;
|
||||
this.EndAnchor = endAnchor;
|
||||
this.FirstControlPoint = firstControlPoint;
|
||||
this.SecondControlPoint = secondControlPoint;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t.
|
||||
/// </summary>
|
||||
/// <param name="t">The t value, between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
public Vector2 CalculatePoint(float t)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
float c = 1.0f - t;
|
||||
|
||||
r.X = (StartAnchor.X * c * c * c) + (FirstControlPoint.X * 3 * t * c * c) + (SecondControlPoint.X * 3 * t * t * c)
|
||||
+ EndAnchor.X * t * t * t;
|
||||
r.Y = (StartAnchor.Y * c * c * c) + (FirstControlPoint.Y * 3 * t * c * c) + (SecondControlPoint.Y * 3 * t * t * c)
|
||||
+ EndAnchor.Y * t * t * t;
|
||||
|
||||
if (Parallel == 0.0f)
|
||||
return r;
|
||||
|
||||
Vector2 perpendicular = new Vector2();
|
||||
|
||||
if (t == 0.0f)
|
||||
perpendicular = FirstControlPoint - StartAnchor;
|
||||
else
|
||||
perpendicular = r - CalculatePointOfDerivative(t);
|
||||
|
||||
return r + Vector2.Normalize(perpendicular).PerpendicularRight * Parallel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t of the derivative of this function.
|
||||
/// </summary>
|
||||
/// <param name="t">The t, value between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
private Vector2 CalculatePointOfDerivative(float t)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
float c = 1.0f - t;
|
||||
|
||||
r.X = (c * c * StartAnchor.X) + (2 * t * c * FirstControlPoint.X) + (t * t * SecondControlPoint.X);
|
||||
r.Y = (c * c * StartAnchor.Y) + (2 * t * c * FirstControlPoint.Y) + (t * t * SecondControlPoint.Y);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of this bezier curve.
|
||||
/// </summary>
|
||||
/// <param name="precision">The precision.</param>
|
||||
/// <returns>Length of the curve.</returns>
|
||||
/// <remarks>The precision gets better when the <paramref name="precision"/>
|
||||
/// value gets smaller.</remarks>
|
||||
public float CalculateLength(float precision)
|
||||
{
|
||||
float length = 0.0f;
|
||||
Vector2 old = CalculatePoint(0.0f);
|
||||
|
||||
for (float i = precision; i < (1.0f + precision); i += precision)
|
||||
{
|
||||
Vector2 n = CalculatePoint(i);
|
||||
length += (n - old).Length;
|
||||
old = n;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
151
Source/Compatibility/Math/BezierCurveQuadric.cs
Normal file
151
Source/Compatibility/Math/BezierCurveQuadric.cs
Normal file
|
@ -0,0 +1,151 @@
|
|||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*
|
||||
* Contributions by Georg W<EFBFBD>chter.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a quadric bezier curve with two anchor and one control point.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct BezierCurveQuadric
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Start anchor point.
|
||||
/// </summary>
|
||||
public Vector2 StartAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// End anchor point.
|
||||
/// </summary>
|
||||
public Vector2 EndAnchor;
|
||||
|
||||
/// <summary>
|
||||
/// Control point, controls the direction of both endings of the curve.
|
||||
/// </summary>
|
||||
public Vector2 ControlPoint;
|
||||
|
||||
/// <summary>
|
||||
/// The parallel value.
|
||||
/// </summary>
|
||||
/// <remarks>This value defines whether the curve should be calculated as a
|
||||
/// parallel curve to the original bezier curve. A value of 0.0f represents
|
||||
/// the original curve, 5.0f i.e. stands for a curve that has always a distance
|
||||
/// of 5.f to the orignal curve at any point.</remarks>
|
||||
public float Parallel;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurveQuadric"/>.
|
||||
/// </summary>
|
||||
/// <param name="startAnchor">The start anchor.</param>
|
||||
/// <param name="endAnchor">The end anchor.</param>
|
||||
/// <param name="controlPoint">The control point.</param>
|
||||
public BezierCurveQuadric(Vector2 startAnchor, Vector2 endAnchor, Vector2 controlPoint)
|
||||
{
|
||||
this.StartAnchor = startAnchor;
|
||||
this.EndAnchor = endAnchor;
|
||||
this.ControlPoint = controlPoint;
|
||||
this.Parallel = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="BezierCurveQuadric"/>.
|
||||
/// </summary>
|
||||
/// <param name="parallel">The parallel value.</param>
|
||||
/// <param name="startAnchor">The start anchor.</param>
|
||||
/// <param name="endAnchor">The end anchor.</param>
|
||||
/// <param name="controlPoint">The control point.</param>
|
||||
public BezierCurveQuadric(float parallel, Vector2 startAnchor, Vector2 endAnchor, Vector2 controlPoint)
|
||||
{
|
||||
this.Parallel = parallel;
|
||||
this.StartAnchor = startAnchor;
|
||||
this.EndAnchor = endAnchor;
|
||||
this.ControlPoint = controlPoint;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t.
|
||||
/// </summary>
|
||||
/// <param name="t">The t value, between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
public Vector2 CalculatePoint(float t)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
float c = 1.0f - t;
|
||||
|
||||
r.X = (c * c * StartAnchor.X) + (2 * t * c * ControlPoint.X) + (t * t * EndAnchor.X);
|
||||
r.Y = (c * c * StartAnchor.Y) + (2 * t * c * ControlPoint.Y) + (t * t * EndAnchor.Y);
|
||||
|
||||
if (Parallel == 0.0f)
|
||||
return r;
|
||||
|
||||
Vector2 perpendicular = new Vector2();
|
||||
|
||||
if (t == 0.0f)
|
||||
perpendicular = ControlPoint - StartAnchor;
|
||||
else
|
||||
perpendicular = r - CalculatePointOfDerivative(t);
|
||||
|
||||
return r + Vector2.Normalize(perpendicular).PerpendicularRight * Parallel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the point with the specified t of the derivative of this function.
|
||||
/// </summary>
|
||||
/// <param name="t">The t, value between 0.0f and 1.0f.</param>
|
||||
/// <returns>Resulting point.</returns>
|
||||
private Vector2 CalculatePointOfDerivative(float t)
|
||||
{
|
||||
Vector2 r = new Vector2();
|
||||
|
||||
r.X = (1.0f - t) * StartAnchor.X + t * ControlPoint.X;
|
||||
r.Y = (1.0f - t) * StartAnchor.Y + t * ControlPoint.Y;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of this bezier curve.
|
||||
/// </summary>
|
||||
/// <param name="precision">The precision.</param>
|
||||
/// <returns>Length of curve.</returns>
|
||||
/// <remarks>The precision gets better when the <paramref name="precision"/>
|
||||
/// value gets smaller.</remarks>
|
||||
public float CalculateLength(float precision)
|
||||
{
|
||||
float length = 0.0f;
|
||||
Vector2 old = CalculatePoint(0.0f);
|
||||
|
||||
for (float i = precision; i < (1.0f + precision); i += precision)
|
||||
{
|
||||
Vector2 n = CalculatePoint(i);
|
||||
length += (n - old).Length;
|
||||
old = n;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
96
Source/Compatibility/Math/Box2.cs
Normal file
96
Source/Compatibility/Math/Box2.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
#region --- License ---
|
||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* See license.txt for license info
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a 2d box (rectangle).
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Box2
|
||||
{
|
||||
/// <summary>
|
||||
/// The left boundary of the structure.
|
||||
/// </summary>
|
||||
public float Left;
|
||||
|
||||
/// <summary>
|
||||
/// The right boundary of the structure.
|
||||
/// </summary>
|
||||
public float Right;
|
||||
|
||||
/// <summary>
|
||||
/// The top boundary of the structure.
|
||||
/// </summary>
|
||||
public float Top;
|
||||
|
||||
/// <summary>
|
||||
/// The bottom boundary of the structure.
|
||||
/// </summary>
|
||||
public float Bottom;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Box2 with the specified dimensions.
|
||||
/// </summary>
|
||||
/// <param name="topLeft">AnOpenTK.Vector2 describing the top-left corner of the Box2.</param>
|
||||
/// <param name="bottomRight">An OpenTK.Vector2 describing the bottom-right corner of the Box2.</param>
|
||||
public Box2(Vector2 topLeft, Vector2 bottomRight)
|
||||
{
|
||||
Left = topLeft.X;
|
||||
Top = topLeft.Y;
|
||||
Right = topLeft.X;
|
||||
Bottom = topLeft.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Box2 with the specified dimensions.
|
||||
/// </summary>
|
||||
/// <param name="left">The position of the left boundary.</param>
|
||||
/// <param name="top">The position of the top boundary.</param>
|
||||
/// <param name="right">The position of the right boundary.</param>
|
||||
/// <param name="bottom">The position of the bottom boundary.</param>
|
||||
public Box2(float left, float top, float right, float bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Box2 with the specified dimensions.
|
||||
/// </summary>
|
||||
/// <param name="top">The position of the top boundary.</param>
|
||||
/// <param name="left">The position of the left boundary.</param>
|
||||
/// <param name="right">The position of the right boundary.</param>
|
||||
/// <param name="bottom">The position of the bottom boundary.</param>
|
||||
/// <returns>A new OpenTK.Box2 with the specfied dimensions.</returns>
|
||||
public static Box2 FromTLRB(float top, float left, float right, float bottom)
|
||||
{
|
||||
return new Box2(left, top, right, bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a float describing the width of the Box2 structure.
|
||||
/// </summary>
|
||||
public float Width { get { return (float)System.Math.Abs(Right - Left); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a float describing the height of the Box2 structure.
|
||||
/// </summary>
|
||||
public float Height { get { return (float)System.Math.Abs(Bottom - Top); } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0},{1})-({2},{3})", Left, Top, Right, Bottom);
|
||||
}
|
||||
}
|
||||
}
|
326
Source/Compatibility/Math/Functions.cs
Normal file
326
Source/Compatibility/Math/Functions.cs
Normal file
|
@ -0,0 +1,326 @@
|
|||
#region --- License ---
|
||||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*
|
||||
* Contributions by Andy Gill, James Talton and Georg Wächter.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains mathematical functions for the OpenTK.Math toolkit.
|
||||
/// </summary>
|
||||
public static class Functions
|
||||
{
|
||||
#region public static long NextPowerOfTwo(long n)
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next power of two that is larger than the specified number.
|
||||
/// </summary>
|
||||
/// <param name="n">The specified number.</param>
|
||||
/// <returns>The next power of two.</returns>
|
||||
public static long NextPowerOfTwo(long n)
|
||||
{
|
||||
if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
|
||||
return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static int NextPowerOfTwo(int n)
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next power of two that is larger than the specified number.
|
||||
/// </summary>
|
||||
/// <param name="n">The specified number.</param>
|
||||
/// <returns>The next power of two.</returns>
|
||||
public static int NextPowerOfTwo(int n)
|
||||
{
|
||||
if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
|
||||
return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static int NextPowerOfTwo(int n)
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next power of two that is larger than the specified number.
|
||||
/// </summary>
|
||||
/// <param name="n">The specified number.</param>
|
||||
/// <returns>The next power of two.</returns>
|
||||
public static float NextPowerOfTwo(float n)
|
||||
{
|
||||
if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
|
||||
return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region public static int NextPowerOfTwo(int n)
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next power of two that is larger than the specified number.
|
||||
/// </summary>
|
||||
/// <param name="n">The specified number.</param>
|
||||
/// <returns>The next power of two.</returns>
|
||||
public static double NextPowerOfTwo(double n)
|
||||
{
|
||||
if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive.");
|
||||
return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>Calculates the factorial of a given natural number.
|
||||
/// </summary>
|
||||
/// <param name="n">The number.</param>
|
||||
/// <returns>n!</returns>
|
||||
public static long Factorial(int n)
|
||||
{
|
||||
long result = 1;
|
||||
|
||||
for (; n > 1; n--)
|
||||
result *= n;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the binomial coefficient <paramref name="n"/> above <paramref name="k"/>.
|
||||
/// </summary>
|
||||
/// <param name="n">The n.</param>
|
||||
/// <param name="k">The k.</param>
|
||||
/// <returns>n! / (k! * (n - k)!)</returns>
|
||||
public static long BinomialCoefficient(int n, int k)
|
||||
{
|
||||
return Factorial(n) / (Factorial(k) * Factorial(n - k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an approximation of the inverse square root of left number.
|
||||
/// </summary>
|
||||
/// <param name="x">A number.</param>
|
||||
/// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns>
|
||||
/// <remarks>
|
||||
/// This is an improved implementation of the the method known as Carmack's inverse square root
|
||||
/// which is found in the Quake III source code. This implementation comes from
|
||||
/// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see
|
||||
/// http://www.beyond3d.com/content/articles/8/
|
||||
/// </remarks>
|
||||
public static float InverseSqrtFast(float x)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
float xhalf = 0.5f * x;
|
||||
int i = *(int*)&x; // Read bits as integer.
|
||||
i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation
|
||||
x = *(float*)&i; // Convert bits back to float
|
||||
x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step.
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an approximation of the inverse square root of left number.
|
||||
/// </summary>
|
||||
/// <param name="x">A number.</param>
|
||||
/// <returns>An approximation of the inverse square root of the specified number, with an upper error bound of 0.001</returns>
|
||||
/// <remarks>
|
||||
/// This is an improved implementation of the the method known as Carmack's inverse square root
|
||||
/// which is found in the Quake III source code. This implementation comes from
|
||||
/// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see
|
||||
/// http://www.beyond3d.com/content/articles/8/
|
||||
/// </remarks>
|
||||
public static double InverseSqrtFast(double x)
|
||||
{
|
||||
return InverseSqrtFast((float)x);
|
||||
// TODO: The following code is wrong. Fix it, to improve precision.
|
||||
#if false
|
||||
unsafe
|
||||
{
|
||||
double xhalf = 0.5f * x;
|
||||
int i = *(int*)&x; // Read bits as integer.
|
||||
i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation
|
||||
x = *(float*)&i; // Convert bits back to float
|
||||
x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step.
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert degrees to radians
|
||||
/// </summary>
|
||||
/// <param name="degrees">An angle in degrees</param>
|
||||
/// <returns>The angle expressed in radians</returns>
|
||||
public static float DegreesToRadians(float degrees)
|
||||
{
|
||||
const float degToRad = (float)System.Math.PI / 180.0f;
|
||||
return degrees * degToRad;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert radians to degrees
|
||||
/// </summary>
|
||||
/// <param name="radians">An angle in radians</param>
|
||||
/// <returns>The angle expressed in degrees</returns>
|
||||
public static float RadiansToDegrees(float radians)
|
||||
{
|
||||
const float radToDeg = 180.0f / (float)System.Math.PI;
|
||||
return radians * radToDeg;
|
||||
}
|
||||
|
||||
public static readonly float PIF = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f;
|
||||
public static readonly float RTODF = 180.0f / PIF;
|
||||
public static readonly float DTORF = PIF / 180.0f;
|
||||
|
||||
public static readonly double PI = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382d;
|
||||
public static readonly double RTOD = 180.0d / PIF;
|
||||
public static readonly double DTOR = PIF / 180.0d;
|
||||
|
||||
public static void Swap(ref double a, ref double b)
|
||||
{
|
||||
double temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
public static void Swap(ref float a, ref float b)
|
||||
{
|
||||
float temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
}
|
||||
|
||||
#if false
|
||||
public static partial class Math
|
||||
{
|
||||
#region --- Vectors ---
|
||||
|
||||
#region --- Addition ---
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector2 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector2 Add(Vector2 left, Vector2 right)
|
||||
{
|
||||
return new Vector2(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector3 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector3 Add(Vector2 left, Vector3 right)
|
||||
{
|
||||
return new Vector3(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector4 containing the result of the addition.</returns>
|
||||
public static Vector4 Add(Vector2 left, Vector4 right)
|
||||
{
|
||||
return new Vector4(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector2 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector3 Add(Vector3 left, Vector2 right)
|
||||
{
|
||||
return new Vector3(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector3 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector3 Add(Vector3 left, Vector3 right)
|
||||
{
|
||||
return new Vector3(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector4 containing the result of the addition.</returns>
|
||||
public static Vector4 Add(Vector3 left, Vector4 right)
|
||||
{
|
||||
return new Vector4(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector2 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector4 Add(Vector4 left, Vector2 right)
|
||||
{
|
||||
return new Vector4(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector3 to the current Vector3.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector3 containing the result of the addition.</returns>
|
||||
public static Vector4 Add(Vector4 left, Vector3 right)
|
||||
{
|
||||
return new Vector4(left).Add(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the addition.</param>
|
||||
/// <returns>A new Vector4 containing the result of the addition.</returns>
|
||||
public static Vector4 Add(Vector4 left, Vector4 right)
|
||||
{
|
||||
return new Vector4(left).Add(right);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Subtraction ---
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Cross ---
|
||||
|
||||
/// <summary>
|
||||
/// Computes the cross product between the current and the given Vector3. The current Vector3 is set to the result of the computation.
|
||||
/// </summary>
|
||||
/// <param name="right">The right operand of the cross product</param>
|
||||
/// <returns>The current </returns>
|
||||
public static Vector3 Cross(Vector3 left, Vector3 right)
|
||||
{
|
||||
return new Vector3(left).Cross(right);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
}
|
588
Source/Compatibility/Math/Half.cs
Normal file
588
Source/Compatibility/Math/Half.cs
Normal file
|
@ -0,0 +1,588 @@
|
|||
#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.
|
||||
*/
|
||||
/*
|
||||
The conversion functions are derived from OpenEXR's implementation and are
|
||||
governed by the following license:
|
||||
|
||||
Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
|
||||
Digital Ltd. LLC
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Industrial Light & Magic nor the names of
|
||||
its contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#endregion --- License ---
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The name Half is derived from half-precision floating-point number.
|
||||
/// It occupies only 16 Bits, which are split into 1 Sign bit, 5 Exponent bits and 10 Mantissa bits.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Quote from ARB_half_float_pixel specification:
|
||||
/// Any representable 16-bit floating-point value is legal as input to a GL command that accepts 16-bit floating-point data. The
|
||||
/// result of providing a value that is not a floating-point number (such as infinity or NaN) to such a command is unspecified,
|
||||
/// but must not lead to GL interruption or termination. Providing a denormalized number or negative zero to GL must yield
|
||||
/// predictable results.
|
||||
/// </remarks>
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
public struct Half : ISerializable, IComparable<Half>, IFormattable, IEquatable<Half>
|
||||
{
|
||||
#region Internal Field
|
||||
|
||||
UInt16 bits;
|
||||
|
||||
#endregion Internal Field
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>Returns true if the Half is zero.</summary>
|
||||
public bool IsZero { get { return (bits == 0) || (bits == 0x8000); } }
|
||||
|
||||
/// <summary>Returns true if the Half represents Not A Number (NaN)</summary>
|
||||
public bool IsNaN { get { return (((bits & 0x7C00) == 0x7C00) && (bits & 0x03FF) != 0x0000); } }
|
||||
|
||||
/// <summary>Returns true if the Half represents positive infinity.</summary>
|
||||
public bool IsPositiveInfinity { get { return (bits == 31744); } }
|
||||
|
||||
/// <summary>Returns true if the Half represents negative infinity.</summary>
|
||||
public bool IsNegativeInfinity { get { return (bits == 64512); } }
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// The new Half instance will convert the parameter into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="f">32-Bit Single precision floating point number.</param>
|
||||
public Half(Single f)
|
||||
: this()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
bits = SingleToHalf(*(int*)&f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half instance will convert the parameter into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="f">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Half(Single f, bool throwOnError)
|
||||
: this(f)
|
||||
{
|
||||
if (throwOnError)
|
||||
{
|
||||
// handle cases that cause overflow rather than silently ignoring it
|
||||
if (f > Half.MaxValue) throw new ArithmeticException("Half: Positive maximum value exceeded.");
|
||||
if (f < -Half.MaxValue) throw new ArithmeticException("Half: Negative minimum value exceeded.");
|
||||
|
||||
// handle cases that make no sense
|
||||
if (Single.IsNaN(f)) throw new ArithmeticException("Half: input is Not a Number (NaN).");
|
||||
if (Single.IsPositiveInfinity(f)) throw new ArithmeticException("Half: input is +infinity.");
|
||||
if (Single.IsNegativeInfinity(f)) throw new ArithmeticException("Half: input is -infinity.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half instance will convert the parameter into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="d">64-Bit Double precision floating point number.</param>
|
||||
public Half(Double d) : this((Single)d) { }
|
||||
|
||||
/// <summary>
|
||||
/// The new Half instance will convert the parameter into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="d">64-Bit Double precision floating point number.</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Half(Double d, bool throwOnError) : this((Single)d, throwOnError) { }
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Single -> Half
|
||||
|
||||
/// <summary>Ported from OpenEXR's IlmBase 1.0.1</summary>
|
||||
private UInt16 SingleToHalf(Int32 si32)
|
||||
{
|
||||
// Our floating point number, F, is represented by the bit pattern in integer i.
|
||||
// Disassemble that bit pattern into the sign, S, the exponent, E, and the significand, M.
|
||||
// Shift S into the position where it will go in in the resulting half number.
|
||||
// Adjust E, accounting for the different exponent bias of float and half (127 versus 15).
|
||||
|
||||
Int32 sign = (si32 >> 16) & 0x00008000;
|
||||
Int32 exponent = ((si32 >> 23) & 0x000000ff) - (127 - 15);
|
||||
Int32 mantissa = si32 & 0x007fffff;
|
||||
|
||||
// Now reassemble S, E and M into a half:
|
||||
|
||||
if (exponent <= 0)
|
||||
{
|
||||
if (exponent < -10)
|
||||
{
|
||||
// E is less than -10. The absolute value of F is less than Half.MinValue
|
||||
// (F may be a small normalized float, a denormalized float or a zero).
|
||||
//
|
||||
// We convert F to a half zero with the same sign as F.
|
||||
|
||||
return (UInt16)sign;
|
||||
}
|
||||
|
||||
// E is between -10 and 0. F is a normalized float whose magnitude is less than Half.MinNormalizedValue.
|
||||
//
|
||||
// We convert F to a denormalized half.
|
||||
|
||||
// Add an explicit leading 1 to the significand.
|
||||
|
||||
mantissa = mantissa | 0x00800000;
|
||||
|
||||
// Round to M to the nearest (10+E)-bit value (with E between -10 and 0); in case of a tie, round to the nearest even value.
|
||||
//
|
||||
// Rounding may cause the significand to overflow and make our number normalized. Because of the way a half's bits
|
||||
// are laid out, we don't have to treat this case separately; the code below will handle it correctly.
|
||||
|
||||
Int32 t = 14 - exponent;
|
||||
Int32 a = (1 << (t - 1)) - 1;
|
||||
Int32 b = (mantissa >> t) & 1;
|
||||
|
||||
mantissa = (mantissa + a + b) >> t;
|
||||
|
||||
// Assemble the half from S, E (==zero) and M.
|
||||
|
||||
return (UInt16)(sign | mantissa);
|
||||
}
|
||||
else if (exponent == 0xff - (127 - 15))
|
||||
{
|
||||
if (mantissa == 0)
|
||||
{
|
||||
// F is an infinity; convert F to a half infinity with the same sign as F.
|
||||
|
||||
return (UInt16)(sign | 0x7c00);
|
||||
}
|
||||
else
|
||||
{
|
||||
// F is a NAN; we produce a half NAN that preserves the sign bit and the 10 leftmost bits of the
|
||||
// significand of F, with one exception: If the 10 leftmost bits are all zero, the NAN would turn
|
||||
// into an infinity, so we have to set at least one bit in the significand.
|
||||
|
||||
mantissa >>= 13;
|
||||
return (UInt16)(sign | 0x7c00 | mantissa | ((mantissa == 0) ? 1 : 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// E is greater than zero. F is a normalized float. We try to convert F to a normalized half.
|
||||
|
||||
// Round to M to the nearest 10-bit value. In case of a tie, round to the nearest even value.
|
||||
|
||||
mantissa = mantissa + 0x00000fff + ((mantissa >> 13) & 1);
|
||||
|
||||
if ((mantissa & 0x00800000) == 1)
|
||||
{
|
||||
mantissa = 0; // overflow in significand,
|
||||
exponent += 1; // adjust exponent
|
||||
}
|
||||
|
||||
// exponent overflow
|
||||
if (exponent > 30) throw new ArithmeticException("Half: hardware floating point overflow.");
|
||||
|
||||
// Assemble the half from S, E and M.
|
||||
|
||||
return (UInt16)(sign | (exponent << 10) | (mantissa >> 13));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Single -> Half
|
||||
|
||||
#region Half -> Single
|
||||
|
||||
/// <summary>Converts the 16-Bit half to 32-Bit floating point.</summary>
|
||||
/// <returns>A Single precision floating point Number.</returns>
|
||||
public Single ToSingle()
|
||||
{
|
||||
int i = HalfToFloat(bits);
|
||||
|
||||
unsafe
|
||||
{
|
||||
return *(float*)&i;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Ported from OpenEXR's IlmBase 1.0.1</summary>
|
||||
private Int32 HalfToFloat(UInt16 ui16)
|
||||
{
|
||||
|
||||
Int32 sign = (ui16 >> 15) & 0x00000001;
|
||||
Int32 exponent = (ui16 >> 10) & 0x0000001f;
|
||||
Int32 mantissa = ui16 & 0x000003ff;
|
||||
|
||||
if (exponent == 0)
|
||||
{
|
||||
if (mantissa == 0)
|
||||
{
|
||||
// Plus or minus zero
|
||||
|
||||
return sign << 31;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Denormalized number -- renormalize it
|
||||
|
||||
while ((mantissa & 0x00000400) == 0)
|
||||
{
|
||||
mantissa <<= 1;
|
||||
exponent -= 1;
|
||||
}
|
||||
|
||||
exponent += 1;
|
||||
mantissa &= ~0x00000400;
|
||||
}
|
||||
}
|
||||
else if (exponent == 31)
|
||||
{
|
||||
if (mantissa == 0)
|
||||
{
|
||||
// Positive or negative infinity
|
||||
|
||||
return (sign << 31) | 0x7f800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nan -- preserve sign and significand bits
|
||||
|
||||
return (sign << 31) | 0x7f800000 | (mantissa << 13);
|
||||
}
|
||||
}
|
||||
|
||||
// Normalized number
|
||||
|
||||
exponent = exponent + (127 - 15);
|
||||
mantissa = mantissa << 13;
|
||||
|
||||
// Assemble S, E and M.
|
||||
|
||||
return (sign << 31) | (exponent << 23) | mantissa;
|
||||
}
|
||||
|
||||
#endregion Half -> Single
|
||||
|
||||
#region Conversions
|
||||
|
||||
/// <summary>
|
||||
/// Converts a System.Single to a OpenTK.Half.
|
||||
/// </summary>
|
||||
/// <param name="f">The value to convert.
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </param>
|
||||
/// <returns>The result of the conversion.
|
||||
/// A <see cref="Half"/>
|
||||
/// </returns>
|
||||
public static explicit operator Half(float f)
|
||||
{
|
||||
return new Half(f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a System.Double to a OpenTK.Half.
|
||||
/// </summary>
|
||||
/// <param name="d">The value to convert.
|
||||
/// A <see cref="System.Double"/>
|
||||
/// </param>
|
||||
/// <returns>The result of the conversion.
|
||||
/// A <see cref="Half"/>
|
||||
/// </returns>
|
||||
public static explicit operator Half(double d)
|
||||
{
|
||||
return new Half(d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a OpenTK.Half to a System.Single.
|
||||
/// </summary>
|
||||
/// <param name="h">The value to convert.
|
||||
/// A <see cref="Half"/>
|
||||
/// </param>
|
||||
/// <returns>The result of the conversion.
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </returns>
|
||||
public static implicit operator float(Half h)
|
||||
{
|
||||
return h.ToSingle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a OpenTK.Half to a System.Double.
|
||||
/// </summary>
|
||||
/// <param name="h">The value to convert.
|
||||
/// A <see cref="Half"/>
|
||||
/// </param>
|
||||
/// <returns>The result of the conversion.
|
||||
/// A <see cref="System.Double"/>
|
||||
/// </returns>
|
||||
public static implicit operator double(Half h)
|
||||
{
|
||||
return (double)h.ToSingle();
|
||||
}
|
||||
|
||||
#endregion Conversions
|
||||
|
||||
#region Constants
|
||||
|
||||
/// <summary>The size in bytes for an instance of the Half struct.</summary>
|
||||
public static readonly Int32 SizeInBytes = 2;
|
||||
|
||||
/// <summary>Smallest positive half</summary>
|
||||
public static readonly Single MinValue = 5.96046448e-08f;
|
||||
|
||||
/// <summary>Smallest positive normalized half</summary>
|
||||
public static readonly Single MinNormalizedValue = 6.10351562e-05f;
|
||||
|
||||
/// <summary>Largest positive half</summary>
|
||||
public static readonly Single MaxValue = 65504.0f;
|
||||
|
||||
/// <summary>Smallest positive e for which half (1.0 + e) != half (1.0)</summary>
|
||||
public static readonly Single Epsilon = 0.00097656f;
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region ISerializable
|
||||
|
||||
/// <summary>Constructor used by ISerializable to deserialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public Half(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
this.bits = (ushort)info.GetValue("bits", typeof(ushort));
|
||||
}
|
||||
|
||||
/// <summary>Used by ISerialize to serialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("bits", this.bits);
|
||||
}
|
||||
|
||||
#endregion ISerializable
|
||||
|
||||
#region Binary dump
|
||||
|
||||
/// <summary>Updates the Half by reading from a Stream.</summary>
|
||||
/// <param name="bin">A BinaryReader instance associated with an open Stream.</param>
|
||||
public void FromBinaryStream(BinaryReader bin)
|
||||
{
|
||||
this.bits = bin.ReadUInt16();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Writes the Half into a Stream.</summary>
|
||||
/// <param name="bin">A BinaryWriter instance associated with an open Stream.</param>
|
||||
public void ToBinaryStream(BinaryWriter bin)
|
||||
{
|
||||
bin.Write(this.bits);
|
||||
}
|
||||
|
||||
#endregion Binary dump
|
||||
|
||||
#region IEquatable<Half> Members
|
||||
|
||||
const int maxUlps = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether this instance is equal to a specified OpenTK.Half value.
|
||||
/// </summary>
|
||||
/// <param name="other">OpenTK.Half object to compare to this instance..</param>
|
||||
/// <returns>True, if other is equal to this instance; false otherwise.</returns>
|
||||
public bool Equals(Half other)
|
||||
{
|
||||
short aInt, bInt;
|
||||
unchecked { aInt = (short)other.bits; }
|
||||
unchecked { bInt = (short)this.bits; }
|
||||
|
||||
// Make aInt lexicographically ordered as a twos-complement int
|
||||
if (aInt < 0)
|
||||
aInt = (short)(0x8000 - aInt);
|
||||
|
||||
// Make bInt lexicographically ordered as a twos-complement int
|
||||
if (bInt < 0)
|
||||
bInt = (short)(0x8000 - bInt);
|
||||
|
||||
short intDiff = System.Math.Abs((short)(aInt - bInt));
|
||||
|
||||
if (intDiff <= maxUlps)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IComparable<Half> Members
|
||||
|
||||
/// <summary>
|
||||
/// Compares this instance to a specified half-precision floating-point number
|
||||
/// and returns an integer that indicates whether the value of this instance
|
||||
/// is less than, equal to, or greater than the value of the specified half-precision
|
||||
/// floating-point number.
|
||||
/// </summary>
|
||||
/// <param name="other">A half-precision floating-point number to compare.</param>
|
||||
/// <returns>
|
||||
/// A signed number indicating the relative values of this instance and value. If the number is:
|
||||
/// <para>Less than zero, then this instance is less than other, or this instance is not a number
|
||||
/// (OpenTK.Half.NaN) and other is a number.</para>
|
||||
/// <para>Zero: this instance is equal to value, or both this instance and other
|
||||
/// are not a number (OpenTK.Half.NaN), OpenTK.Half.PositiveInfinity, or
|
||||
/// OpenTK.Half.NegativeInfinity.</para>
|
||||
/// <para>Greater than zero: this instance is greater than othrs, or this instance is a number
|
||||
/// and other is not a number (OpenTK.Half.NaN).</para>
|
||||
/// </returns>
|
||||
public int CompareTo(Half other)
|
||||
{
|
||||
return ((float)this).CompareTo((float)other);
|
||||
}
|
||||
|
||||
#endregion IComparable<Half> Members
|
||||
|
||||
#region IFormattable Members
|
||||
|
||||
/// <summary>Converts this Half into a human-legible string representation.</summary>
|
||||
/// <returns>The string representation of this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return this.ToSingle().ToString();
|
||||
}
|
||||
|
||||
/// <summary>Converts this Half into a human-legible string representation.</summary>
|
||||
/// <param name="format">formatting for the output string.</param>
|
||||
/// <param name="formatProvider">Culture-specific formatting information.</param>
|
||||
/// <returns>The string representation of this instance.</returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
return this.ToSingle().ToString(format, formatProvider);
|
||||
}
|
||||
|
||||
#endregion IFormattable Members
|
||||
|
||||
#region String -> Half
|
||||
|
||||
/// <summary>Converts the string representation of a number to a Half precision floating point equivalent.</summary>
|
||||
/// <param name="s">string representation of the number to convert.</param>
|
||||
/// <returns>A new Half instance.</returns>
|
||||
public static Half Parse(string s)
|
||||
{
|
||||
return (Half)Single.Parse(s);
|
||||
}
|
||||
|
||||
/// <summary>Converts the string representation of a number to a Half precision floating point equivalent.</summary>
|
||||
/// <param name="s">string representation of the number to convert.</param>
|
||||
/// <param name="style">specifies the format of s.</param>
|
||||
/// <param name="provider">Culture-specific formatting information.</param>
|
||||
/// <returns>A new Half instance.</returns>
|
||||
public static Half Parse(string s, System.Globalization.NumberStyles style, IFormatProvider provider)
|
||||
{
|
||||
return (Half)Single.Parse(s, style, provider);
|
||||
}
|
||||
|
||||
/// <summary>Converts the string representation of a number to a Half precision floating point equivalent. Returns success.</summary>
|
||||
/// <param name="s">string representation of the number to convert.</param>
|
||||
/// <param name="result">The Half instance to write to.</param>
|
||||
/// <returns>Success.</returns>
|
||||
public static bool TryParse(string s, out Half result)
|
||||
{
|
||||
float f;
|
||||
bool b = Single.TryParse(s, out f);
|
||||
result = (Half)f;
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>Converts the string representation of a number to a Half precision floating point equivalent. Returns success.</summary>
|
||||
/// <param name="s">string representation of the number to convert.</param>
|
||||
/// <param name="style">specifies the format of s.</param>
|
||||
/// <param name="provider">Culture-specific formatting information.</param>
|
||||
/// <param name="result">The Half instance to write to.</param>
|
||||
/// <returns>Success.</returns>
|
||||
public static bool TryParse(string s, System.Globalization.NumberStyles style, IFormatProvider provider, out Half result)
|
||||
{
|
||||
float f;
|
||||
bool b = Single.TryParse(s, style, provider, out f);
|
||||
result = (Half)f;
|
||||
return b;
|
||||
}
|
||||
|
||||
#endregion String -> Half
|
||||
|
||||
#region BitConverter
|
||||
|
||||
/// <summary>Returns the Half as an array of bytes.</summary>
|
||||
/// <param name="h">The Half to convert.</param>
|
||||
/// <returns>The input as byte array.</returns>
|
||||
public static byte[] GetBytes(Half h)
|
||||
{
|
||||
return BitConverter.GetBytes(h.bits);
|
||||
}
|
||||
|
||||
/// <summary>Converts an array of bytes into Half.</summary>
|
||||
/// <param name="value">A Half in it's byte[] representation.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A new Half instance.</returns>
|
||||
public static Half FromBytes(byte[] value, int startIndex)
|
||||
{
|
||||
Half h;
|
||||
h.bits = BitConverter.ToUInt16(value, startIndex);
|
||||
return h;
|
||||
}
|
||||
|
||||
#endregion BitConverter
|
||||
}
|
||||
}
|
828
Source/Compatibility/Math/Matrix3d.cs
Normal file
828
Source/Compatibility/Math/Matrix3d.cs
Normal file
|
@ -0,0 +1,828 @@
|
|||
#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.Math
|
||||
{
|
||||
// Todo: Remove this warning when the code goes public.
|
||||
#pragma warning disable 3019
|
||||
#if false
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Matrix3d : IEquatable<Matrix3d>
|
||||
{
|
||||
#region Fields & Access
|
||||
|
||||
/// <summary>Row 0, Column 0</summary>
|
||||
public double R0C0;
|
||||
|
||||
/// <summary>Row 0, Column 1</summary>
|
||||
public double R0C1;
|
||||
|
||||
/// <summary>Row 0, Column 2</summary>
|
||||
public double R0C2;
|
||||
|
||||
/// <summary>Row 1, Column 0</summary>
|
||||
public double R1C0;
|
||||
|
||||
/// <summary>Row 1, Column 1</summary>
|
||||
public double R1C1;
|
||||
|
||||
/// <summary>Row 1, Column 2</summary>
|
||||
public double R1C2;
|
||||
|
||||
/// <summary>Row 2, Column 0</summary>
|
||||
public double R2C0;
|
||||
|
||||
/// <summary>Row 2, Column 1</summary>
|
||||
public double R2C1;
|
||||
|
||||
/// <summary>Row 2, Column 2</summary>
|
||||
public double R2C2;
|
||||
|
||||
/// <summary>Gets the component at the given row and column in the matrix.</summary>
|
||||
/// <param name="row">The row of the matrix.</param>
|
||||
/// <param name="column">The column of the matrix.</param>
|
||||
/// <returns>The component at the given row and column in the matrix.</returns>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the component at the index into the matrix.</summary>
|
||||
/// <param name="index">The index into the components of the matrix.</param>
|
||||
/// <returns>The component at the given index into the matrix.</returns>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Converts the matrix into an IntPtr.</summary>
|
||||
/// <param name="matrix">The matrix to convert.</param>
|
||||
/// <returns>An IntPtr for the matrix.</returns>
|
||||
public static explicit operator IntPtr(Matrix3d matrix)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return (IntPtr)(&matrix.R0C0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Converts the matrix into left double*.</summary>
|
||||
/// <param name="matrix">The matrix to convert.</param>
|
||||
/// <returns>A double* for the matrix.</returns>
|
||||
[CLSCompliant(false)]
|
||||
unsafe public static explicit operator double*(Matrix3d matrix)
|
||||
{
|
||||
return &matrix.R0C0;
|
||||
}
|
||||
|
||||
/// <summary>Converts the matrix into an array of doubles.</summary>
|
||||
/// <param name="matrix">The matrix to convert.</param>
|
||||
/// <returns>An array of doubles for the matrix.</returns>
|
||||
public static explicit operator double[](Matrix3d matrix)
|
||||
{
|
||||
return new double[9]
|
||||
{
|
||||
matrix.R0C0,
|
||||
matrix.R0C1,
|
||||
matrix.R0C2,
|
||||
matrix.R1C0,
|
||||
matrix.R1C1,
|
||||
matrix.R1C2,
|
||||
matrix.R2C0,
|
||||
matrix.R2C1,
|
||||
matrix.R2C2
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>Constructs left matrix with the same components as the given matrix.</summary>
|
||||
/// <param name="vector">The matrix whose components to copy.</param>
|
||||
public Matrix3d(ref Matrix3d matrix)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Constructs left matrix with the given values.</summary>
|
||||
/// <param name="r0c0">The value for row 0 column 0.</param>
|
||||
/// <param name="r0c1">The value for row 0 column 1.</param>
|
||||
/// <param name="r0c2">The value for row 0 column 2.</param>
|
||||
/// <param name="r1c0">The value for row 1 column 0.</param>
|
||||
/// <param name="r1c1">The value for row 1 column 1.</param>
|
||||
/// <param name="r1c2">The value for row 1 column 2.</param>
|
||||
/// <param name="r2c0">The value for row 2 column 0.</param>
|
||||
/// <param name="r2c1">The value for row 2 column 1.</param>
|
||||
/// <param name="r2c2">The value for row 2 column 2.</param>
|
||||
public Matrix3d
|
||||
(
|
||||
double r0c0,
|
||||
double r0c1,
|
||||
double r0c2,
|
||||
double r1c0,
|
||||
double r1c1,
|
||||
double r1c2,
|
||||
double r2c0,
|
||||
double r2c1,
|
||||
double r2c2
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Constructs left matrix from the given array of double-precision floating point numbers.</summary>
|
||||
/// <param name="doubleArray">The array of doubles for the components of the matrix.</param>
|
||||
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];
|
||||
}
|
||||
|
||||
/// <summary>Constructs left matrix from the given quaternion.</summary>
|
||||
/// <param name="quaternion">The quaternion to use to construct the martix.</param>
|
||||
public Matrix3d(Quaterniond quaternion)
|
||||
{
|
||||
quaternion.Normalize();
|
||||
|
||||
double xx = quaternion.X * quaternion.X;
|
||||
double yy = quaternion.Y * quaternion.Y;
|
||||
double zz = quaternion.Z * quaternion.Z;
|
||||
double xy = quaternion.X * quaternion.Y;
|
||||
double xz = quaternion.X * quaternion.Z;
|
||||
double yz = quaternion.Y * quaternion.Z;
|
||||
double wx = quaternion.W * quaternion.X;
|
||||
double wy = quaternion.W * quaternion.Y;
|
||||
double wz = quaternion.W * quaternion.Z;
|
||||
|
||||
R0C0 = 1 - 2 * (yy + zz);
|
||||
R0C1 = 2 * (xy - wz);
|
||||
R0C2 = 2 * (xz + wy);
|
||||
|
||||
R1C0 = 2 * (xy + wz);
|
||||
R1C1 = 1 - 2 * (xx + zz);
|
||||
R1C2 = 2 * (yz - wx);
|
||||
|
||||
R2C0 = 2 * (xz - wy);
|
||||
R2C1 = 2 * (yz + wx);
|
||||
R2C2 = 1 - 2 * (xx + yy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equality
|
||||
|
||||
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
|
||||
/// <param name="matrix">The OpenTK.Matrix3d structure to compare with.</param>
|
||||
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
|
||||
[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;
|
||||
}
|
||||
|
||||
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
|
||||
/// <param name="matrix">The OpenTK.Matrix3d structure to compare to.</param>
|
||||
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
|
||||
/// <param name="left">The left-hand operand.</param>
|
||||
/// <param name="right">The right-hand operand.</param>
|
||||
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
|
||||
/// <param name="matrix">The OpenTK.Matrix3d structure to compare with.</param>
|
||||
/// <param name="tolerance">The limit below which the matrices are considered equal.</param>
|
||||
/// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
|
||||
/// <param name="left">The left-hand operand.</param>
|
||||
/// <param name="right">The right-hand operand.</param>
|
||||
/// <param name="tolerance">The limit below which the matrices are considered equal.</param>
|
||||
/// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
|
||||
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
|
||||
|
||||
|
||||
/// <summary>Add left matrix to this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to add.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Add left matrix to this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to add.</param>
|
||||
/// <param name="result">The resulting matrix of the addition.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Add left matrix to left matrix.</summary>
|
||||
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
||||
/// <param name="right">The matrix on the right side of the equation</param>
|
||||
/// <param name="result">The resulting matrix of the addition.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Subtract left matrix from this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to subtract.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Subtract left matrix from this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to subtract.</param>
|
||||
/// <param name="result">The resulting matrix of the subtraction.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Subtract left matrix from left matrix.</summary>
|
||||
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
||||
/// <param name="right">The matrix on the right side of the equation</param>
|
||||
/// <param name="result">The resulting matrix of the subtraction.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Multiply left martix times this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to multiply.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Multiply matrix times this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to multiply.</param>
|
||||
/// <param name="result">The resulting matrix of the multiplication.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Multiply left matrix times left matrix.</summary>
|
||||
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
||||
/// <param name="right">The matrix on the right side of the equation</param>
|
||||
/// <param name="result">The resulting matrix of the multiplication.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Multiply matrix times this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to multiply.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Multiply matrix times this matrix.</summary>
|
||||
/// <param name="matrix">The matrix to multiply.</param>
|
||||
/// <param name="result">The resulting matrix of the multiplication.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Multiply left matrix times left matrix.</summary>
|
||||
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
||||
/// <param name="right">The matrix on the right side of the equation</param>
|
||||
/// <param name="result">The resulting matrix of the multiplication.</param>
|
||||
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
|
||||
|
||||
public double Determinant
|
||||
{
|
||||
get
|
||||
{
|
||||
return R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Transpose()
|
||||
{
|
||||
Functions.Swap(ref R0C1, ref R1C0);
|
||||
Functions.Swap(ref R0C2, ref R2C0);
|
||||
Functions.Swap(ref R1C2, ref R2C1);
|
||||
}
|
||||
public void Transpose(out Matrix3d result)
|
||||
{
|
||||
result.R0C0 = R0C0;
|
||||
result.R0C1 = R1C0;
|
||||
result.R0C2 = R2C0;
|
||||
result.R1C0 = R0C1;
|
||||
result.R1C1 = R1C1;
|
||||
result.R1C2 = R2C1;
|
||||
result.R2C0 = R0C2;
|
||||
result.R2C1 = R1C2;
|
||||
result.R2C2 = R2C2;
|
||||
}
|
||||
public static void Transpose(ref Matrix3d matrix, out Matrix3d result)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Transformation Functions
|
||||
|
||||
public void Transform(ref Vector3d vector)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void Rotate(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;
|
||||
}
|
||||
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 Constants
|
||||
|
||||
/// <summary>The identity matrix.</summary>
|
||||
public static readonly Matrix3d Identity = new Matrix3d
|
||||
(
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1
|
||||
);
|
||||
|
||||
/// <summary>A matrix of all zeros.</summary>
|
||||
public static readonly Matrix3d Zero = new Matrix3d
|
||||
(
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0
|
||||
);
|
||||
|
||||
#endregion
|
||||
|
||||
#region HashCode
|
||||
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return
|
||||
R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^
|
||||
R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^
|
||||
R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region String
|
||||
|
||||
/// <summary>Returns the fully qualified type name of this instance.</summary>
|
||||
/// <returns>A System.String containing left fully qualified type name.</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
#pragma warning restore 3019
|
||||
}
|
1120
Source/Compatibility/Math/Matrix4.cs
Normal file
1120
Source/Compatibility/Math/Matrix4.cs
Normal file
File diff suppressed because it is too large
Load diff
968
Source/Compatibility/Math/Matrix4d.cs
Normal file
968
Source/Compatibility/Math/Matrix4d.cs
Normal file
|
@ -0,0 +1,968 @@
|
|||
#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.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a 4x4 Matrix with double-precision components.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Matrix4d : IEquatable<Matrix4d>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Top row of the matrix
|
||||
/// </summary>
|
||||
public Vector4d Row0;
|
||||
/// <summary>
|
||||
/// 2nd row of the matrix
|
||||
/// </summary>
|
||||
public Vector4d Row1;
|
||||
/// <summary>
|
||||
/// 3rd row of the matrix
|
||||
/// </summary>
|
||||
public Vector4d Row2;
|
||||
/// <summary>
|
||||
/// Bottom row of the matrix
|
||||
/// </summary>
|
||||
public Vector4d Row3;
|
||||
|
||||
/// <summary>
|
||||
/// The identity matrix
|
||||
/// </summary>
|
||||
public static Matrix4d Identity = new Matrix4d(Vector4d .UnitX, Vector4d .UnitY, Vector4d .UnitZ, Vector4d .UnitW);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="row0">Top row of the matrix</param>
|
||||
/// <param name="row1">Second row of the matrix</param>
|
||||
/// <param name="row2">Third row of the matrix</param>
|
||||
/// <param name="row3">Bottom row of the matrix</param>
|
||||
public Matrix4d(Vector4d row0, Vector4d row1, Vector4d row2, Vector4d row3)
|
||||
{
|
||||
Row0 = row0;
|
||||
Row1 = row1;
|
||||
Row2 = row2;
|
||||
Row3 = row3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="m00">First item of the first row.</param>
|
||||
/// <param name="m01">Second item of the first row.</param>
|
||||
/// <param name="m02">Third item of the first row.</param>
|
||||
/// <param name="m03">Fourth item of the first row.</param>
|
||||
/// <param name="m10">First item of the second row.</param>
|
||||
/// <param name="m11">Second item of the second row.</param>
|
||||
/// <param name="m12">Third item of the second row.</param>
|
||||
/// <param name="m13">Fourth item of the second row.</param>
|
||||
/// <param name="m20">First item of the third row.</param>
|
||||
/// <param name="m21">Second item of the third row.</param>
|
||||
/// <param name="m22">Third item of the third row.</param>
|
||||
/// <param name="m23">First item of the third row.</param>
|
||||
/// <param name="m30">Fourth item of the fourth row.</param>
|
||||
/// <param name="m31">Second item of the fourth row.</param>
|
||||
/// <param name="m32">Third item of the fourth row.</param>
|
||||
/// <param name="m33">Fourth item of the fourth row.</param>
|
||||
public Matrix4d(
|
||||
float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
Row0 = new Vector4d(m00, m01, m02, m03);
|
||||
Row1 = new Vector4d(m10, m11, m12, m13);
|
||||
Row2 = new Vector4d(m20, m21, m22, m23);
|
||||
Row3 = new Vector4d(m30, m31, m32, m33);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// The determinant of this matrix
|
||||
/// </summary>
|
||||
public double Determinant
|
||||
{
|
||||
get
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The first column of this matrix
|
||||
/// </summary>
|
||||
public Vector4d Column0
|
||||
{
|
||||
get { return new Vector4d (Row0.X, Row1.X, Row2.X, Row3.X); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The second column of this matrix
|
||||
/// </summary>
|
||||
public Vector4d Column1
|
||||
{
|
||||
get { return new Vector4d (Row0.Y, Row1.Y, Row2.Y, Row3.Y); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The third column of this matrix
|
||||
/// </summary>
|
||||
public Vector4d Column2
|
||||
{
|
||||
get { return new Vector4d (Row0.Z, Row1.Z, Row2.Z, Row3.Z); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The fourth column of this matrix
|
||||
/// </summary>
|
||||
public Vector4d Column3
|
||||
{
|
||||
get { return new Vector4d (Row0.W, Row1.W, Row2.W, Row3.W); }
|
||||
}
|
||||
|
||||
public double this[int i, int j]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (i < 0 || i > 3)
|
||||
throw new ArgumentOutOfRangeException("i");
|
||||
|
||||
if (j < 0 || j > 3)
|
||||
throw new ArgumentOutOfRangeException("j");
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (Matrix4d* ptr = &this)
|
||||
return *((double*)ptr + i + j * 4);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (i < 0 || i > 3)
|
||||
throw new ArgumentOutOfRangeException("i");
|
||||
|
||||
if (j < 0 || j > 3)
|
||||
throw new ArgumentOutOfRangeException("j");
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (Matrix4d* ptr = &this)
|
||||
*((double*)ptr + i + j * 4) = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 1, column 1 of this instance.
|
||||
/// </summary>
|
||||
public double M11 { get { return Row0.X; } set { Row0.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 1, column 2 of this instance.
|
||||
/// </summary>
|
||||
public double M12 { get { return Row0.Y; } set { Row0.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 1, column 3 of this instance.
|
||||
/// </summary>
|
||||
public double M13 { get { return Row0.Z; } set { Row0.Z = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 1, column 4 of this instance.
|
||||
/// </summary>
|
||||
public double M14 { get { return Row0.W; } set { Row0.W = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 2, column 1 of this instance.
|
||||
/// </summary>
|
||||
public double M21 { get { return Row1.X; } set { Row1.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 2, column 2 of this instance.
|
||||
/// </summary>
|
||||
public double M22 { get { return Row1.Y; } set { Row1.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 2, column 3 of this instance.
|
||||
/// </summary>
|
||||
public double M23 { get { return Row1.Z; } set { Row1.Z = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 2, column 4 of this instance.
|
||||
/// </summary>
|
||||
public double M24 { get { return Row1.W; } set { Row1.W = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 3, column 1 of this instance.
|
||||
/// </summary>
|
||||
public double M31 { get { return Row2.X; } set { Row2.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 3, column 2 of this instance.
|
||||
/// </summary>
|
||||
public double M32 { get { return Row2.Y; } set { Row2.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 3, column 3 of this instance.
|
||||
/// </summary>
|
||||
public double M33 { get { return Row2.Z; } set { Row2.Z = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 3, column 4 of this instance.
|
||||
/// </summary>
|
||||
public double M34 { get { return Row2.W; } set { Row2.W = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 4, column 1 of this instance.
|
||||
/// </summary>
|
||||
public double M41 { get { return Row3.X; } set { Row3.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 4, column 3 of this instance.
|
||||
/// </summary>
|
||||
public double M42 { get { return Row3.Y; } set { Row3.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 4, column 3 of this instance.
|
||||
/// </summary>
|
||||
public double M43 { get { return Row3.Z; } set { Row3.Z = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value at row 4, column 4 of this instance.
|
||||
/// </summary>
|
||||
public double M44 { get { return Row3.W; } set { Row3.W = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instance
|
||||
|
||||
#region public void Invert()
|
||||
|
||||
public void Invert()
|
||||
{
|
||||
this = Matrix4d.Invert(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Transpose()
|
||||
|
||||
public void Transpose()
|
||||
{
|
||||
this = Matrix4d.Transpose(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
#region CreateTranslation
|
||||
|
||||
/// <summary>
|
||||
/// Creates a translation matrix.
|
||||
/// </summary>
|
||||
/// <param name="x">X translation.</param>
|
||||
/// <param name="y">Y translation.</param>
|
||||
/// <param name="z">Z translation.</param>
|
||||
/// <param name="result">The resulting Matrix4d instance.</param>
|
||||
public static void CreateTranslation(double x, double y, double z, out Matrix4d result)
|
||||
{
|
||||
result = Identity;
|
||||
result.Row3 = new Vector4d(x, y, z, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a translation matrix.
|
||||
/// </summary>
|
||||
/// <param name="vector">The translation vector.</param>
|
||||
/// <param name="result">The resulting Matrix4d instance.</param>
|
||||
public static void CreateTranslation(ref Vector3d vector, out Matrix4d result)
|
||||
{
|
||||
result = Identity;
|
||||
result.Row3 = new Vector4d(vector.X, vector.Y, vector.Z, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a translation matrix.
|
||||
/// </summary>
|
||||
/// <param name="x">X translation.</param>
|
||||
/// <param name="y">Y translation.</param>
|
||||
/// <param name="z">Z translation.</param>
|
||||
/// <returns>The resulting Matrix4d instance.</returns>
|
||||
public static Matrix4d CreateTranslation(double x, double y, double z)
|
||||
{
|
||||
Matrix4d result;
|
||||
CreateTranslation(x, y, z, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a translation matrix.
|
||||
/// </summary>
|
||||
/// <param name="vector">The translation vector.</param>
|
||||
/// <returns>The resulting Matrix4d instance.</returns>
|
||||
public static Matrix4d CreateTranslation(Vector3d vector)
|
||||
{
|
||||
Matrix4d result;
|
||||
CreateTranslation(vector.X, vector.Y, vector.Z, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateOrthographic
|
||||
|
||||
/// <summary>
|
||||
/// Creates an orthographic projection matrix.
|
||||
/// </summary>
|
||||
/// <param name="width">The width of the projection volume.</param>
|
||||
/// <param name="height">The height of the projection volume.</param>
|
||||
/// <param name="zNear">The near edge of the projection volume.</param>
|
||||
/// <param name="zFar">The far edge of the projection volume.</param>
|
||||
/// <param name="result">The resulting Matrix4d instance.</param>
|
||||
public static void CreateOrthographic(double width, double height, double zNear, double zFar, out Matrix4d result)
|
||||
{
|
||||
CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an orthographic projection matrix.
|
||||
/// </summary>
|
||||
/// <param name="width">The width of the projection volume.</param>
|
||||
/// <param name="height">The height of the projection volume.</param>
|
||||
/// <param name="zNear">The near edge of the projection volume.</param>
|
||||
/// <param name="zFar">The far edge of the projection volume.</param>
|
||||
/// <rereturns>The resulting Matrix4d instance.</rereturns>
|
||||
public static Matrix4d CreateOrthographic(double width, double height, double zNear, double zFar)
|
||||
{
|
||||
Matrix4d result;
|
||||
CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateOrthographicOffCenter
|
||||
|
||||
/// <summary>
|
||||
/// Creates an orthographic projection matrix.
|
||||
/// </summary>
|
||||
/// <param name="left">The left edge of the projection volume.</param>
|
||||
/// <param name="right">The right edge of the projection volume.</param>
|
||||
/// <param name="bottom">The bottom edge of the projection volume.</param>
|
||||
/// <param name="top">The top edge of the projection volume.</param>
|
||||
/// <param name="zNear">The near edge of the projection volume.</param>
|
||||
/// <param name="zFar">The far edge of the projection volume.</param>
|
||||
/// <param name="result">The resulting Matrix4d instance.</param>
|
||||
public static void CreateOrthographicOffCenter(double left, double right, double bottom, double top, double zNear, double zFar, out Matrix4d result)
|
||||
{
|
||||
result = new Matrix4d();
|
||||
|
||||
double invRL = 1 / (right - left);
|
||||
double invTB = 1 / (top - bottom);
|
||||
double invFN = 1 / (zFar - zNear);
|
||||
|
||||
result.M11 = 2 * invRL;
|
||||
result.M22 = 2 * invTB;
|
||||
result.M33 = -2 * invFN;
|
||||
|
||||
result.M41 = -(right + left) * invRL;
|
||||
result.M42 = -(top + bottom) * invTB;
|
||||
result.M43 = -(zFar + zNear) * invFN;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an orthographic projection matrix.
|
||||
/// </summary>
|
||||
/// <param name="left">The left edge of the projection volume.</param>
|
||||
/// <param name="right">The right edge of the projection volume.</param>
|
||||
/// <param name="bottom">The bottom edge of the projection volume.</param>
|
||||
/// <param name="top">The top edge of the projection volume.</param>
|
||||
/// <param name="zNear">The near edge of the projection volume.</param>
|
||||
/// <param name="zFar">The far edge of the projection volume.</param>
|
||||
/// <returns>The resulting Matrix4d instance.</returns>
|
||||
public static Matrix4d CreateOrthographicOffCenter(double left, double right, double bottom, double top, double zNear, double zFar)
|
||||
{
|
||||
Matrix4d result;
|
||||
CreateOrthographicOffCenter(left, right, bottom, top, zNear, zFar, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Obsolete Functions
|
||||
|
||||
#region Translation Functions
|
||||
|
||||
/// <summary>
|
||||
/// Build a translation matrix with the given translation
|
||||
/// </summary>
|
||||
/// <param name="trans">The vector to translate along</param>
|
||||
/// <returns>A Translation matrix</returns>
|
||||
[Obsolete("Use CreateTranslation instead.")]
|
||||
public static Matrix4d Translation(Vector3d trans)
|
||||
{
|
||||
return Translation(trans.X, trans.Y, trans.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a translation matrix with the given translation
|
||||
/// </summary>
|
||||
/// <param name="x">X translation</param>
|
||||
/// <param name="y">Y translation</param>
|
||||
/// <param name="z">Z translation</param>
|
||||
/// <returns>A Translation matrix</returns>
|
||||
[Obsolete("Use CreateTranslation instead.")]
|
||||
public static Matrix4d Translation(double x, double y, double z)
|
||||
{
|
||||
Matrix4d result = Identity;
|
||||
result.Row3 = new Vector4d(x, y, z, 1.0f);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scale Functions
|
||||
|
||||
/// <summary>
|
||||
/// Build a scaling matrix
|
||||
/// </summary>
|
||||
/// <param name="scale">Single scale factor for x,y and z axes</param>
|
||||
/// <returns>A scaling matrix</returns>
|
||||
public static Matrix4d Scale(double scale)
|
||||
{
|
||||
return Scale(scale, scale, scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a scaling matrix
|
||||
/// </summary>
|
||||
/// <param name="scale">Scale factors for x,y and z axes</param>
|
||||
/// <returns>A scaling matrix</returns>
|
||||
public static Matrix4d Scale(Vector3d scale)
|
||||
{
|
||||
return Scale(scale.X, scale.Y, scale.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a scaling matrix
|
||||
/// </summary>
|
||||
/// <param name="x">Scale factor for x-axis</param>
|
||||
/// <param name="y">Scale factor for y-axis</param>
|
||||
/// <param name="z">Scale factor for z-axis</param>
|
||||
/// <returns>A scaling matrix</returns>
|
||||
public static Matrix4d Scale(double x, double y, double z)
|
||||
{
|
||||
Matrix4d result;
|
||||
result.Row0 = Vector4d .UnitX * x;
|
||||
result.Row1 = Vector4d .UnitY * y;
|
||||
result.Row2 = Vector4d .UnitZ * z;
|
||||
result.Row3 = Vector4d .UnitW;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rotation Functions
|
||||
|
||||
/// <summary>
|
||||
/// Build a rotation matrix that rotates about the x-axis
|
||||
/// </summary>
|
||||
/// <param name="angle">angle in radians to rotate counter-clockwise around the x-axis</param>
|
||||
/// <returns>A rotation matrix</returns>
|
||||
public static Matrix4d RotateX(double angle)
|
||||
{
|
||||
double cos = (double)System.Math.Cos(angle);
|
||||
double sin = (double)System.Math.Sin(angle);
|
||||
|
||||
Matrix4d result;
|
||||
result.Row0 = Vector4d .UnitX;
|
||||
result.Row1 = new Vector4d (0.0f, cos, sin, 0.0f);
|
||||
result.Row2 = new Vector4d (0.0f, -sin, cos, 0.0f);
|
||||
result.Row3 = Vector4d .UnitW;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a rotation matrix that rotates about the y-axis
|
||||
/// </summary>
|
||||
/// <param name="angle">angle in radians to rotate counter-clockwise around the y-axis</param>
|
||||
/// <returns>A rotation matrix</returns>
|
||||
public static Matrix4d RotateY(double angle)
|
||||
{
|
||||
double cos = (double)System.Math.Cos(angle);
|
||||
double sin = (double)System.Math.Sin(angle);
|
||||
|
||||
Matrix4d result;
|
||||
result.Row0 = new Vector4d (cos, 0.0f, -sin, 0.0f);
|
||||
result.Row1 = Vector4d .UnitY;
|
||||
result.Row2 = new Vector4d (sin, 0.0f, cos, 0.0f);
|
||||
result.Row3 = Vector4d .UnitW;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a rotation matrix that rotates about the z-axis
|
||||
/// </summary>
|
||||
/// <param name="angle">angle in radians to rotate counter-clockwise around the z-axis</param>
|
||||
/// <returns>A rotation matrix</returns>
|
||||
public static Matrix4d RotateZ(double angle)
|
||||
{
|
||||
double cos = (double)System.Math.Cos(angle);
|
||||
double sin = (double)System.Math.Sin(angle);
|
||||
|
||||
Matrix4d result;
|
||||
result.Row0 = new Vector4d (cos, sin, 0.0f, 0.0f);
|
||||
result.Row1 = new Vector4d (-sin, cos, 0.0f, 0.0f);
|
||||
result.Row2 = Vector4d .UnitZ;
|
||||
result.Row3 = Vector4d .UnitW;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a rotation matrix to rotate about the given axis
|
||||
/// </summary>
|
||||
/// <param name="axis">the axis to rotate about</param>
|
||||
/// <param name="angle">angle in radians to rotate counter-clockwise (looking in the direction of the given axis)</param>
|
||||
/// <returns>A rotation matrix</returns>
|
||||
public static Matrix4d Rotate(Vector3d axis, double angle)
|
||||
{
|
||||
double cos = (double)System.Math.Cos(-angle);
|
||||
double sin = (double)System.Math.Sin(-angle);
|
||||
double t = 1.0f - cos;
|
||||
|
||||
axis.Normalize();
|
||||
|
||||
Matrix4d result;
|
||||
result.Row0 = new Vector4d (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 Vector4d (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 Vector4d (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 = Vector4d .UnitW;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a rotation matrix from a quaternion
|
||||
/// </summary>
|
||||
/// <param name="q">the quaternion</param>
|
||||
/// <returns>A rotation matrix</returns>
|
||||
public static Matrix4d Rotate(Quaterniond q)
|
||||
{
|
||||
Vector3d axis;
|
||||
double angle;
|
||||
q.ToAxisAngle(out axis, out angle);
|
||||
return Rotate(axis, angle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Camera Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// Build a world space to camera space matrix
|
||||
/// </summary>
|
||||
/// <param name="eye">Eye (camera) position in world space</param>
|
||||
/// <param name="target">Target position in world space</param>
|
||||
/// <param name="up">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
|
||||
/// <returns>A Matrix that transforms world space to camera space</returns>
|
||||
public static Matrix4d LookAt(Vector3d eye, Vector3d target, Vector3d up)
|
||||
{
|
||||
Vector3d z = Vector3d.Normalize(eye - target);
|
||||
Vector3d x = Vector3d.Normalize(Vector3d.Cross(up, z));
|
||||
Vector3d y = Vector3d.Normalize(Vector3d.Cross(z, x));
|
||||
|
||||
Matrix4d rot = new Matrix4d(new Vector4d (x.X, y.X, z.X, 0.0f),
|
||||
new Vector4d (x.Y, y.Y, z.Y, 0.0f),
|
||||
new Vector4d (x.Z, y.Z, z.Z, 0.0f),
|
||||
Vector4d .UnitW);
|
||||
|
||||
Matrix4d trans = Matrix4d.CreateTranslation(-eye);
|
||||
|
||||
return trans * rot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a world space to camera space matrix
|
||||
/// </summary>
|
||||
/// <param name="eyeX">Eye (camera) position in world space</param>
|
||||
/// <param name="eyeY">Eye (camera) position in world space</param>
|
||||
/// <param name="eyeZ">Eye (camera) position in world space</param>
|
||||
/// <param name="targetX">Target position in world space</param>
|
||||
/// <param name="targetY">Target position in world space</param>
|
||||
/// <param name="targetZ">Target position in world space</param>
|
||||
/// <param name="upX">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
|
||||
/// <param name="upY">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
|
||||
/// <param name="upZ">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
|
||||
/// <returns>A Matrix4 that transforms world space to camera space</returns>
|
||||
public static Matrix4d LookAt(double eyeX, double eyeY, double eyeZ, double targetX, double targetY, double targetZ, double upX, double upY, double upZ)
|
||||
{
|
||||
return LookAt(new Vector3d(eyeX, eyeY, eyeZ), new Vector3d(targetX, targetY, targetZ), new Vector3d(upX, upY, upZ));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a projection matrix
|
||||
/// </summary>
|
||||
/// <param name="left">Left edge of the view frustum</param>
|
||||
/// <param name="right">Right edge of the view frustum</param>
|
||||
/// <param name="bottom">Bottom edge of the view frustum</param>
|
||||
/// <param name="top">Top edge of the view frustum</param>
|
||||
/// <param name="near">Distance to the near clip plane</param>
|
||||
/// <param name="far">Distance to the far clip plane</param>
|
||||
/// <returns>A projection matrix that transforms camera space to raster space</returns>
|
||||
public static Matrix4d Frustum(double left, double right, double bottom, double top, double near, double far)
|
||||
{
|
||||
double invRL = 1.0f / (right - left);
|
||||
double invTB = 1.0f / (top - bottom);
|
||||
double invFN = 1.0f / (far - near);
|
||||
return new Matrix4d(new Vector4d (2.0f * near * invRL, 0.0f, 0.0f, 0.0f),
|
||||
new Vector4d (0.0f, 2.0f * near * invTB, 0.0f, 0.0f),
|
||||
new Vector4d ((right + left) * invRL, (top + bottom) * invTB, -(far + near) * invFN, -1.0f),
|
||||
new Vector4d (0.0f, 0.0f, -2.0f * far * near * invFN, 0.0f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a projection matrix
|
||||
/// </summary>
|
||||
/// <param name="fovy">Angle of the field of view in the y direction (in radians)</param>
|
||||
/// <param name="aspect">Aspect ratio of the view (width / height)</param>
|
||||
/// <param name="near">Distance to the near clip plane</param>
|
||||
/// <param name="far">Distance to the far clip plane</param>
|
||||
/// <returns>A projection matrix that transforms camera space to raster space</returns>
|
||||
public static Matrix4d Perspective(double fovy, double aspect, double near, double far)
|
||||
{
|
||||
double yMax = near * (double)System.Math.Tan(0.5f * fovy);
|
||||
double yMin = -yMax;
|
||||
double xMin = yMin * aspect;
|
||||
double xMax = yMax * aspect;
|
||||
|
||||
return Frustum(xMin, xMax, yMin, yMax, near, far);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Multiply Functions
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand of the multiplication.</param>
|
||||
/// <param name="right">The right operand of the multiplication.</param>
|
||||
/// <returns>A new instance that is the result of the multiplication</returns>
|
||||
public static Matrix4d Mult(Matrix4d left, Matrix4d right)
|
||||
{
|
||||
Matrix4d result;
|
||||
Mult(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand of the multiplication.</param>
|
||||
/// <param name="right">The right operand of the multiplication.</param>
|
||||
/// <param name="result">A new instance that is the result of the multiplication</param>
|
||||
public static void Mult(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
|
||||
{
|
||||
result = new Matrix4d();
|
||||
result.M11 = left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31 + left.M14 * right.M41;
|
||||
result.M12 = left.M11 * right.M12 + left.M12 * right.M22 + left.M13 * right.M32 + left.M14 * right.M42;
|
||||
result.M13 = left.M11 * right.M13 + left.M12 * right.M23 + left.M13 * right.M33 + left.M14 * right.M43;
|
||||
result.M14 = left.M11 * right.M14 + left.M12 * right.M24 + left.M13 * right.M34 + left.M14 * right.M44;
|
||||
result.M21 = left.M21 * right.M11 + left.M22 * right.M21 + left.M23 * right.M31 + left.M24 * right.M41;
|
||||
result.M22 = left.M21 * right.M12 + left.M22 * right.M22 + left.M23 * right.M32 + left.M24 * right.M42;
|
||||
result.M23 = left.M21 * right.M13 + left.M22 * right.M23 + left.M23 * right.M33 + left.M24 * right.M43;
|
||||
result.M24 = left.M21 * right.M14 + left.M22 * right.M24 + left.M23 * right.M34 + left.M24 * right.M44;
|
||||
result.M31 = left.M31 * right.M11 + left.M32 * right.M21 + left.M33 * right.M31 + left.M34 * right.M41;
|
||||
result.M32 = left.M31 * right.M12 + left.M32 * right.M22 + left.M33 * right.M32 + left.M34 * right.M42;
|
||||
result.M33 = left.M31 * right.M13 + left.M32 * right.M23 + left.M33 * right.M33 + left.M34 * right.M43;
|
||||
result.M34 = left.M31 * right.M14 + left.M32 * right.M24 + left.M33 * right.M34 + left.M34 * right.M44;
|
||||
result.M41 = left.M41 * right.M11 + left.M42 * right.M21 + left.M43 * right.M31 + left.M44 * right.M41;
|
||||
result.M42 = left.M41 * right.M12 + left.M42 * right.M22 + left.M43 * right.M32 + left.M44 * right.M42;
|
||||
result.M43 = left.M41 * right.M13 + left.M42 * right.M23 + left.M43 * right.M33 + left.M44 * right.M43;
|
||||
result.M44 = left.M41 * right.M14 + left.M42 * right.M24 + left.M43 * right.M34 + left.M44 * right.M44;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Invert Functions
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the inverse of the given matrix
|
||||
/// </summary>
|
||||
/// <param name="mat">The matrix to invert</param>
|
||||
/// <returns>The inverse of the given matrix if it has one, or the input if it is singular</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the Matrix4d is singular.</exception>
|
||||
public static Matrix4d Invert(Matrix4d mat)
|
||||
{
|
||||
int[] colIdx = { 0, 0, 0, 0 };
|
||||
int[] rowIdx = { 0, 0, 0, 0 };
|
||||
int[] pivotIdx = { -1, -1, -1, -1 };
|
||||
|
||||
// convert the matrix to an array for easy looping
|
||||
double[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z, mat.Row0.W},
|
||||
{mat.Row1.X, mat.Row1.Y, mat.Row1.Z, mat.Row1.W},
|
||||
{mat.Row2.X, mat.Row2.Y, mat.Row2.Z, mat.Row2.W},
|
||||
{mat.Row3.X, mat.Row3.Y, mat.Row3.Z, mat.Row3.W} };
|
||||
int icol = 0;
|
||||
int irow = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// Find the largest pivot value
|
||||
double maxPivot = 0.0f;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (pivotIdx[j] != 0)
|
||||
{
|
||||
for (int k = 0; k < 4; ++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)
|
||||
{
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++(pivotIdx[icol]);
|
||||
|
||||
// Swap rows over so pivot is on diagonal
|
||||
if (irow != icol)
|
||||
{
|
||||
for (int k = 0; k < 4; ++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];
|
||||
// check for singular matrix
|
||||
if (pivot == 0.0f)
|
||||
{
|
||||
throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
|
||||
//return mat;
|
||||
}
|
||||
|
||||
// Scale row so it has a unit diagonal
|
||||
double oneOverPivot = 1.0f / pivot;
|
||||
inverse[icol, icol] = 1.0f;
|
||||
for (int k = 0; k < 4; ++k)
|
||||
inverse[icol, k] *= oneOverPivot;
|
||||
|
||||
// Do elimination of non-diagonal elements
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
// check this isn't on the diagonal
|
||||
if (icol != j)
|
||||
{
|
||||
double f = inverse[j, icol];
|
||||
inverse[j, icol] = 0.0f;
|
||||
for (int k = 0; k < 4; ++k)
|
||||
inverse[j, k] -= inverse[icol, k] * f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 3; j >= 0; --j)
|
||||
{
|
||||
int ir = rowIdx[j];
|
||||
int ic = colIdx[j];
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
double f = inverse[k, ir];
|
||||
inverse[k, ir] = inverse[k, ic];
|
||||
inverse[k, ic] = f;
|
||||
}
|
||||
}
|
||||
|
||||
mat.Row0 = new Vector4d (inverse[0, 0], inverse[0, 1], inverse[0, 2], inverse[0, 3]);
|
||||
mat.Row1 = new Vector4d (inverse[1, 0], inverse[1, 1], inverse[1, 2], inverse[1, 3]);
|
||||
mat.Row2 = new Vector4d (inverse[2, 0], inverse[2, 1], inverse[2, 2], inverse[2, 3]);
|
||||
mat.Row3 = new Vector4d (inverse[3, 0], inverse[3, 1], inverse[3, 2], inverse[3, 3]);
|
||||
return mat;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Transpose
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the transpose of the given matrix
|
||||
/// </summary>
|
||||
/// <param name="mat">The matrix to transpose</param>
|
||||
/// <returns>The transpose of the given matrix</returns>
|
||||
public static Matrix4d Transpose(Matrix4d mat)
|
||||
{
|
||||
return new Matrix4d(mat.Column0, mat.Column1, mat.Column2, mat.Column3);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the transpose of the given matrix
|
||||
/// </summary>
|
||||
/// <param name="mat">The matrix to transpose</param>
|
||||
/// <param name="result">The result of the calculation</param>
|
||||
public static void Transpose(ref Matrix4d mat, out Matrix4d result)
|
||||
{
|
||||
result.Row0 = mat.Column0;
|
||||
result.Row1 = mat.Column1;
|
||||
result.Row2 = mat.Column2;
|
||||
result.Row3 = mat.Column3;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operators
|
||||
|
||||
/// <summary>
|
||||
/// Matrix multiplication
|
||||
/// </summary>
|
||||
/// <param name="left">left-hand operand</param>
|
||||
/// <param name="right">right-hand operand</param>
|
||||
/// <returns>A new Matrix44 which holds the result of the multiplication</returns>
|
||||
public static Matrix4d operator *(Matrix4d left, Matrix4d right)
|
||||
{
|
||||
return Matrix4d.Mult(left, right);
|
||||
}
|
||||
|
||||
public static bool operator ==(Matrix4d left, Matrix4d right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Matrix4d left, Matrix4d right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current Matrix44.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override int GetHashCode()
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hashcode for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override bool Equals(object obj)
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare to.</param>
|
||||
/// <returns>True if the instances are equal; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Matrix4d))
|
||||
return false;
|
||||
|
||||
return this.Equals((Matrix4d)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<Matrix4d> Members
|
||||
|
||||
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
|
||||
/// <param name="other">An matrix to compare with this matrix.</param>
|
||||
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
|
||||
public bool Equals(Matrix4d other)
|
||||
{
|
||||
return
|
||||
Row0 == other.Row0 &&
|
||||
Row1 == other.Row1 &&
|
||||
Row2 == other.Row2 &&
|
||||
Row3 == other.Row3;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
586
Source/Compatibility/Math/Quaternion.cs
Normal file
586
Source/Compatibility/Math/Quaternion.cs
Normal file
|
@ -0,0 +1,586 @@
|
|||
#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;
|
||||
using System.ComponentModel;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Quaternion.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Quaternion : IEquatable<Quaternion>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
Vector3 xyz;
|
||||
float w;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new Quaternion from vector and w components
|
||||
/// </summary>
|
||||
/// <param name="v">The vector part</param>
|
||||
/// <param name="w">The w part</param>
|
||||
public Quaternion(Vector3 v, float w)
|
||||
{
|
||||
this.xyz = v;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new Quaternion
|
||||
/// </summary>
|
||||
/// <param name="x">The x component</param>
|
||||
/// <param name="y">The y component</param>
|
||||
/// <param name="z">The z component</param>
|
||||
/// <param name="w">The w component</param>
|
||||
public Quaternion(float x, float y, float z, float w)
|
||||
: this(new Vector3(x, y, z), w)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
|
||||
/// </summary>
|
||||
[Obsolete("Use Xyz property instead.")]
|
||||
[CLSCompliant(false)]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[XmlIgnore]
|
||||
public Vector3 XYZ { get { return Xyz; } set { Xyz = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
|
||||
/// </summary>
|
||||
public Vector3 Xyz { get { return xyz; } set { xyz = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X component of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public float X { get { return xyz.X; } set { xyz.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y component of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public float Y { get { return xyz.Y; } set { xyz.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Z component of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public float Z { get { return xyz.Z; } set { xyz.Z = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the W component of this instance.
|
||||
/// </summary>
|
||||
public float W { get { return w; } set { w = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instance
|
||||
|
||||
#region ToAxisAngle
|
||||
|
||||
/// <summary>
|
||||
/// Convert the current quaternion to axis angle representation
|
||||
/// </summary>
|
||||
/// <param name="axis">The resultant axis</param>
|
||||
/// <param name="angle">The resultant angle</param>
|
||||
public void ToAxisAngle(out Vector3 axis, out float angle)
|
||||
{
|
||||
Vector4 result = ToAxisAngle();
|
||||
axis = result.Xyz;
|
||||
angle = result.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this instance to an axis-angle representation.
|
||||
/// </summary>
|
||||
/// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
|
||||
public Vector4 ToAxisAngle()
|
||||
{
|
||||
Quaternion q = this;
|
||||
if (q.W > 1.0f)
|
||||
q.Normalize();
|
||||
|
||||
Vector4 result = new Vector4();
|
||||
|
||||
result.W = 2.0f * (float)System.Math.Acos(q.W); // angle
|
||||
float den = (float)System.Math.Sqrt(1.0 - q.W * q.W);
|
||||
if (den > 0.0001f)
|
||||
{
|
||||
result.Xyz = q.Xyz / den;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This occurs when the angle is zero.
|
||||
// Not a problem: just set an arbitrary normalized axis.
|
||||
result.Xyz = Vector3.UnitX;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float Length
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length (magnitude) of the quaternion.
|
||||
/// </summary>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Sqrt(W * W + Xyz.LengthSquared);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float LengthSquared
|
||||
|
||||
/// <summary>
|
||||
/// Gets the square of the quaternion length (magnitude).
|
||||
/// </summary>
|
||||
public float LengthSquared
|
||||
{
|
||||
get
|
||||
{
|
||||
return W * W + Xyz.LengthSquared;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Normalize()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Quaternion to unit length.
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
float scale = 1.0f / this.Length;
|
||||
Xyz *= scale;
|
||||
W *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Conjugate()
|
||||
|
||||
/// <summary>
|
||||
/// Convert this quaternion to its conjugate
|
||||
/// </summary>
|
||||
public void Conjugate()
|
||||
{
|
||||
Xyz = -Xyz;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Defines the identity quaternion.
|
||||
/// </summary>
|
||||
public static Quaternion Identity = new Quaternion(0, 0, 0, 1);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Add
|
||||
|
||||
/// <summary>
|
||||
/// Add two quaternions
|
||||
/// </summary>
|
||||
/// <param name="left">The first operand</param>
|
||||
/// <param name="right">The second operand</param>
|
||||
/// <returns>The result of the addition</returns>
|
||||
public static Quaternion Add(Quaternion left, Quaternion right)
|
||||
{
|
||||
return new Quaternion(
|
||||
left.Xyz + right.Xyz,
|
||||
left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add two quaternions
|
||||
/// </summary>
|
||||
/// <param name="left">The first operand</param>
|
||||
/// <param name="right">The second operand</param>
|
||||
/// <param name="result">The result of the addition</param>
|
||||
public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result)
|
||||
{
|
||||
result = new Quaternion(
|
||||
left.Xyz + right.Xyz,
|
||||
left.W + right.W);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sub
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Quaternion Sub(Quaternion left, Quaternion right)
|
||||
{
|
||||
return new Quaternion(
|
||||
left.Xyz - right.Xyz,
|
||||
left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static void Sub(ref Quaternion left, ref Quaternion right, out Quaternion result)
|
||||
{
|
||||
result = new Quaternion(
|
||||
left.Xyz - right.Xyz,
|
||||
left.W - right.W);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mult
|
||||
|
||||
public static Quaternion Mult(Quaternion left, Quaternion right)
|
||||
{
|
||||
return new Quaternion(
|
||||
right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz),
|
||||
left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz));
|
||||
}
|
||||
|
||||
public static void Mult(ref Quaternion left, ref Quaternion right, out Quaternion result)
|
||||
{
|
||||
result = new Quaternion(
|
||||
right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz),
|
||||
left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Conjugate
|
||||
|
||||
/// <summary>
|
||||
/// Get the conjugate of the given quaternion
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion</param>
|
||||
/// <returns>The conjugate of the given quaternion</returns>
|
||||
public static Quaternion Conjugate(Quaternion q)
|
||||
{
|
||||
return new Quaternion(-q.Xyz, q.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the conjugate of the given quaternion
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion</param>
|
||||
/// <param name="result">The conjugate of the given quaternion</param>
|
||||
public static void Conjugate(ref Quaternion q, out Quaternion result)
|
||||
{
|
||||
result = new Quaternion(-q.Xyz, q.W);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Invert
|
||||
|
||||
/// <summary>
|
||||
/// Get the inverse of the given quaternion
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion to invert</param>
|
||||
/// <returns>The inverse of the given quaternion</returns>
|
||||
public static Quaternion Invert(Quaternion q)
|
||||
{
|
||||
Quaternion result;
|
||||
Invert(ref q, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the inverse of the given quaternion
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion to invert</param>
|
||||
/// <param name="result">The inverse of the given quaternion</param>
|
||||
public static void Invert(ref Quaternion q, out Quaternion result)
|
||||
{
|
||||
float lengthSq = q.LengthSquared;
|
||||
if (lengthSq != 0.0)
|
||||
{
|
||||
float i = 1.0f / lengthSq;
|
||||
result = new Quaternion(q.Xyz * -i, q.W * i);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = q;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Normalize
|
||||
|
||||
/// <summary>
|
||||
/// Scale the given quaternion to unit length
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion to normalize</param>
|
||||
/// <returns>The normalized quaternion</returns>
|
||||
public static Quaternion Normalize(Quaternion q)
|
||||
{
|
||||
Quaternion result;
|
||||
Normalize(ref q, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the given quaternion to unit length
|
||||
/// </summary>
|
||||
/// <param name="q">The quaternion to normalize</param>
|
||||
/// <param name="result">The normalized quaternion</param>
|
||||
public static void Normalize(ref Quaternion q, out Quaternion result)
|
||||
{
|
||||
float scale = 1.0f / q.Length;
|
||||
result = new Quaternion(q.Xyz * scale, q.W * scale);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FromAxisAngle
|
||||
|
||||
/// <summary>
|
||||
/// Build a quaternion from the given axis and angle
|
||||
/// </summary>
|
||||
/// <param name="axis">The axis to rotate about</param>
|
||||
/// <param name="angle">The rotation angle in radians</param>
|
||||
/// <returns></returns>
|
||||
public static Quaternion FromAxisAngle(Vector3 axis, float angle)
|
||||
{
|
||||
if (axis.LengthSquared == 0.0f)
|
||||
return Identity;
|
||||
|
||||
Quaternion result = Identity;
|
||||
|
||||
angle *= 0.5f;
|
||||
axis.Normalize();
|
||||
result.Xyz = axis * (float)System.Math.Sin(angle);
|
||||
result.W = (float)System.Math.Cos(angle);
|
||||
|
||||
return Normalize(result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Slerp
|
||||
|
||||
/// <summary>
|
||||
/// Do Spherical linear interpolation between two quaternions
|
||||
/// </summary>
|
||||
/// <param name="q1">The first quaternion</param>
|
||||
/// <param name="q2">The second quaternion</param>
|
||||
/// <param name="blend">The blend factor</param>
|
||||
/// <returns>A smooth blend between the given quaternions</returns>
|
||||
public static Quaternion Slerp(Quaternion q1, Quaternion q2, float blend)
|
||||
{
|
||||
// if either input is zero, return the other.
|
||||
if (q1.LengthSquared == 0.0f)
|
||||
{
|
||||
if (q2.LengthSquared == 0.0f)
|
||||
{
|
||||
return Identity;
|
||||
}
|
||||
return q2;
|
||||
}
|
||||
else if (q2.LengthSquared == 0.0f)
|
||||
{
|
||||
return q1;
|
||||
}
|
||||
|
||||
|
||||
float cosHalfAngle = q1.W * q2.W + Vector3.Dot(q1.Xyz, q2.Xyz);
|
||||
|
||||
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f)
|
||||
{
|
||||
// angle = 0.0f, so just return one input.
|
||||
return q1;
|
||||
}
|
||||
else if (cosHalfAngle < 0.0f)
|
||||
{
|
||||
q2.Xyz = -q2.Xyz;
|
||||
q2.W = -q2.W;
|
||||
cosHalfAngle = -cosHalfAngle;
|
||||
}
|
||||
|
||||
float blendA;
|
||||
float blendB;
|
||||
if (cosHalfAngle < 0.99f)
|
||||
{
|
||||
// do proper slerp for big angles
|
||||
float halfAngle = (float)System.Math.Acos(cosHalfAngle);
|
||||
float sinHalfAngle = (float)System.Math.Sin(halfAngle);
|
||||
float oneOverSinHalfAngle = 1.0f / sinHalfAngle;
|
||||
blendA = (float)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle;
|
||||
blendB = (float)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
// do lerp if angle is really small.
|
||||
blendA = 1.0f - blend;
|
||||
blendB = blend;
|
||||
}
|
||||
|
||||
Quaternion result = new Quaternion(blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.W + blendB * q2.W);
|
||||
if (result.LengthSquared > 0.0f)
|
||||
return Normalize(result);
|
||||
else
|
||||
return Identity;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operators
|
||||
|
||||
public static Quaternion operator +(Quaternion left, Quaternion right)
|
||||
{
|
||||
left.Xyz += right.Xyz;
|
||||
left.W += right.W;
|
||||
return left;
|
||||
}
|
||||
|
||||
public static Quaternion operator -(Quaternion left, Quaternion right)
|
||||
{
|
||||
left.Xyz -= right.Xyz;
|
||||
left.W -= right.W;
|
||||
return left;
|
||||
}
|
||||
|
||||
public static Quaternion operator *(Quaternion left, Quaternion right)
|
||||
{
|
||||
float w = left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz);
|
||||
left.Xyz = right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz);
|
||||
left.W = w;
|
||||
return left;
|
||||
}
|
||||
|
||||
public static bool operator ==(Quaternion left, Quaternion right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Quaternion left, Quaternion right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current Quaternion.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("V: {0}, W: {1}", Xyz, W);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override bool Equals (object o)
|
||||
|
||||
/// <summary>
|
||||
/// Compares this object instance to another object for equality.
|
||||
/// </summary>
|
||||
/// <param name="other">The other object to be used in the comparison.</param>
|
||||
/// <returns>True if both objects are Quaternions of equal value. Otherwise it returns false.</returns>
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (other is Quaternion == false) return false;
|
||||
return this == (Quaternion)other;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override int GetHashCode ()
|
||||
|
||||
/// <summary>
|
||||
/// Provides the hash code for this object.
|
||||
/// </summary>
|
||||
/// <returns>A hash code formed from the bitwise XOR of this objects members.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Xyz.GetHashCode() ^ W.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<Quaternion> Members
|
||||
|
||||
/// <summary>
|
||||
/// Compares this Quaternion instance to another Quaternion for equality.
|
||||
/// </summary>
|
||||
/// <param name="other">The other Quaternion to be used in the comparison.</param>
|
||||
/// <returns>True if both instances are equal; false otherwise.</returns>
|
||||
public bool Equals(Quaternion other)
|
||||
{
|
||||
return Xyz == other.Xyz && W == other.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
1211
Source/Compatibility/Math/Quaterniond.cs
Normal file
1211
Source/Compatibility/Math/Quaterniond.cs
Normal file
File diff suppressed because it is too large
Load diff
914
Source/Compatibility/Math/Vector2.cs
Normal file
914
Source/Compatibility/Math/Vector2.cs
Normal file
|
@ -0,0 +1,914 @@
|
|||
#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.Math
|
||||
{
|
||||
/// <summary>Represents a 2D vector using two single-precision floating-point numbers.</summary>
|
||||
/// <remarks>
|
||||
/// The Vector2 structure is suitable for interoperation with unmanaged code requiring two consecutive floats.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector2 : IEquatable<Vector2>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the Vector2.
|
||||
/// </summary>
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the Vector2.
|
||||
/// </summary>
|
||||
public float Y;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector2.
|
||||
/// </summary>
|
||||
/// <param name="x">The x coordinate of the net Vector2.</param>
|
||||
/// <param name="y">The y coordinate of the net Vector2.</param>
|
||||
public Vector2(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector2 from the given Vector2.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector2 to copy components from.</param>
|
||||
[Obsolete]
|
||||
public Vector2(Vector2 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector2 from the given Vector3.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector3 to copy components from. Z is discarded.</param>
|
||||
[Obsolete]
|
||||
public Vector2(Vector3 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector2 from the given Vector4.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector4 to copy components from. Z and W are discarded.</param>
|
||||
[Obsolete]
|
||||
public Vector2(Vector4 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
#region Instance
|
||||
|
||||
#region public void Add()
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Add( Vector2 right )
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
}
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Add( ref Vector2 right )
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
}
|
||||
|
||||
#endregion public void Add()
|
||||
|
||||
#region public void Sub()
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Sub( Vector2 right )
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
}
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Sub( ref Vector2 right )
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
}
|
||||
|
||||
#endregion public void Sub()
|
||||
|
||||
#region public void Mult()
|
||||
|
||||
/// <summary>Multiply this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Mult( float f )
|
||||
{
|
||||
this.X *= f;
|
||||
this.Y *= f;
|
||||
}
|
||||
|
||||
#endregion public void Mult()
|
||||
|
||||
#region public void Div()
|
||||
|
||||
/// <summary>Divide this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Div( float f )
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
this.X *= mult;
|
||||
this.Y *= mult;
|
||||
}
|
||||
|
||||
#endregion public void Div()
|
||||
|
||||
#region public float Length
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length (magnitude) of the vector.
|
||||
/// </summary>
|
||||
/// <see cref="LengthFast"/>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Sqrt(X * X + Y * Y);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float LengthFast
|
||||
|
||||
/// <summary>
|
||||
/// Gets an approximation of the vector length (magnitude).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property uses an approximation of the square root function to calculate vector magnitude, with
|
||||
/// an upper error bound of 0.001.
|
||||
/// </remarks>
|
||||
/// <see cref="Length"/>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public float LengthFast
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float LengthSquared
|
||||
|
||||
/// <summary>
|
||||
/// Gets the square of the vector length (magnitude).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property avoids the costly square root operation required by the Length property. This makes it more suitable
|
||||
/// for comparisons.
|
||||
/// </remarks>
|
||||
/// <see cref="Length"/>
|
||||
/// <seealso cref="LengthFast"/>
|
||||
public float LengthSquared
|
||||
{
|
||||
get
|
||||
{
|
||||
return X * X + Y * Y;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public Vector2 PerpendicularRight
|
||||
|
||||
/// <summary>
|
||||
/// Gets the perpendicular vector on the right side of this vector.
|
||||
/// </summary>
|
||||
public Vector2 PerpendicularRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2(Y, -X);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public Vector2 PerpendicularLeft
|
||||
|
||||
/// <summary>
|
||||
/// Gets the perpendicular vector on the left side of this vector.
|
||||
/// </summary>
|
||||
public Vector2 PerpendicularLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2(-Y, X);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Normalize()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Vector2 to unit length.
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
float scale = 1.0f / this.Length;
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void NormalizeFast()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Vector2 to approximately unit length.
|
||||
/// </summary>
|
||||
public void NormalizeFast()
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(X * X + Y * Y);
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Scale()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the current Vector2 by the given amounts.
|
||||
/// </summary>
|
||||
/// <param name="sx">The scale of the X component.</param>
|
||||
/// <param name="sy">The scale of the Y component.</param>
|
||||
public void Scale(float sx, float sy)
|
||||
{
|
||||
this.X = X * sx;
|
||||
this.Y = Y * sy;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
public void Scale( Vector2 scale )
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Scale( ref Vector2 scale )
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
}
|
||||
|
||||
#endregion public void Scale()
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector2 that points towards the X-axis.
|
||||
/// </summary>
|
||||
public static readonly Vector2 UnitX = new Vector2(1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector2 that points towards the Y-axis.
|
||||
/// </summary>
|
||||
public static readonly Vector2 UnitY = new Vector2(0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a zero-length Vector2.
|
||||
/// </summary>
|
||||
public static readonly Vector2 Zero = new Vector2(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines an instance with all components set to 1.
|
||||
/// </summary>
|
||||
public static readonly Vector2 One = new Vector2(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines the size of the Vector2 struct in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Add
|
||||
|
||||
/// <summary>
|
||||
/// Add the specified instances
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of addition</returns>
|
||||
public static Vector2 Add(Vector2 a, Vector2 b)
|
||||
{
|
||||
a.X += b.X;
|
||||
a.Y += b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add two Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of addition</param>
|
||||
public static void Add(ref Vector2 a, ref Vector2 b, out Vector2 result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sub
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of subtraction</returns>
|
||||
public static Vector2 Sub(Vector2 a, Vector2 b)
|
||||
{
|
||||
a.X -= b.X;
|
||||
a.Y -= b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of subtraction</param>
|
||||
public static void Sub(ref Vector2 a, ref Vector2 b, out Vector2 result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mult
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <returns>Result of the multiplication</returns>
|
||||
public static Vector2 Mult(Vector2 a, float f)
|
||||
{
|
||||
a.X *= f;
|
||||
a.Y *= f;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <param name="result">Result of the multiplication</param>
|
||||
public static void Mult(ref Vector2 a, float f, out Vector2 result)
|
||||
{
|
||||
result.X = a.X * f;
|
||||
result.Y = a.Y * f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Div
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <returns>Result of the division</returns>
|
||||
public static Vector2 Div(Vector2 a, float f)
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
a.X *= mult;
|
||||
a.Y *= mult;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <param name="result">Result of the division</param>
|
||||
public static void Div(ref Vector2 a, float f, out Vector2 result)
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
result.X = a.X * mult;
|
||||
result.Y = a.Y * mult;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ComponentMin
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise minimum</returns>
|
||||
public static Vector2 ComponentMin(Vector2 a, Vector2 b)
|
||||
{
|
||||
a.X = a.X < b.X ? a.X : b.X;
|
||||
a.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise minimum</param>
|
||||
public static void ComponentMin(ref Vector2 a, ref Vector2 b, out Vector2 result)
|
||||
{
|
||||
result.X = a.X < b.X ? a.X : b.X;
|
||||
result.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ComponentMax
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise maximum</returns>
|
||||
public static Vector2 ComponentMax(Vector2 a, Vector2 b)
|
||||
{
|
||||
a.X = a.X > b.X ? a.X : b.X;
|
||||
a.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise maximum</param>
|
||||
public static void ComponentMax(ref Vector2 a, ref Vector2 b, out Vector2 result)
|
||||
{
|
||||
result.X = a.X > b.X ? a.X : b.X;
|
||||
result.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Min
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Vector3 with the minimum magnitude
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand</param>
|
||||
/// <param name="right">Right operand</param>
|
||||
/// <returns>The minimum Vector3</returns>
|
||||
public static Vector2 Min(Vector2 left, Vector2 right)
|
||||
{
|
||||
return left.LengthSquared < right.LengthSquared ? left : right;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Max
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Vector3 with the minimum magnitude
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand</param>
|
||||
/// <param name="right">Right operand</param>
|
||||
/// <returns>The minimum Vector3</returns>
|
||||
public static Vector2 Max(Vector2 left, Vector2 right)
|
||||
{
|
||||
return left.LengthSquared >= right.LengthSquared ? left : right;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clamp
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <returns>The clamped vector</returns>
|
||||
public static Vector2 Clamp(Vector2 vec, Vector2 min, Vector2 max)
|
||||
{
|
||||
vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <param name="result">The clamped vector</param>
|
||||
public static void Clamp(ref Vector2 vec, ref Vector2 min, ref Vector2 max, out Vector2 result)
|
||||
{
|
||||
result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Normalize
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector2 Normalize(Vector2 vec)
|
||||
{
|
||||
float scale = 1.0f / vec.Length;
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void Normalize(ref Vector2 vec, out Vector2 result)
|
||||
{
|
||||
float scale = 1.0f / vec.Length;
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NormalizeFast
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector2 NormalizeFast(Vector2 vec)
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void NormalizeFast(ref Vector2 vec, out Vector2 result)
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dot
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot (scalar) product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <returns>The dot product of the two inputs</returns>
|
||||
public static float Dot(Vector2 left, Vector2 right)
|
||||
{
|
||||
return left.X * right.X + left.Y * right.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot (scalar) product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <param name="result">The dot product of the two inputs</param>
|
||||
public static void Dot( ref Vector2 left, ref Vector2 right, out float result )
|
||||
{
|
||||
result = left.X * right.X + left.Y * right.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lerp
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
|
||||
public static Vector2 Lerp(Vector2 a, Vector2 b, float blend)
|
||||
{
|
||||
a.X = blend * (b.X - a.X) + a.X;
|
||||
a.Y = blend * (b.Y - a.Y) + a.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
|
||||
public static void Lerp( ref Vector2 a, ref Vector2 b, float blend, out Vector2 result )
|
||||
{
|
||||
result.X = blend * ( b.X - a.X ) + a.X;
|
||||
result.Y = blend * ( b.Y - a.Y ) + a.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Barycentric
|
||||
|
||||
/// <summary>
|
||||
/// Interpolate 3 Vectors using Barycentric coordinates
|
||||
/// </summary>
|
||||
/// <param name="a">First input Vector</param>
|
||||
/// <param name="b">Second input Vector</param>
|
||||
/// <param name="c">Third input Vector</param>
|
||||
/// <param name="u">First Barycentric Coordinate</param>
|
||||
/// <param name="v">Second Barycentric Coordinate</param>
|
||||
/// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
|
||||
public static Vector2 BaryCentric(Vector2 a, Vector2 b, Vector2 c, float u, float v)
|
||||
{
|
||||
return a + u * (b - a) + v * (c - a);
|
||||
}
|
||||
|
||||
/// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
|
||||
/// <param name="a">First input Vector.</param>
|
||||
/// <param name="b">Second input Vector.</param>
|
||||
/// <param name="c">Third input Vector.</param>
|
||||
/// <param name="u">First Barycentric Coordinate.</param>
|
||||
/// <param name="v">Second Barycentric Coordinate.</param>
|
||||
/// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
|
||||
public static void BaryCentric( ref Vector2 a, ref Vector2 b, ref Vector2 c, float u, float v, out Vector2 result )
|
||||
{
|
||||
result = a; // copy
|
||||
|
||||
Vector2 temp = b; // copy
|
||||
temp.Sub( ref a );
|
||||
temp.Mult( u );
|
||||
result.Add( ref temp );
|
||||
|
||||
temp = c; // copy
|
||||
temp.Sub( ref a );
|
||||
temp.Mult( v );
|
||||
result.Add( ref temp );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operators
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified instances.
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand.</param>
|
||||
/// <param name="right">Right operand.</param>
|
||||
/// <returns>Result of addition.</returns>
|
||||
public static Vector2 operator +(Vector2 left, Vector2 right)
|
||||
{
|
||||
left.X += right.X;
|
||||
left.Y += right.Y;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts the specified instances.
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand.</param>
|
||||
/// <param name="right">Right operand.</param>
|
||||
/// <returns>Result of subtraction.</returns>
|
||||
public static Vector2 operator -(Vector2 left, Vector2 right)
|
||||
{
|
||||
left.X -= right.X;
|
||||
left.Y -= right.Y;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates the specified instance.
|
||||
/// </summary>
|
||||
/// <param name="vec">Operand.</param>
|
||||
/// <returns>Result of negation.</returns>
|
||||
public static Vector2 operator -(Vector2 vec)
|
||||
{
|
||||
vec.X = -vec.X;
|
||||
vec.Y = -vec.Y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies the specified instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="vec">Left operand.</param>
|
||||
/// <param name="scale">Right operand.</param>
|
||||
/// <returns>Result of multiplication.</returns>
|
||||
public static Vector2 operator *(Vector2 vec, float scale)
|
||||
{
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies the specified instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="scale">Left operand.</param>
|
||||
/// <param name="vec">Right operand.</param>
|
||||
/// <returns>Result of multiplication.</returns>
|
||||
public static Vector2 operator *(float scale, Vector2 vec)
|
||||
{
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides the specified instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="vec">Left operand</param>
|
||||
/// <param name="scale">Right operand</param>
|
||||
/// <returns>Result of the division.</returns>
|
||||
public static Vector2 operator /(Vector2 vec, float scale)
|
||||
{
|
||||
float mult = 1.0f / scale;
|
||||
vec.X *= mult;
|
||||
vec.Y *= mult;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified instances for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand.</param>
|
||||
/// <param name="right">Right operand.</param>
|
||||
/// <returns>True if both instances are equal; false otherwise.</returns>
|
||||
public static bool operator ==(Vector2 left, Vector2 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">Left operand.</param>
|
||||
/// <param name="right">Right operand.</param>
|
||||
/// <returns>True if both instances are not equal; false otherwise.</returns>
|
||||
public static bool operator !=(Vector2 left, Vector2 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current Vector2.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1})", X, Y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override int GetHashCode()
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hashcode for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override bool Equals(object obj)
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare to.</param>
|
||||
/// <returns>True if the instances are equal; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Vector2))
|
||||
return false;
|
||||
|
||||
return this.Equals((Vector2)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<Vector2> Members
|
||||
|
||||
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
|
||||
/// <param name="other">A vector to compare with this vector.</param>
|
||||
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
|
||||
public bool Equals(Vector2 other)
|
||||
{
|
||||
return
|
||||
X == other.X &&
|
||||
Y == other.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
817
Source/Compatibility/Math/Vector2d.cs
Normal file
817
Source/Compatibility/Math/Vector2d.cs
Normal file
|
@ -0,0 +1,817 @@
|
|||
#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.Math
|
||||
{
|
||||
/// <summary>Represents a 2D vector using two double-precision floating-point numbers.</summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector2d : IEquatable<Vector2d>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>The X coordinate of this instance.</summary>
|
||||
public double X;
|
||||
|
||||
/// <summary>The Y coordinate of this instance.</summary>
|
||||
public double Y;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector2d that points towards the X-axis.
|
||||
/// </summary>
|
||||
public static Vector2d UnitX = new Vector2d(1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector2d that points towards the Y-axis.
|
||||
/// </summary>
|
||||
public static Vector2d UnitY = new Vector2d(0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a zero-length Vector2d.
|
||||
/// </summary>
|
||||
public static Vector2d Zero = new Vector2d(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines an instance with all components set to 1.
|
||||
/// </summary>
|
||||
public static readonly Vector2d One = new Vector2d(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines the size of the Vector2d struct in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2d());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>Constructs left vector with the given coordinates.</summary>
|
||||
/// <param name="x">The X coordinate.</param>
|
||||
/// <param name="y">The Y coordinate.</param>
|
||||
public Vector2d(double x, double y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
#region Instance
|
||||
|
||||
#region public void Add()
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Add(Vector2d right)
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
}
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Add(ref Vector2d right)
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
}
|
||||
|
||||
#endregion public void Add()
|
||||
|
||||
#region public void Sub()
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Sub(Vector2d right)
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
}
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Sub(ref Vector2d right)
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
}
|
||||
|
||||
#endregion public void Sub()
|
||||
|
||||
#region public void Mult()
|
||||
|
||||
/// <summary>Multiply this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Mult(double f)
|
||||
{
|
||||
this.X *= f;
|
||||
this.Y *= f;
|
||||
}
|
||||
|
||||
#endregion public void Mult()
|
||||
|
||||
#region public void Div()
|
||||
|
||||
/// <summary>Divide this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Div(double f)
|
||||
{
|
||||
double mult = 1.0 / f;
|
||||
this.X *= mult;
|
||||
this.Y *= mult;
|
||||
}
|
||||
|
||||
#endregion public void Div()
|
||||
|
||||
#region public double Length
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length (magnitude) of the vector.
|
||||
/// </summary>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public double Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Sqrt(X * X + Y * Y);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public double LengthSquared
|
||||
|
||||
/// <summary>
|
||||
/// Gets the square of the vector length (magnitude).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property avoids the costly square root operation required by the Length property. This makes it more suitable
|
||||
/// for comparisons.
|
||||
/// </remarks>
|
||||
/// <see cref="Length"/>
|
||||
public double LengthSquared
|
||||
{
|
||||
get
|
||||
{
|
||||
return X * X + Y * Y;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public Vector2d PerpendicularRight
|
||||
|
||||
/// <summary>
|
||||
/// Gets the perpendicular vector on the right side of this vector.
|
||||
/// </summary>
|
||||
public Vector2d PerpendicularRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2d(Y, -X);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public Vector2d PerpendicularLeft
|
||||
|
||||
/// <summary>
|
||||
/// Gets the perpendicular vector on the left side of this vector.
|
||||
/// </summary>
|
||||
public Vector2d PerpendicularLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vector2d(-Y, X);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Normalize()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Vector2 to unit length.
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
double scale = 1.0f / Length;
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Scale()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the current Vector2 by the given amounts.
|
||||
/// </summary>
|
||||
/// <param name="sx">The scale of the X component.</param>
|
||||
/// <param name="sy">The scale of the Y component.</param>
|
||||
public void Scale(double sx, double sy)
|
||||
{
|
||||
X *= sx;
|
||||
Y *= sy;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
public void Scale(Vector2d scale)
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Scale(ref Vector2d scale)
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
}
|
||||
|
||||
#endregion public void Scale()
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
#region Add
|
||||
|
||||
/// <summary>
|
||||
/// Add two Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of addition</returns>
|
||||
public static Vector2d Add(Vector2d a, Vector2d b)
|
||||
{
|
||||
a.X += b.X;
|
||||
a.Y += b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add two Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of addition</param>
|
||||
public static void Add(ref Vector2d a, ref Vector2d b, out Vector2d result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sub
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of subtraction</returns>
|
||||
public static Vector2d Sub(Vector2d a, Vector2d b)
|
||||
{
|
||||
a.X -= b.X;
|
||||
a.Y -= b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of subtraction</param>
|
||||
public static void Sub(ref Vector2d a, ref Vector2d b, out Vector2d result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mult
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="d">Scalar operand</param>
|
||||
/// <returns>Result of the multiplication</returns>
|
||||
public static Vector2d Mult(Vector2d a, double d)
|
||||
{
|
||||
a.X *= d;
|
||||
a.Y *= d;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="d">Scalar operand</param>
|
||||
/// <param name="result">Result of the multiplication</param>
|
||||
public static void Mult(ref Vector2d a, double d, out Vector2d result)
|
||||
{
|
||||
result.X = a.X * d;
|
||||
result.Y = a.Y * d;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Div
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="d">Scalar operand</param>
|
||||
/// <returns>Result of the division</returns>
|
||||
public static Vector2d Div(Vector2d a, double d)
|
||||
{
|
||||
double mult = 1.0 / d;
|
||||
a.X *= mult;
|
||||
a.Y *= mult;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="d">Scalar operand</param>
|
||||
/// <param name="result">Result of the division</param>
|
||||
public static void Div(ref Vector2d a, double d, out Vector2d result)
|
||||
{
|
||||
double mult = 1.0 / d;
|
||||
result.X = a.X * mult;
|
||||
result.Y = a.Y * mult;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Min
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise minimum</returns>
|
||||
public static Vector2d Min(Vector2d a, Vector2d b)
|
||||
{
|
||||
a.X = a.X < b.X ? a.X : b.X;
|
||||
a.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise minimum</param>
|
||||
public static void Min(ref Vector2d a, ref Vector2d b, out Vector2d result)
|
||||
{
|
||||
result.X = a.X < b.X ? a.X : b.X;
|
||||
result.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Max
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise maximum</returns>
|
||||
public static Vector2d Max(Vector2d a, Vector2d b)
|
||||
{
|
||||
a.X = a.X > b.X ? a.X : b.X;
|
||||
a.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise maximum</param>
|
||||
public static void Max(ref Vector2d a, ref Vector2d b, out Vector2d result)
|
||||
{
|
||||
result.X = a.X > b.X ? a.X : b.X;
|
||||
result.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clamp
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <returns>The clamped vector</returns>
|
||||
public static Vector2d Clamp(Vector2d vec, Vector2d min, Vector2d max)
|
||||
{
|
||||
vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <param name="result">The clamped vector</param>
|
||||
public static void Clamp(ref Vector2d vec, ref Vector2d min, ref Vector2d max, out Vector2d result)
|
||||
{
|
||||
result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Normalize
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector2d Normalize(Vector2d vec)
|
||||
{
|
||||
double scale = 1.0f / vec.Length;
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void Normalize(ref Vector2d vec, out Vector2d result)
|
||||
{
|
||||
double scale = 1.0f / vec.Length;
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NormalizeFast
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector2d NormalizeFast(Vector2d vec)
|
||||
{
|
||||
double scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void NormalizeFast(ref Vector2d vec, out Vector2d result)
|
||||
{
|
||||
double scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dot
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot (scalar) product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <returns>The dot product of the two inputs</returns>
|
||||
public static double Dot(Vector2d left, Vector2d right)
|
||||
{
|
||||
return left.X * right.X + left.Y * right.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot (scalar) product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <param name="result">The dot product of the two inputs</param>
|
||||
public static void Dot(ref Vector2d left, ref Vector2d right, out double result)
|
||||
{
|
||||
result = left.X * right.X + left.Y * right.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lerp
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
|
||||
public static Vector2d Lerp(Vector2d a, Vector2d b, double blend)
|
||||
{
|
||||
a.X = blend * (b.X - a.X) + a.X;
|
||||
a.Y = blend * (b.Y - a.Y) + a.Y;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
|
||||
public static void Lerp(ref Vector2d a, ref Vector2d b, double blend, out Vector2d result)
|
||||
{
|
||||
result.X = blend * (b.X - a.X) + a.X;
|
||||
result.Y = blend * (b.Y - a.Y) + a.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Barycentric
|
||||
|
||||
/// <summary>
|
||||
/// Interpolate 3 Vectors using Barycentric coordinates
|
||||
/// </summary>
|
||||
/// <param name="a">First input Vector</param>
|
||||
/// <param name="b">Second input Vector</param>
|
||||
/// <param name="c">Third input Vector</param>
|
||||
/// <param name="u">First Barycentric Coordinate</param>
|
||||
/// <param name="v">Second Barycentric Coordinate</param>
|
||||
/// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
|
||||
public static Vector2d BaryCentric(Vector2d a, Vector2d b, Vector2d c, double u, double v)
|
||||
{
|
||||
return a + u * (b - a) + v * (c - a);
|
||||
}
|
||||
|
||||
/// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
|
||||
/// <param name="a">First input Vector.</param>
|
||||
/// <param name="b">Second input Vector.</param>
|
||||
/// <param name="c">Third input Vector.</param>
|
||||
/// <param name="u">First Barycentric Coordinate.</param>
|
||||
/// <param name="v">Second Barycentric Coordinate.</param>
|
||||
/// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
|
||||
public static void BaryCentric(ref Vector2d a, ref Vector2d b, ref Vector2d c, float u, float v, out Vector2d result)
|
||||
{
|
||||
result = a; // copy
|
||||
|
||||
Vector2d temp = b; // copy
|
||||
temp.Sub(ref a);
|
||||
temp.Mult(u);
|
||||
result.Add(ref temp);
|
||||
|
||||
temp = c; // copy
|
||||
temp.Sub(ref a);
|
||||
temp.Mult(v);
|
||||
result.Add(ref temp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operators
|
||||
|
||||
/// <summary>
|
||||
/// Adds two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator +(Vector2d left, Vector2d right)
|
||||
{
|
||||
left.X += right.X;
|
||||
left.Y += right.Y;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two instances.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator -(Vector2d left, Vector2d right)
|
||||
{
|
||||
left.X -= right.X;
|
||||
left.Y -= right.Y;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates an instance.
|
||||
/// </summary>
|
||||
/// <param name="vec">The instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator -(Vector2d vec)
|
||||
{
|
||||
vec.X = -vec.X;
|
||||
vec.Y = -vec.Y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies an instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="vec">The instance.</param>
|
||||
/// <param name="f">The scalar.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator *(Vector2d vec, double f)
|
||||
{
|
||||
vec.X *= f;
|
||||
vec.Y *= f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply an instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="f">The scalar.</param>
|
||||
/// <param name="vec">The instance.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator *(double f, Vector2d vec)
|
||||
{
|
||||
vec.X *= f;
|
||||
vec.Y *= f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides an instance by a scalar.
|
||||
/// </summary>
|
||||
/// <param name="vec">The instance.</param>
|
||||
/// <param name="f">The scalar.</param>
|
||||
/// <returns>The result of the operation.</returns>
|
||||
public static Vector2d operator /(Vector2d vec, double f)
|
||||
{
|
||||
double mult = 1.0f / f;
|
||||
vec.X *= mult;
|
||||
vec.Y *= mult;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>True, if both instances are equal; false otherwise.</returns>
|
||||
public static bool operator ==(Vector2d left, Vector2d right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for ienquality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left instance.</param>
|
||||
/// <param name="right">The right instance.</param>
|
||||
/// <returns>True, if the instances are not equal; false otherwise.</returns>
|
||||
public static bool operator !=(Vector2d left, Vector2d right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Vector2 to OpenTK.Vector2d.</summary>
|
||||
/// <param name="v2">The Vector2 to convert.</param>
|
||||
/// <returns>The resulting Vector2d.</returns>
|
||||
public static explicit operator Vector2d(Vector2 v2)
|
||||
{
|
||||
return new Vector2d(v2.X, v2.Y);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Vector2d to OpenTK.Vector2.</summary>
|
||||
/// <param name="v2d">The Vector2d to convert.</param>
|
||||
/// <returns>The resulting Vector2.</returns>
|
||||
public static explicit operator Vector2(Vector2d v2d)
|
||||
{
|
||||
return new Vector2((float)v2d.X, (float)v2d.Y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current instance.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1})", X, Y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override int GetHashCode()
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hashcode for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override bool Equals(object obj)
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare to.</param>
|
||||
/// <returns>True if the instances are equal; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Vector2d))
|
||||
return false;
|
||||
|
||||
return this.Equals((Vector2d)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<Vector2d> Members
|
||||
|
||||
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
|
||||
/// <param name="other">A vector to compare with this vector.</param>
|
||||
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
|
||||
public bool Equals(Vector2d other)
|
||||
{
|
||||
return
|
||||
X == other.X &&
|
||||
Y == other.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
336
Source/Compatibility/Math/Vector2h.cs
Normal file
336
Source/Compatibility/Math/Vector2h.cs
Normal file
|
@ -0,0 +1,336 @@
|
|||
#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.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
|
||||
/// <summary>2-component Vector of the Half type. Occupies 4 Byte total.</summary>
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector2h : ISerializable, IEquatable<Vector2h>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>The X component of the Half2.</summary>
|
||||
public Half X;
|
||||
|
||||
/// <summary>The Y component of the Half2.</summary>
|
||||
public Half Y;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will avoid conversion and copy directly from the Half parameters.
|
||||
/// </summary>
|
||||
/// <param name="x">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="y">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
public Vector2h(Half x, Half y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the 2 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
public Vector2h(Single x, Single y)
|
||||
{
|
||||
X = new Half(x);
|
||||
Y = new Half(y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the 2 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector2h(Single x, Single y, bool throwOnError)
|
||||
{
|
||||
X = new Half(x, throwOnError);
|
||||
Y = new Half(y, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector2h(Vector2 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector2h(Vector2 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2 into 16-Bit Half precision floating point.
|
||||
/// This is the fastest constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2</param>
|
||||
public Vector2h(ref Vector2 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector2h(ref Vector2 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2d</param>
|
||||
public Vector2h(Vector2d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector2h(Vector2d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2d into 16-Bit Half precision floating point.
|
||||
/// This is the faster constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2d</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector2h(ref Vector2d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half2 instance will convert the Vector2d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector2d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector2h(ref Vector2d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Half -> Single
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half2 instance's contents as Vector2.
|
||||
/// </summary>
|
||||
/// <returns>OpenTK.Vector2</returns>
|
||||
public Vector2 ToVector2()
|
||||
{
|
||||
return new Vector2(X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half2 instance's contents as Vector2d.
|
||||
/// </summary>
|
||||
public Vector2d ToVector2d()
|
||||
{
|
||||
return new Vector2d(X, Y);
|
||||
}
|
||||
|
||||
#endregion Half -> Single
|
||||
|
||||
#region Conversions
|
||||
|
||||
/// <summary>Converts OpenTK.Vector2 to OpenTK.Half2.</summary>
|
||||
/// <param name="v">The Vector2 to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector2h(Vector2 v)
|
||||
{
|
||||
return new Vector2h(v);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Vector2d to OpenTK.Half2.</summary>
|
||||
/// <param name="v">The Vector2d to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector2h(Vector2d v)
|
||||
{
|
||||
return new Vector2h(v);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half2 to OpenTK.Vector2.</summary>
|
||||
/// <param name="h">The Half2 to convert.</param>
|
||||
/// <returns>The resulting Vector2.</returns>
|
||||
public static explicit operator Vector2(Vector2h h)
|
||||
{
|
||||
return new Vector2(h.X, h.Y);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half2 to OpenTK.Vector2d.</summary>
|
||||
/// <param name="h">The Half2 to convert.</param>
|
||||
/// <returns>The resulting Vector2d.</returns>
|
||||
public static explicit operator Vector2d(Vector2h h)
|
||||
{
|
||||
return new Vector2d(h.X, h.Y);
|
||||
}
|
||||
|
||||
#endregion Conversions
|
||||
|
||||
#region Constants
|
||||
|
||||
/// <summary>The size in bytes for an instance of the Half2 struct is 4.</summary>
|
||||
public static readonly int SizeInBytes = 4;
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region ISerializable
|
||||
|
||||
/// <summary>Constructor used by ISerializable to deserialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public Vector2h(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
this.X = (Half)info.GetValue("X", typeof(Half));
|
||||
this.Y = (Half)info.GetValue("Y", typeof(Half));
|
||||
}
|
||||
|
||||
/// <summary>Used by ISerialize to serialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("X", this.X);
|
||||
info.AddValue("Y", this.Y);
|
||||
}
|
||||
|
||||
#endregion ISerializable
|
||||
|
||||
#region Binary dump
|
||||
|
||||
/// <summary>Updates the X and Y components of this instance by reading from a Stream.</summary>
|
||||
/// <param name="bin">A BinaryReader instance associated with an open Stream.</param>
|
||||
public void FromBinaryStream(BinaryReader bin)
|
||||
{
|
||||
X.FromBinaryStream(bin);
|
||||
Y.FromBinaryStream(bin);
|
||||
}
|
||||
|
||||
/// <summary>Writes the X and Y components of this instance into a Stream.</summary>
|
||||
/// <param name="bin">A BinaryWriter instance associated with an open Stream.</param>
|
||||
public void ToBinaryStream(BinaryWriter bin)
|
||||
{
|
||||
X.ToBinaryStream(bin);
|
||||
Y.ToBinaryStream(bin);
|
||||
}
|
||||
|
||||
#endregion Binary dump
|
||||
|
||||
#region IEquatable<Half2> Members
|
||||
|
||||
/// <summary>Returns a value indicating whether this instance is equal to a specified OpenTK.Half2 vector.</summary>
|
||||
/// <param name="other">OpenTK.Half2 to compare to this instance..</param>
|
||||
/// <returns>True, if other is equal to this instance; false otherwise.</returns>
|
||||
public bool Equals(Vector2h other)
|
||||
{
|
||||
return (this.X.Equals(other.X) && this.Y.Equals(other.Y));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToString()
|
||||
|
||||
/// <summary>Returns a string that contains this Half2's numbers in human-legible form.</summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1})", X.ToString(), Y.ToString());
|
||||
}
|
||||
|
||||
#endregion ToString()
|
||||
|
||||
#region BitConverter
|
||||
|
||||
/// <summary>Returns the Half2 as an array of bytes.</summary>
|
||||
/// <param name="h">The Half2 to convert.</param>
|
||||
/// <returns>The input as byte array.</returns>
|
||||
public static byte[] GetBytes(Vector2h h)
|
||||
{
|
||||
byte[] result = new byte[SizeInBytes];
|
||||
|
||||
byte[] temp = Half.GetBytes(h.X);
|
||||
result[0] = temp[0];
|
||||
result[1] = temp[1];
|
||||
temp = Half.GetBytes(h.Y);
|
||||
result[2] = temp[0];
|
||||
result[3] = temp[1];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Converts an array of bytes into Half2.</summary>
|
||||
/// <param name="value">A Half2 in it's byte[] representation.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A new Half2 instance.</returns>
|
||||
public static Vector2h FromBytes(byte[] value, int startIndex)
|
||||
{
|
||||
Vector2h h2 = new Vector2h();
|
||||
h2.X = Half.FromBytes(value, startIndex);
|
||||
h2.Y = Half.FromBytes(value, startIndex + 2);
|
||||
return h2;
|
||||
}
|
||||
|
||||
#endregion BitConverter
|
||||
}
|
||||
}
|
1151
Source/Compatibility/Math/Vector3.cs
Normal file
1151
Source/Compatibility/Math/Vector3.cs
Normal file
File diff suppressed because it is too large
Load diff
1163
Source/Compatibility/Math/Vector3d.cs
Normal file
1163
Source/Compatibility/Math/Vector3d.cs
Normal file
File diff suppressed because it is too large
Load diff
381
Source/Compatibility/Math/Vector3h.cs
Normal file
381
Source/Compatibility/Math/Vector3h.cs
Normal file
|
@ -0,0 +1,381 @@
|
|||
#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.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// 3-component Vector of the Half type. Occupies 6 Byte total.
|
||||
/// </summary>
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector3h : ISerializable, IEquatable<Vector3h>
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>The X component of the Half3.</summary>
|
||||
public Half X;
|
||||
|
||||
/// <summary>The Y component of the Half3.</summary>
|
||||
public Half Y;
|
||||
|
||||
/// <summary>The Z component of the Half3.</summary>
|
||||
public Half Z;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will avoid conversion and copy directly from the Half parameters.
|
||||
/// </summary>
|
||||
/// <param name="x">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="y">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="z">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
public Vector3h(Half x, Half y, Half z)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the 3 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="z">32-Bit Single precision floating point number.</param>
|
||||
public Vector3h(Single x, Single y, Single z)
|
||||
{
|
||||
X = new Half(x);
|
||||
Y = new Half(y);
|
||||
Z = new Half(z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the 3 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="z">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector3h(Single x, Single y, Single z, bool throwOnError)
|
||||
{
|
||||
X = new Half(x, throwOnError);
|
||||
Y = new Half(y, throwOnError);
|
||||
Z = new Half(z, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector3h(Vector3 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector3h(Vector3 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3 into 16-Bit Half precision floating point.
|
||||
/// This is the fastest constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3</param>
|
||||
public Vector3h(ref Vector3 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector3h(ref Vector3 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3d</param>
|
||||
public Vector3h(Vector3d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector3h(Vector3d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3d into 16-Bit Half precision floating point.
|
||||
/// This is the faster constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3d</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector3h(ref Vector3d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half3 instance will convert the Vector3d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector3d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector3h(ref Vector3d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Swizzle
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Half -> Single
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half3 instance's contents as Vector3.
|
||||
/// </summary>
|
||||
/// <returns>OpenTK.Vector3</returns>
|
||||
public Vector3 ToVector3()
|
||||
{
|
||||
return new Vector3(X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half3 instance's contents as Vector3d.
|
||||
/// </summary>
|
||||
public Vector3d ToVector3d()
|
||||
{
|
||||
return new Vector3d(X, Y, Z);
|
||||
}
|
||||
|
||||
#endregion Half -> Single
|
||||
|
||||
#region Conversions
|
||||
|
||||
/// <summary>Converts OpenTK.Vector3 to OpenTK.Half3.</summary>
|
||||
/// <param name="v3f">The Vector3 to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector3h(Vector3 v3f)
|
||||
{
|
||||
return new Vector3h(v3f);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Vector3d to OpenTK.Half3.</summary>
|
||||
/// <param name="v3d">The Vector3d to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector3h(Vector3d v3d)
|
||||
{
|
||||
return new Vector3h(v3d);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half3 to OpenTK.Vector3.</summary>
|
||||
/// <param name="h3">The Half3 to convert.</param>
|
||||
/// <returns>The resulting Vector3.</returns>
|
||||
public static explicit operator Vector3(Vector3h h3)
|
||||
{
|
||||
Vector3 result = new Vector3();
|
||||
result.X = h3.X.ToSingle();
|
||||
result.Y = h3.Y.ToSingle();
|
||||
result.Z = h3.Z.ToSingle();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half3 to OpenTK.Vector3d.</summary>
|
||||
/// <param name="h3">The Half3 to convert.</param>
|
||||
/// <returns>The resulting Vector3d.</returns>
|
||||
public static explicit operator Vector3d(Vector3h h3)
|
||||
{
|
||||
Vector3d result = new Vector3d();
|
||||
result.X = h3.X.ToSingle();
|
||||
result.Y = h3.Y.ToSingle();
|
||||
result.Z = h3.Z.ToSingle();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion Conversions
|
||||
|
||||
#region Constants
|
||||
|
||||
/// <summary>The size in bytes for an instance of the Half3 struct is 6.</summary>
|
||||
public static readonly int SizeInBytes = 6;
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region ISerializable
|
||||
|
||||
/// <summary>Constructor used by ISerializable to deserialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public Vector3h(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
this.X = (Half)info.GetValue("X", typeof(Half));
|
||||
this.Y = (Half)info.GetValue("Y", typeof(Half));
|
||||
this.Z = (Half)info.GetValue("Z", typeof(Half));
|
||||
}
|
||||
|
||||
/// <summary>Used by ISerialize to serialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("X", this.X);
|
||||
info.AddValue("Y", this.Y);
|
||||
info.AddValue("Z", this.Z);
|
||||
}
|
||||
|
||||
#endregion ISerializable
|
||||
|
||||
#region Binary dump
|
||||
|
||||
/// <summary>Updates the X,Y and Z components of this instance by reading from a Stream.</summary>
|
||||
/// <param name="bin">A BinaryReader instance associated with an open Stream.</param>
|
||||
public void FromBinaryStream(BinaryReader bin)
|
||||
{
|
||||
X.FromBinaryStream(bin);
|
||||
Y.FromBinaryStream(bin);
|
||||
Z.FromBinaryStream(bin);
|
||||
}
|
||||
|
||||
/// <summary>Writes the X,Y and Z components of this instance into a Stream.</summary>
|
||||
/// <param name="bin">A BinaryWriter instance associated with an open Stream.</param>
|
||||
public void ToBinaryStream(BinaryWriter bin)
|
||||
{
|
||||
X.ToBinaryStream(bin);
|
||||
Y.ToBinaryStream(bin);
|
||||
Z.ToBinaryStream(bin);
|
||||
}
|
||||
|
||||
#endregion Binary dump
|
||||
|
||||
#region IEquatable<Half3> Members
|
||||
|
||||
/// <summary>Returns a value indicating whether this instance is equal to a specified OpenTK.Half3 vector.</summary>
|
||||
/// <param name="other">OpenTK.Half3 to compare to this instance..</param>
|
||||
/// <returns>True, if other is equal to this instance; false otherwise.</returns>
|
||||
public bool Equals(Vector3h other)
|
||||
{
|
||||
return (this.X.Equals(other.X) && this.Y.Equals(other.Y) && this.Z.Equals(other.Z));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToString()
|
||||
|
||||
/// <summary>Returns a string that contains this Half3's numbers in human-legible form.</summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1}, {2})", X.ToString(), Y.ToString(), Z.ToString());
|
||||
}
|
||||
|
||||
#endregion ToString()
|
||||
|
||||
#region BitConverter
|
||||
|
||||
/// <summary>Returns the Half3 as an array of bytes.</summary>
|
||||
/// <param name="h">The Half3 to convert.</param>
|
||||
/// <returns>The input as byte array.</returns>
|
||||
public static byte[] GetBytes(Vector3h h)
|
||||
{
|
||||
byte[] result = new byte[SizeInBytes];
|
||||
|
||||
byte[] temp = Half.GetBytes(h.X);
|
||||
result[0] = temp[0];
|
||||
result[1] = temp[1];
|
||||
temp = Half.GetBytes(h.Y);
|
||||
result[2] = temp[0];
|
||||
result[3] = temp[1];
|
||||
temp = Half.GetBytes(h.Z);
|
||||
result[4] = temp[0];
|
||||
result[5] = temp[1];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Converts an array of bytes into Half3.</summary>
|
||||
/// <param name="value">A Half3 in it's byte[] representation.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A new Half3 instance.</returns>
|
||||
public static Vector3h FromBytes(byte[] value, int startIndex)
|
||||
{
|
||||
Vector3h h3 = new Vector3h();
|
||||
h3.X = Half.FromBytes(value, startIndex);
|
||||
h3.Y = Half.FromBytes(value, startIndex + 2);
|
||||
h3.Z = Half.FromBytes(value, startIndex + 4);
|
||||
return h3;
|
||||
}
|
||||
|
||||
#endregion BitConverter
|
||||
}
|
||||
}
|
997
Source/Compatibility/Math/Vector4.cs
Normal file
997
Source/Compatibility/Math/Vector4.cs
Normal file
|
@ -0,0 +1,997 @@
|
|||
#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;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>Represents a 4D vector using four single-precision floating-point numbers.</summary>
|
||||
/// <remarks>
|
||||
/// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector4 : IEquatable<Vector4>
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the Vector4.
|
||||
/// </summary>
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the Vector4.
|
||||
/// </summary>
|
||||
public float Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the Vector4.
|
||||
/// </summary>
|
||||
public float Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component of the Vector4.
|
||||
/// </summary>
|
||||
public float W;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector4 that points towards the X-axis.
|
||||
/// </summary>
|
||||
public static Vector4 UnitX = new Vector4(1, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector4 that points towards the Y-axis.
|
||||
/// </summary>
|
||||
public static Vector4 UnitY = new Vector4(0, 1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector4 that points towards the Z-axis.
|
||||
/// </summary>
|
||||
public static Vector4 UnitZ = new Vector4(0, 0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a unit-length Vector4 that points towards the W-axis.
|
||||
/// </summary>
|
||||
public static Vector4 UnitW = new Vector4(0, 0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a zero-length Vector4.
|
||||
/// </summary>
|
||||
public static Vector4 Zero = new Vector4(0, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Defines an instance with all components set to 1.
|
||||
/// </summary>
|
||||
public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Defines the size of the Vector4 struct in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector4.
|
||||
/// </summary>
|
||||
/// <param name="x">The x component of the Vector4.</param>
|
||||
/// <param name="y">The y component of the Vector4.</param>
|
||||
/// <param name="z">The z component of the Vector4.</param>
|
||||
/// <param name="w">The z component of the Vector4.</param>
|
||||
public Vector4(float x, float y, float z, float w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector4 from the given Vector2.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector2 to copy components from.</param>
|
||||
public Vector4(Vector2 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
Z = 0.0f;
|
||||
W = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector4 from the given Vector3.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector3 to copy components from.</param>
|
||||
public Vector4(Vector3 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
Z = v.Z;
|
||||
W = 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector4 from the specified Vector3 and W component.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector3 to copy components from.</param>
|
||||
/// <param name="w">The W component of the new Vector4.</param>
|
||||
public Vector4(Vector3 v, float w)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
Z = v.Z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Vector4 from the given Vector4.
|
||||
/// </summary>
|
||||
/// <param name="v">The Vector4 to copy components from.</param>
|
||||
public Vector4(Vector4 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
Z = v.Z;
|
||||
W = v.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
#region Instance
|
||||
|
||||
#region public void Add()
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Add( Vector4 right )
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
this.Z += right.Z;
|
||||
this.W += right.W;
|
||||
}
|
||||
|
||||
/// <summary>Add the Vector passed as parameter to this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Add( ref Vector4 right )
|
||||
{
|
||||
this.X += right.X;
|
||||
this.Y += right.Y;
|
||||
this.Z += right.Z;
|
||||
this.W += right.W;
|
||||
}
|
||||
|
||||
#endregion public void Add()
|
||||
|
||||
#region public void Sub()
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
public void Sub( Vector4 right )
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
this.Z -= right.Z;
|
||||
this.W -= right.W;
|
||||
}
|
||||
|
||||
/// <summary>Subtract the Vector passed as parameter from this instance.</summary>
|
||||
/// <param name="right">Right operand. This parameter is only read from.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Sub( ref Vector4 right )
|
||||
{
|
||||
this.X -= right.X;
|
||||
this.Y -= right.Y;
|
||||
this.Z -= right.Z;
|
||||
this.W -= right.W;
|
||||
}
|
||||
|
||||
#endregion public void Sub()
|
||||
|
||||
#region public void Mult()
|
||||
|
||||
/// <summary>Multiply this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Mult( float f )
|
||||
{
|
||||
this.X *= f;
|
||||
this.Y *= f;
|
||||
this.Z *= f;
|
||||
this.W *= f;
|
||||
}
|
||||
|
||||
#endregion public void Mult()
|
||||
|
||||
#region public void Div()
|
||||
|
||||
/// <summary>Divide this instance by a scalar.</summary>
|
||||
/// <param name="f">Scalar operand.</param>
|
||||
public void Div( float f )
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
this.X *= mult;
|
||||
this.Y *= mult;
|
||||
this.Z *= mult;
|
||||
this.W *= mult;
|
||||
}
|
||||
|
||||
#endregion public void Div()
|
||||
|
||||
#region public float Length
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length (magnitude) of the vector.
|
||||
/// </summary>
|
||||
/// <see cref="LengthFast"/>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float LengthFast
|
||||
|
||||
/// <summary>
|
||||
/// Gets an approximation of the vector length (magnitude).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property uses an approximation of the square root function to calculate vector magnitude, with
|
||||
/// an upper error bound of 0.001.
|
||||
/// </remarks>
|
||||
/// <see cref="Length"/>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
public float LengthFast
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public float LengthSquared
|
||||
|
||||
/// <summary>
|
||||
/// Gets the square of the vector length (magnitude).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property avoids the costly square root operation required by the Length property. This makes it more suitable
|
||||
/// for comparisons.
|
||||
/// </remarks>
|
||||
/// <see cref="Length"/>
|
||||
/// <seealso cref="LengthFast"/>
|
||||
public float LengthSquared
|
||||
{
|
||||
get
|
||||
{
|
||||
return X * X + Y * Y + Z * Z + W * W;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Normalize()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Vector4 to unit length.
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
float scale = 1.0f / this.Length;
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
Z *= scale;
|
||||
W *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void NormalizeFast()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the Vector4 to approximately unit length.
|
||||
/// </summary>
|
||||
public void NormalizeFast()
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
Z *= scale;
|
||||
W *= scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void Scale()
|
||||
|
||||
/// <summary>
|
||||
/// Scales the current Vector4 by the given amounts.
|
||||
/// </summary>
|
||||
/// <param name="sx">The scale of the X component.</param>
|
||||
/// <param name="sy">The scale of the Y component.</param>
|
||||
/// <param name="sz">The scale of the Z component.</param>
|
||||
/// <param name="sw">The scale of the Z component.</param>
|
||||
public void Scale( float sx, float sy, float sz, float sw )
|
||||
{
|
||||
this.X = X * sx;
|
||||
this.Y = Y * sy;
|
||||
this.Z = Z * sz;
|
||||
this.W = W * sw;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
public void Scale( Vector4 scale )
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
this.Z *= scale.Z;
|
||||
this.W *= scale.W;
|
||||
}
|
||||
|
||||
/// <summary>Scales this instance by the given parameter.</summary>
|
||||
/// <param name="scale">The scaling of the individual components.</param>
|
||||
[CLSCompliant(false)]
|
||||
public void Scale( ref Vector4 scale )
|
||||
{
|
||||
this.X *= scale.X;
|
||||
this.Y *= scale.Y;
|
||||
this.Z *= scale.Z;
|
||||
this.W *= scale.W;
|
||||
}
|
||||
|
||||
#endregion public void Scale()
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
#region Add
|
||||
|
||||
/// <summary>
|
||||
/// Add two Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of addition</returns>
|
||||
public static Vector4 Add(Vector4 a, Vector4 b)
|
||||
{
|
||||
a.X += b.X;
|
||||
a.Y += b.Y;
|
||||
a.Z += b.Z;
|
||||
a.W += b.W;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add two Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of addition</param>
|
||||
public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
|
||||
{
|
||||
result.X = a.X + b.X;
|
||||
result.Y = a.Y + b.Y;
|
||||
result.Z = a.Z + b.Z;
|
||||
result.W = a.W + b.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sub
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>Result of subtraction</returns>
|
||||
public static Vector4 Sub(Vector4 a, Vector4 b)
|
||||
{
|
||||
a.X -= b.X;
|
||||
a.Y -= b.Y;
|
||||
a.Z -= b.Z;
|
||||
a.W -= b.W;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract one Vector from another
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">Result of subtraction</param>
|
||||
public static void Sub(ref Vector4 a, ref Vector4 b, out Vector4 result)
|
||||
{
|
||||
result.X = a.X - b.X;
|
||||
result.Y = a.Y - b.Y;
|
||||
result.Z = a.Z - b.Z;
|
||||
result.W = a.W - b.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mult
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <returns>Result of the multiplication</returns>
|
||||
public static Vector4 Mult(Vector4 a, float f)
|
||||
{
|
||||
a.X *= f;
|
||||
a.Y *= f;
|
||||
a.Z *= f;
|
||||
a.W *= f;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply a vector and a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <param name="result">Result of the multiplication</param>
|
||||
public static void Mult(ref Vector4 a, float f, out Vector4 result)
|
||||
{
|
||||
result.X = a.X * f;
|
||||
result.Y = a.Y * f;
|
||||
result.Z = a.Z * f;
|
||||
result.W = a.W * f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Div
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <returns>Result of the division</returns>
|
||||
public static Vector4 Div(Vector4 a, float f)
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
a.X *= mult;
|
||||
a.Y *= mult;
|
||||
a.Z *= mult;
|
||||
a.W *= mult;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divide a vector by a scalar
|
||||
/// </summary>
|
||||
/// <param name="a">Vector operand</param>
|
||||
/// <param name="f">Scalar operand</param>
|
||||
/// <param name="result">Result of the division</param>
|
||||
public static void Div(ref Vector4 a, float f, out Vector4 result)
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
result.X = a.X * mult;
|
||||
result.Y = a.Y * mult;
|
||||
result.Z = a.Z * mult;
|
||||
result.W = a.W * mult;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Min
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise minimum</returns>
|
||||
public static Vector4 Min(Vector4 a, Vector4 b)
|
||||
{
|
||||
a.X = a.X < b.X ? a.X : b.X;
|
||||
a.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
a.Z = a.Z < b.Z ? a.Z : b.Z;
|
||||
a.W = a.W < b.W ? a.W : b.W;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise minimum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise minimum</param>
|
||||
public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
|
||||
{
|
||||
result.X = a.X < b.X ? a.X : b.X;
|
||||
result.Y = a.Y < b.Y ? a.Y : b.Y;
|
||||
result.Z = a.Z < b.Z ? a.Z : b.Z;
|
||||
result.W = a.W < b.W ? a.W : b.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Max
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <returns>The component-wise maximum</returns>
|
||||
public static Vector4 Max(Vector4 a, Vector4 b)
|
||||
{
|
||||
a.X = a.X > b.X ? a.X : b.X;
|
||||
a.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
a.Z = a.Z > b.Z ? a.Z : b.Z;
|
||||
a.W = a.W > b.W ? a.W : b.W;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the component-wise maximum of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First operand</param>
|
||||
/// <param name="b">Second operand</param>
|
||||
/// <param name="result">The component-wise maximum</param>
|
||||
public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
|
||||
{
|
||||
result.X = a.X > b.X ? a.X : b.X;
|
||||
result.Y = a.Y > b.Y ? a.Y : b.Y;
|
||||
result.Z = a.Z > b.Z ? a.Z : b.Z;
|
||||
result.W = a.W > b.W ? a.W : b.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clamp
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <returns>The clamped vector</returns>
|
||||
public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
|
||||
{
|
||||
vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
|
||||
vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a vector to the given minimum and maximum vectors
|
||||
/// </summary>
|
||||
/// <param name="vec">Input vector</param>
|
||||
/// <param name="min">Minimum vector</param>
|
||||
/// <param name="max">Maximum vector</param>
|
||||
/// <param name="result">The clamped vector</param>
|
||||
public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
|
||||
{
|
||||
result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
|
||||
result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
|
||||
result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
|
||||
result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Normalize
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector4 Normalize(Vector4 vec)
|
||||
{
|
||||
float scale = 1.0f / vec.Length;
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
vec.Z *= scale;
|
||||
vec.W *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void Normalize(ref Vector4 vec, out Vector4 result)
|
||||
{
|
||||
float scale = 1.0f / vec.Length;
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
result.Z = vec.Z * scale;
|
||||
result.W = vec.W * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region NormalizeFast
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <returns>The normalized vector</returns>
|
||||
public static Vector4 NormalizeFast(Vector4 vec)
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
|
||||
vec.X *= scale;
|
||||
vec.Y *= scale;
|
||||
vec.Z *= scale;
|
||||
vec.W *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale a vector to approximately unit length
|
||||
/// </summary>
|
||||
/// <param name="vec">The input vector</param>
|
||||
/// <param name="result">The normalized vector</param>
|
||||
public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
|
||||
{
|
||||
float scale = Functions.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
|
||||
result.X = vec.X * scale;
|
||||
result.Y = vec.Y * scale;
|
||||
result.Z = vec.Z * scale;
|
||||
result.W = vec.W * scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dot
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <returns>The dot product of the two inputs</returns>
|
||||
public static float Dot(Vector4 left, Vector4 right)
|
||||
{
|
||||
return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the dot product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="left">First operand</param>
|
||||
/// <param name="right">Second operand</param>
|
||||
/// <param name="result">The dot product of the two inputs</param>
|
||||
public static void Dot( ref Vector4 left, ref Vector4 right, out float result )
|
||||
{
|
||||
result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lerp
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
|
||||
public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
|
||||
{
|
||||
a.X = blend * (b.X - a.X) + a.X;
|
||||
a.Y = blend * (b.Y - a.Y) + a.Y;
|
||||
a.Z = blend * (b.Z - a.Z) + a.Z;
|
||||
a.W = blend * (b.W - a.W) + a.W;
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new Vector that is the linear blend of the 2 given Vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First input vector</param>
|
||||
/// <param name="b">Second input vector</param>
|
||||
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
|
||||
/// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
|
||||
public static void Lerp( ref Vector4 a, ref Vector4 b, float blend, out Vector4 result )
|
||||
{
|
||||
result.X = blend * ( b.X - a.X ) + a.X;
|
||||
result.Y = blend * ( b.Y - a.Y ) + a.Y;
|
||||
result.Z = blend * ( b.Z - a.Z ) + a.Z;
|
||||
result.W = blend * ( b.W - a.W ) + a.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Barycentric
|
||||
|
||||
/// <summary>
|
||||
/// Interpolate 3 Vectors using Barycentric coordinates
|
||||
/// </summary>
|
||||
/// <param name="a">First input Vector</param>
|
||||
/// <param name="b">Second input Vector</param>
|
||||
/// <param name="c">Third input Vector</param>
|
||||
/// <param name="u">First Barycentric Coordinate</param>
|
||||
/// <param name="v">Second Barycentric Coordinate</param>
|
||||
/// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
|
||||
public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
|
||||
{
|
||||
return a + u * (b - a) + v * (c - a);
|
||||
}
|
||||
|
||||
/// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
|
||||
/// <param name="a">First input Vector.</param>
|
||||
/// <param name="b">Second input Vector.</param>
|
||||
/// <param name="c">Third input Vector.</param>
|
||||
/// <param name="u">First Barycentric Coordinate.</param>
|
||||
/// <param name="v">Second Barycentric Coordinate.</param>
|
||||
/// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
|
||||
public static void BaryCentric( ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result )
|
||||
{
|
||||
result = a; // copy
|
||||
|
||||
Vector4 temp = b; // copy
|
||||
temp.Sub( ref a );
|
||||
temp.Mult( u );
|
||||
result.Add( ref temp );
|
||||
|
||||
temp = c; // copy
|
||||
temp.Sub( ref a );
|
||||
temp.Mult( v );
|
||||
result.Add( ref temp );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Transform
|
||||
|
||||
/// <summary>Transform a Vector by the given Matrix</summary>
|
||||
/// <param name="vec">The vector to transform</param>
|
||||
/// <param name="mat">The desired transformation</param>
|
||||
/// <returns>The transformed vector</returns>
|
||||
public static Vector4 Transform(Vector4 vec, Matrix4 mat)
|
||||
{
|
||||
Vector4 result;
|
||||
result.X = Vector4.Dot(vec, mat.Column0);
|
||||
result.Y = Vector4.Dot(vec, mat.Column1);
|
||||
result.Z = Vector4.Dot(vec, mat.Column2);
|
||||
result.W = Vector4.Dot(vec, mat.Column3);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Transform a Vector by the given Matrix</summary>
|
||||
/// <param name="vec">The vector to transform</param>
|
||||
/// <param name="mat">The desired transformation</param>
|
||||
/// <param name="result">The transformed vector</param>
|
||||
public static void Transform( ref Vector4 vec, ref Matrix4 mat, out Vector4 result )
|
||||
{
|
||||
result.X = vec.X * mat.Row0.X +
|
||||
vec.Y * mat.Row1.X +
|
||||
vec.Z * mat.Row2.X +
|
||||
vec.W * mat.Row3.X;
|
||||
|
||||
result.Y = vec.X * mat.Row0.Y +
|
||||
vec.Y * mat.Row1.Y +
|
||||
vec.Z * mat.Row2.Y +
|
||||
vec.W * mat.Row3.Y;
|
||||
|
||||
result.Z = vec.X * mat.Row0.Z +
|
||||
vec.Y * mat.Row1.Z +
|
||||
vec.Z * mat.Row2.Z +
|
||||
vec.W * mat.Row3.Z;
|
||||
|
||||
result.W = vec.X * mat.Row0.W +
|
||||
vec.Y * mat.Row1.W +
|
||||
vec.Z * mat.Row2.W +
|
||||
vec.W * mat.Row3.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Swizzle
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operators
|
||||
|
||||
public static Vector4 operator +(Vector4 left, Vector4 right)
|
||||
{
|
||||
left.X += right.X;
|
||||
left.Y += right.Y;
|
||||
left.Z += right.Z;
|
||||
left.W += right.W;
|
||||
return left;
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 left, Vector4 right)
|
||||
{
|
||||
left.X -= right.X;
|
||||
left.Y -= right.Y;
|
||||
left.Z -= right.Z;
|
||||
left.W -= right.W;
|
||||
return left;
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 vec)
|
||||
{
|
||||
vec.X = -vec.X;
|
||||
vec.Y = -vec.Y;
|
||||
vec.Z = -vec.Z;
|
||||
vec.W = -vec.W;
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Vector4 operator *(Vector4 vec, float f)
|
||||
{
|
||||
vec.X *= f;
|
||||
vec.Y *= f;
|
||||
vec.Z *= f;
|
||||
vec.W *= f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Vector4 operator *(float f, Vector4 vec)
|
||||
{
|
||||
vec.X *= f;
|
||||
vec.Y *= f;
|
||||
vec.Z *= f;
|
||||
vec.W *= f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Vector4 operator /(Vector4 vec, float f)
|
||||
{
|
||||
float mult = 1.0f / f;
|
||||
vec.X *= mult;
|
||||
vec.Y *= mult;
|
||||
vec.Z *= mult;
|
||||
vec.W *= mult;
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector4 left, Vector4 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector4 left, Vector4 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
unsafe public static explicit operator float*(Vector4 v)
|
||||
{
|
||||
return &v.X;
|
||||
}
|
||||
|
||||
public static explicit operator IntPtr(Vector4 v)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return (IntPtr)(&v.X);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String that represents the current Vector4.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override int GetHashCode()
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hashcode for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public override bool Equals(object obj)
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare to.</param>
|
||||
/// <returns>True if the instances are equal; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Vector4))
|
||||
return false;
|
||||
|
||||
return this.Equals((Vector4)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<Vector4> Members
|
||||
|
||||
/// <summary>Indicates whether the current vector is equal to another vector.</summary>
|
||||
/// <param name="other">A vector to compare with this vector.</param>
|
||||
/// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
|
||||
public bool Equals(Vector4 other)
|
||||
{
|
||||
return
|
||||
X == other.X &&
|
||||
Y == other.Y &&
|
||||
Z == other.Z &&
|
||||
W == other.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
1009
Source/Compatibility/Math/Vector4d.cs
Normal file
1009
Source/Compatibility/Math/Vector4d.cs
Normal file
File diff suppressed because it is too large
Load diff
414
Source/Compatibility/Math/Vector4h.cs
Normal file
414
Source/Compatibility/Math/Vector4h.cs
Normal file
|
@ -0,0 +1,414 @@
|
|||
#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.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace OpenTK.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// 4-component Vector of the Half type. Occupies 8 Byte total.
|
||||
/// </summary>
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector4h : ISerializable, IEquatable<Vector4h>
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>The X component of the Half4.</summary>
|
||||
public Half X;
|
||||
|
||||
/// <summary>The Y component of the Half4.</summary>
|
||||
public Half Y;
|
||||
|
||||
/// <summary>The Z component of the Half4.</summary>
|
||||
public Half Z;
|
||||
|
||||
/// <summary>The W component of the Half4.</summary>
|
||||
public Half W;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will avoid conversion and copy directly from the Half parameters.
|
||||
/// </summary>
|
||||
/// <param name="x">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="y">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="z">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
/// <param name="w">An Half instance of a 16-Bit half precision floating point number.</param>
|
||||
public Vector4h(Half x, Half y, Half z, Half w)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Z = z;
|
||||
this.W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the 4 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="z">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="w">32-Bit Single precision floating point number.</param>
|
||||
public Vector4h(Single x, Single y, Single z, Single w)
|
||||
{
|
||||
X = new Half(x);
|
||||
Y = new Half(y);
|
||||
Z = new Half(z);
|
||||
W = new Half(w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the 4 parameters into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="y">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="z">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="w">32-Bit Single precision floating point number.</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector4h(Single x, Single y, Single z, Single w, bool throwOnError)
|
||||
{
|
||||
X = new Half(x, throwOnError);
|
||||
Y = new Half(y, throwOnError);
|
||||
Z = new Half(z, throwOnError);
|
||||
W = new Half(w, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector4h(Vector4 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
W = new Half(v.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector4h(Vector4 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
W = new Half(v.W, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4 into 16-Bit Half precision floating point.
|
||||
/// This is the fastest constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4</param>
|
||||
public Vector4h(ref Vector4 v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
W = new Half(v.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4 into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector4h(ref Vector4 v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
W = new Half(v.W, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4d</param>
|
||||
public Vector4h(Vector4d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
W = new Half(v.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
public Vector4h(Vector4d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
W = new Half(v.W, throwOnError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4d into 16-Bit Half precision floating point.
|
||||
/// This is the faster constructor.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4d</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector4h(ref Vector4d v)
|
||||
{
|
||||
X = new Half(v.X);
|
||||
Y = new Half(v.Y);
|
||||
Z = new Half(v.Z);
|
||||
W = new Half(v.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The new Half4 instance will convert the Vector4d into 16-Bit Half precision floating point.
|
||||
/// </summary>
|
||||
/// <param name="v">OpenTK.Vector4d</param>
|
||||
/// <param name="throwOnError">Enable checks that will throw if the conversion result is not meaningful.</param>
|
||||
[CLSCompliant(false)]
|
||||
public Vector4h(ref Vector4d v, bool throwOnError)
|
||||
{
|
||||
X = new Half(v.X, throwOnError);
|
||||
Y = new Half(v.Y, throwOnError);
|
||||
Z = new Half(v.Z, throwOnError);
|
||||
W = new Half(v.W, throwOnError);
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Swizzle
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an OpenTK.Vector3h with the X, Y and Z components of this instance.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Vector3h Xyz { get { return new Vector3h(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Half -> Single
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half4 instance's contents as Vector4.
|
||||
/// </summary>
|
||||
/// <returns>OpenTK.Vector4</returns>
|
||||
public Vector4 ToVector4()
|
||||
{
|
||||
return new Vector4(X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this Half4 instance's contents as Vector4d.
|
||||
/// </summary>
|
||||
public Vector4d ToVector4d()
|
||||
{
|
||||
return new Vector4d(X, Y, Z, W);
|
||||
}
|
||||
|
||||
#endregion Half -> Single
|
||||
|
||||
#region Conversions
|
||||
|
||||
/// <summary>Converts OpenTK.Vector4 to OpenTK.Half4.</summary>
|
||||
/// <param name="v4f">The Vector4 to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector4h(Vector4 v4f)
|
||||
{
|
||||
return new Vector4h(v4f);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Vector4d to OpenTK.Half4.</summary>
|
||||
/// <param name="v4d">The Vector4d to convert.</param>
|
||||
/// <returns>The resulting Half vector.</returns>
|
||||
public static explicit operator Vector4h(Vector4d v4d)
|
||||
{
|
||||
return new Vector4h(v4d);
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half4 to OpenTK.Vector4.</summary>
|
||||
/// <param name="h4">The Half4 to convert.</param>
|
||||
/// <returns>The resulting Vector4.</returns>
|
||||
public static explicit operator Vector4(Vector4h h4)
|
||||
{
|
||||
Vector4 result = new Vector4();
|
||||
result.X = h4.X.ToSingle();
|
||||
result.Y = h4.Y.ToSingle();
|
||||
result.Z = h4.Z.ToSingle();
|
||||
result.W = h4.W.ToSingle();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Converts OpenTK.Half4 to OpenTK.Vector4d.</summary>
|
||||
/// <param name="h4">The Half4 to convert.</param>
|
||||
/// <returns>The resulting Vector4d.</returns>
|
||||
public static explicit operator Vector4d(Vector4h h4)
|
||||
{
|
||||
Vector4d result = new Vector4d();
|
||||
result.X = h4.X.ToSingle();
|
||||
result.Y = h4.Y.ToSingle();
|
||||
result.Z = h4.Z.ToSingle();
|
||||
result.W = h4.W.ToSingle();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion Conversions
|
||||
|
||||
#region Constants
|
||||
|
||||
/// <summary>The size in bytes for an instance of the Half4 struct is 8.</summary>
|
||||
public static readonly int SizeInBytes = 8;
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region ISerializable
|
||||
|
||||
/// <summary>Constructor used by ISerializable to deserialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public Vector4h(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
this.X = (Half)info.GetValue("X", typeof(Half));
|
||||
this.Y = (Half)info.GetValue("Y", typeof(Half));
|
||||
this.Z = (Half)info.GetValue("Z", typeof(Half));
|
||||
this.W = (Half)info.GetValue("W", typeof(Half));
|
||||
}
|
||||
|
||||
/// <summary>Used by ISerialize to serialize the object.</summary>
|
||||
/// <param name="info"></param>
|
||||
/// <param name="context"></param>
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("X", this.X);
|
||||
info.AddValue("Y", this.Y);
|
||||
info.AddValue("Z", this.Z);
|
||||
info.AddValue("W", this.W);
|
||||
}
|
||||
|
||||
#endregion ISerializable
|
||||
|
||||
#region Binary dump
|
||||
|
||||
/// <summary>Updates the X,Y,Z and W components of this instance by reading from a Stream.</summary>
|
||||
/// <param name="bin">A BinaryReader instance associated with an open Stream.</param>
|
||||
public void FromBinaryStream(BinaryReader bin)
|
||||
{
|
||||
X.FromBinaryStream(bin);
|
||||
Y.FromBinaryStream(bin);
|
||||
Z.FromBinaryStream(bin);
|
||||
W.FromBinaryStream(bin);
|
||||
}
|
||||
|
||||
/// <summary>Writes the X,Y,Z and W components of this instance into a Stream.</summary>
|
||||
/// <param name="bin">A BinaryWriter instance associated with an open Stream.</param>
|
||||
public void ToBinaryStream(BinaryWriter bin)
|
||||
{
|
||||
X.ToBinaryStream(bin);
|
||||
Y.ToBinaryStream(bin);
|
||||
Z.ToBinaryStream(bin);
|
||||
W.ToBinaryStream(bin);
|
||||
}
|
||||
|
||||
#endregion Binary dump
|
||||
|
||||
#region IEquatable<Half4> Members
|
||||
|
||||
/// <summary>Returns a value indicating whether this instance is equal to a specified OpenTK.Half4 vector.</summary>
|
||||
/// <param name="other">OpenTK.Half4 to compare to this instance..</param>
|
||||
/// <returns>True, if other is equal to this instance; false otherwise.</returns>
|
||||
public bool Equals(Vector4h other)
|
||||
{
|
||||
return (this.X.Equals(other.X) && this.Y.Equals(other.Y) && this.Z.Equals(other.Z) && this.W.Equals(other.W));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToString()
|
||||
|
||||
/// <summary>Returns a string that contains this Half4's numbers in human-legible form.</summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1}, {2}, {3})", X.ToString(), Y.ToString(), Z.ToString(), W.ToString());
|
||||
}
|
||||
|
||||
#endregion ToString()
|
||||
|
||||
#region BitConverter
|
||||
|
||||
/// <summary>Returns the Half4 as an array of bytes.</summary>
|
||||
/// <param name="h">The Half4 to convert.</param>
|
||||
/// <returns>The input as byte array.</returns>
|
||||
public static byte[] GetBytes(Vector4h h)
|
||||
{
|
||||
byte[] result = new byte[SizeInBytes];
|
||||
|
||||
byte[] temp = Half.GetBytes(h.X);
|
||||
result[0] = temp[0];
|
||||
result[1] = temp[1];
|
||||
temp = Half.GetBytes(h.Y);
|
||||
result[2] = temp[0];
|
||||
result[3] = temp[1];
|
||||
temp = Half.GetBytes(h.Z);
|
||||
result[4] = temp[0];
|
||||
result[5] = temp[1];
|
||||
temp = Half.GetBytes(h.W);
|
||||
result[6] = temp[0];
|
||||
result[7] = temp[1];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Converts an array of bytes into Half4.</summary>
|
||||
/// <param name="value">A Half4 in it's byte[] representation.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A new Half4 instance.</returns>
|
||||
public static Vector4h FromBytes(byte[] value, int startIndex)
|
||||
{
|
||||
Vector4h h4 = new Vector4h();
|
||||
h4.X = Half.FromBytes(value, startIndex);
|
||||
h4.Y = Half.FromBytes(value, startIndex + 2);
|
||||
h4.Z = Half.FromBytes(value, startIndex + 4);
|
||||
h4.W = Half.FromBytes(value, startIndex + 6);
|
||||
return h4;
|
||||
}
|
||||
|
||||
#endregion BitConverter
|
||||
}
|
||||
}
|
35
Source/Compatibility/Properties/AssemblyInfo.cs
Normal file
35
Source/Compatibility/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("The Open Toolkit Compatilibity library")]
|
||||
[assembly: AssemblyDescription("Provides compatibility with previous versions of OpenTK")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("The Open Toolkit Library")]
|
||||
[assembly: AssemblyProduct("The Open Toolkit Library")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006-2009 the Open Toolkit team")]
|
||||
[assembly: AssemblyTrademark("OpenTK")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("7c495044-4b1a-4bff-aee9-ff9dbf85433f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.9.9.2")]
|
||||
[assembly: AssemblyFileVersion("0.9.9.2")]
|
||||
|
||||
[assembly: System.CLSCompliant(true)]
|
Loading…
Reference in a new issue