diff --git a/source/OrkEngine3D.Annotations/OrkEngine3D.Annotations.csproj b/source/OrkEngine3D.Annotations/OrkEngine3D.Annotations.csproj index bb5862d..ec14c34 100644 --- a/source/OrkEngine3D.Annotations/OrkEngine3D.Annotations.csproj +++ b/source/OrkEngine3D.Annotations/OrkEngine3D.Annotations.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net7.0 diff --git a/source/OrkEngine3D.Common.Utils/AssetDatabase.cs b/source/OrkEngine3D.Common.Utils/AssetDatabase.cs deleted file mode 100644 index a94cca8..0000000 --- a/source/OrkEngine3D.Common.Utils/AssetDatabase.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public abstract class AssetDatabase -{ - public T LoadAsset(AssetID assetID) => LoadAsset(assetID, true); - public abstract T LoadAsset(AssetID assetID, bool cache); - - public T LoadAsset(AssetRef assetRef) => LoadAsset(assetRef, true); - public abstract T LoadAsset(AssetRef assetRef, bool cache); - - public object LoadAsset(AssetID assetID) => LoadAsset(assetID, true); - public abstract object LoadAsset(AssetID assetID, bool cache); - - public bool TryLoadAsset(AssetID assetID, out T asset) => TryLoadAsset(assetID, true, out asset); - public abstract bool TryLoadAsset(AssetID assetID, bool cache, out T asset); - - public abstract Stream OpenAssetStream(AssetID assetID); - - public abstract bool TryOpenAssetStream(AssetID assetID, out Stream stream); - - public abstract AssetID[] GetAssetsOfType(Type t); -} - -/* -public abstract class EditableAssetDatabase : AssetDatabase -{ - public abstract string GetAssetPath(AssetID assetID); - public abstract DirectoryNode GetRootDirectoryGraph(); - public abstract Type GetAssetType(AssetID assetID); - public abstract void CloneAsset(string path); - public abstract void DeleteAsset(string path); -} -*/ diff --git a/source/OrkEngine3D.Common.Utils/AssetDefinition.cs b/source/OrkEngine3D.Common.Utils/AssetDefinition.cs deleted file mode 100644 index 9906599..0000000 --- a/source/OrkEngine3D.Common.Utils/AssetDefinition.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public interface AssetDefinition -{ - object Create(AssetDatabase ad); -} - -public abstract class AssetDefinition : AssetDefinition -{ - public abstract T Create(AssetDatabase ad); - - object AssetDefinition.Create(AssetDatabase ad) - { - return Create(ad); - } -} diff --git a/source/OrkEngine3D.Common.Utils/AssetID.cs b/source/OrkEngine3D.Common.Utils/AssetID.cs deleted file mode 100644 index c528ea1..0000000 --- a/source/OrkEngine3D.Common.Utils/AssetID.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public struct AssetID : IEquatable -{ - private string _value; - public string Value { get { return _value; } set { _value = value; } } - - public bool IsEmpty => string.IsNullOrEmpty(_value); - - public AssetID(string value) - { - _value = value.Replace("\\", "/"); - } - - public bool Equals(AssetID other) - { - return other._value.Equals(_value); - } - - public override bool Equals(object obj) - { - return obj is AssetID && ((AssetID)(obj)).Equals(this); - } - - public override int GetHashCode() - { - return _value != null ? _value.GetHashCode() : 0; - } - - public override string ToString() - { - return $"ID:{_value}"; - } - - public static implicit operator AssetID(string s) => new AssetID(s); - public static implicit operator string(AssetID id) => id._value; -} diff --git a/source/OrkEngine3D.Common.Utils/AssetLoader.cs b/source/OrkEngine3D.Common.Utils/AssetLoader.cs deleted file mode 100644 index db2c0f8..0000000 --- a/source/OrkEngine3D.Common.Utils/AssetLoader.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public interface AssetLoader -{ - string FileExtension { get; } - object Load(Stream s); -} - -public interface AssetLoader : AssetLoader -{ - new TAsset Load(Stream s); -} - -public abstract class ConcreteLoader : AssetLoader -{ - public abstract string FileExtension { get; } - - public abstract T Load(Stream s); - - object AssetLoader.Load(Stream s) => Load(s); -} diff --git a/source/OrkEngine3D.Common.Utils/AssetRef.cs b/source/OrkEngine3D.Common.Utils/AssetRef.cs deleted file mode 100644 index 703f2e7..0000000 --- a/source/OrkEngine3D.Common.Utils/AssetRef.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public class AssetRef -{ - public AssetID ID { get; set; } - - public AssetRef(AssetID id) - { - ID = id; - } - - public AssetRef() - { - } -} diff --git a/source/OrkEngine3D.Common.Utils/CreatedResourceCache.cs b/source/OrkEngine3D.Common.Utils/CreatedResourceCache.cs deleted file mode 100644 index 5c44abf..0000000 --- a/source/OrkEngine3D.Common.Utils/CreatedResourceCache.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - MIT License - -Copyright (c) 2022 OrkEngine - -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. -*/ - -namespace OrkEngine3D.Common.Utils; - -public static class CreatedResourceCache -{ - private static readonly Dictionary s_cache = new Dictionary(); - public static void ClearCache() => s_cache.Clear(); - - public static bool TryGetCachedItem(TKey key, out TValue value) - { - object fromCache; - if (!s_cache.TryGetValue(key, out fromCache)) - { - value = default(TValue); - return false; - } - else - { - value = (TValue)fromCache; - return true; - } - } - - public static void CacheItem(TKey key, TValue value) - { - s_cache.Add(key, value); - } -} diff --git a/source/OrkEngine3D.Common.Utils/OrkEngine3D.Common.Utils.csproj b/source/OrkEngine3D.Common.Utils/OrkEngine3D.Common.Utils.csproj deleted file mode 100644 index aa63f9f..0000000 --- a/source/OrkEngine3D.Common.Utils/OrkEngine3D.Common.Utils.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Library - net6.0 - enable - enable - - - diff --git a/source/OrkEngine3D.Components.Tests/OrkEngine3D.Components.Tests.csproj b/source/OrkEngine3D.Components.Tests/OrkEngine3D.Components.Tests.csproj index 41f1d5a..120e38c 100644 --- a/source/OrkEngine3D.Components.Tests/OrkEngine3D.Components.Tests.csproj +++ b/source/OrkEngine3D.Components.Tests/OrkEngine3D.Components.Tests.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 diff --git a/source/OrkEngine3D.Core/Components/Transform.cs b/source/OrkEngine3D.Core/Components/Transform.cs index aa9dc29..dee3176 100644 --- a/source/OrkEngine3D.Core/Components/Transform.cs +++ b/source/OrkEngine3D.Core/Components/Transform.cs @@ -364,7 +364,7 @@ private void OnParentRotationChanged(Quaternion oldParentRot, Quaternion newPare Quaternion diff = Quaternion.Concatenate(Quaternion.Inverse(oldParentRot), newParentRot); _physicsEntity.Orientation = Quaternion.Concatenate(_physicsEntity.BufferedStates.InterpolatedStates.Orientation, diff); Vector3 basisDirection = Vector3.Transform(GetInterpolatedPosition() - _parent.Position, Quaternion.Inverse(oldRot)); - float distance = basisDirection.Length(); + float distance = basisDirection.Length; Vector3 newDirection = Vector3.Transform(basisDirection, newParentRot); if (newDirection != Vector3.Zero) { diff --git a/source/OrkEngine3D.Core/OrkEngine3D.Core.csproj b/source/OrkEngine3D.Core/OrkEngine3D.Core.csproj index 82b0e1b..5aa4374 100644 --- a/source/OrkEngine3D.Core/OrkEngine3D.Core.csproj +++ b/source/OrkEngine3D.Core/OrkEngine3D.Core.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net7.0 @@ -13,8 +13,7 @@ - - + diff --git a/source/OrkEngine3D.Diagnostics/OrkEngine3D.Diagnostics.csproj b/source/OrkEngine3D.Diagnostics/OrkEngine3D.Diagnostics.csproj index 9c48cdd..15edc6c 100644 --- a/source/OrkEngine3D.Diagnostics/OrkEngine3D.Diagnostics.csproj +++ b/source/OrkEngine3D.Diagnostics/OrkEngine3D.Diagnostics.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net7.0 OrkEngine3D.Diagnostics diff --git a/source/OrkEngine3D.Graphics.Tests/OrkEngine3D.Graphics.Tests.csproj b/source/OrkEngine3D.Graphics.Tests/OrkEngine3D.Graphics.Tests.csproj index 5aa07ee..d72b0d8 100644 --- a/source/OrkEngine3D.Graphics.Tests/OrkEngine3D.Graphics.Tests.csproj +++ b/source/OrkEngine3D.Graphics.Tests/OrkEngine3D.Graphics.Tests.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 @@ -16,7 +16,7 @@ - + diff --git a/source/OrkEngine3D.Graphics.Tests/Program.cs b/source/OrkEngine3D.Graphics.Tests/Program.cs index 107d853..7178afd 100644 --- a/source/OrkEngine3D.Graphics.Tests/Program.cs +++ b/source/OrkEngine3D.Graphics.Tests/Program.cs @@ -2,151 +2,730 @@ using OrkEngine3D.Graphics.MeshData; using OrkEngine3D.Graphics.TK; using OrkEngine3D.Graphics.TK.Resources; -using OrkEngine3D.Mathematics; +//using OrkEngine3D.Mathematics; using System; using System.IO; using System.Linq; -using Mesh = OrkEngine3D.Graphics.TK.Resources.Mesh; +//using Mesh = OrkEngine3D.Graphics.TK.Resources.Mesh; using Material = OrkEngine3D.Graphics.TK.Material; +using OrkEngine3D.Core.Components; +using OpenTK.Windowing.GraphicsLibraryFramework; +using OpenTK.Windowing.Common; +using System.Collections.Generic; +using OpenTK.Graphics.OpenGL4; +using OpenTK.Mathematics; //using OrkEngine3D.Components; -namespace OrkEngine3D.Graphics.Tests +namespace OrkEngine3D.Graphics.Tests; + +class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Logger logger = new Logger("MainLogger", "NoModule"); - logger.Log(LogMessageType.DEBUG, "Teapot"); + Logger logger = new Logger("MainLogger", "NoModule"); + logger.Log(LogMessageType.DEBUG, "Teapot"); - //GraphicsContext ctx = new GraphicsContext("Hello World", new TestHandler()); - //ctx.Run(); - } + GContext ctx = new GContext("Hello World", new TestHandler()); + ctx.Run(); } - +} +class TestHandler : GraphicsBehaviour +{ + private readonly float[] _vertices = + { + // Positions Normals Texture coords + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f + }; + + private readonly Vector3[] _cubePositions = + { + new Vector3(0.0f, 0.0f, 0.0f), + new Vector3(2.0f, 5.0f, -15.0f), + new Vector3(-1.5f, -2.2f, -2.5f), + new Vector3(-3.8f, -2.0f, -12.3f), + new Vector3(2.4f, -0.4f, -3.5f), + new Vector3(-1.7f, 3.0f, -7.5f), + new Vector3(1.3f, -2.0f, -2.5f), + new Vector3(1.5f, 2.0f, -2.5f), + new Vector3(1.5f, 0.2f, -1.5f), + new Vector3(-1.3f, 1.0f, -1.5f) + }; + + // We need the point lights' positions to draw the lamps and to get light the materials properly + private readonly Vector3[] _pointLightPositions = + { + new Vector3(0.7f, 0.2f, 2.0f), + new Vector3(2.3f, -3.3f, -4.0f), + new Vector3(-4.0f, 2.0f, -12.0f), + new Vector3(0.0f, 0.0f, -3.0f) + }; /* - - class TestHandler : GraphicsHandler + // The vertices are now used to draw cubes. + // For this example, we aren't using texture coordinates. + // You can use textures with lighting (and we will get onto this), but for simplicity's sake, we'll just use a solid color here + private readonly float[] _vertices = { - Logger logger = new Logger("GraphicsTest", "TestHandler"); - ID fshader; - ID vshader; - ID program; - Camera camera; + // Position + -0.5f, -0.5f, -0.5f, // Front face + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + + -0.5f, -0.5f, 0.5f, // Back face + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + + -0.5f, 0.5f, 0.5f, // Left face + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + 0.5f, 0.5f, 0.5f, // Right face + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + + -0.5f, -0.5f, -0.5f, // Bottom face + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, -0.5f, + + -0.5f, 0.5f, -0.5f, // Top face + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, -0.5f + }; + */ + /* plane + private readonly float[] _vertices = + { + // Position Texture coordinates + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left + -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left + }; + + private readonly uint[] _indices = + { + 0, 1, 3, + 1, 2, 3 + }; + */ + Logger logger = new Logger("GraphicsTest", "TestHandler"); + private readonly Vector3 _lightPos = new Vector3(1.2f, 1.0f, 2.0f); + //private int _elementBufferObject; + private int _vertexBufferObject; + //private int _vertexArrayObject; + private int _vaoModel; + private int _vaoLamp; + private Shader _lampShader; + private Shader _lightingShader; + //private Shader _shader; + private Texture _diffuseMap; + private Texture _specularMap; + + //ID fshader; + //ID vshader; + //ID program; + Camera _camera; + private bool _firstMove = true; + private Vector2 _lastPos; + private double _time; + //public float speed = 5; + //ShaderProgram shader; + + //LightScene lscene; + + //Transform cubeTransform; + //Transform teapotTransform; + + //ID cubeMesh; + //ID teapotMesh; + //private ID shadowManager; + public override void OnLoad() + { + GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); - LightScene lscene; + GL.Enable(EnableCap.DepthTest); - Transform cubeTransform; - Transform teapotTransform; + _vertexBufferObject = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject); + GL.BufferData(BufferTarget.ArrayBuffer, _vertices.Length * sizeof(float), _vertices, BufferUsageHint.StaticDraw); + + // Load the two different shaders, they use the same vertex shader program. However they have two different fragment shaders. + // This is because the lamp only uses a basic shader to turn it white, it wouldn't make sense to have the lamp lit in other colors. + // The lighting shaders uses the lighting.frag shader which is what a large part of this chapter will be about + _lightingShader = new Shader("resources/shaders/shader.vert", "resources/shaders/lighting.frag"); + _lampShader = new Shader("resources/shaders/shader.vert", "resources/shaders/shader.frag"); - ID cubeMesh; - ID teapotMesh; - private ID shadowManager; - public override void Init() { + _vaoModel = GL.GenVertexArray(); + GL.BindVertexArray(_vaoModel); + + // All of the vertex attributes have been updated to now have a stride of 8 float sizes. + var positionLocation = _lightingShader.GetAttribLocation("aPos"); + GL.EnableVertexAttribArray(positionLocation); + GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0); + + var normalLocation = _lightingShader.GetAttribLocation("aNormal"); + GL.EnableVertexAttribArray(normalLocation); + GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float)); + + // The texture coords have now been added too, remember we only have 2 coordinates as the texture is 2d, + // so the size parameter should only be 2 for the texture coordinates. + var texCoordLocation = _lightingShader.GetAttribLocation("aTexCoords"); + GL.EnableVertexAttribArray(texCoordLocation); + GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float)); + } + + { + _vaoLamp = GL.GenVertexArray(); + GL.BindVertexArray(_vaoLamp); + + // The lamp shader should have its stride updated aswell, however we dont actually + // use the texture coords for the lamp, so we dont need to add any extra attributes. + var positionLocation = _lampShader.GetAttribLocation("aPos"); + GL.EnableVertexAttribArray(positionLocation); + GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0); + } + + // Our two textures are loaded in from memory, you should head over and + // check them out and compare them to the results. + _diffuseMap = Texture.LoadFromFile("resources/container2.png"); + _specularMap = Texture.LoadFromFile("resources/container2_specular.png"); + + _camera = new Camera(Vector3.UnitZ * 3, Size.X / (float)Size.Y); + + CursorState = CursorState.Grabbed; + //shader = new ShaderProgram(); + //Rendering.BindContext(context); + //Rendering.BindResourceManager(resourceManager); + + + + //fshader = Rendering.CreateShader(File.ReadAllText("resources/shader.frag"), TK.Resources.ShaderType.FragmentShader); + //vshader = Rendering.CreateShader(File.ReadAllText("resources/shader.vert"), TK.Resources.ShaderType.VertexShader); + //shadowManager = Rendering.CreateShadowManager(); + + //program = Rendering.CreateShaderProgram(vshader, fshader); + + //cubeMesh = Rendering.CreateMesh(); - Rendering.BindContext(context); - Rendering.BindResourceManager(resourceManager); - - - fshader = Rendering.CreateShader( File.ReadAllText("resources/shader.frag"), ShaderType.FragmentShader); - vshader = Rendering.CreateShader(File.ReadAllText("resources/shader.vert"), ShaderType.VertexShader); - shadowManager = Rendering.CreateShadowManager(); - program = Rendering.CreateShaderProgram(vshader, fshader); + //Color3 white = new Color3(1f, 1f, 1f); + //ObjComplete voxelInformation = ObjLoader.LoadObjFromFile("resources/scene.obj");//new ObjComplete(VoxelData.GenerateVoxelInformation(), new Material[] { new Material() }); + //voxelInformation.materials[0].textures = new ID[] {Rendering.CreateTexture(Texture.GetTextureDataFromFile("resources/wod.png"))}; + //Rendering.BindMaterials(voxelInformation.materials); + + //Rendering.UpdateMeshVerticies(cubeMesh, voxelInformation.meshInformation.verticies); + //Rendering.UpdateMeshUVs(cubeMesh, voxelInformation.meshInformation.uv); + //Rendering.UpdateMeshNormals(cubeMesh, voxelInformation.meshInformation.normals); + //Rendering.UpdateMeshMaterials(cubeMesh, voxelInformation.meshInformation.materials); + //Rendering.UpdateMeshTriangles(cubeMesh, voxelInformation.meshInformation.triangles); + //Rendering.UpdateMeshShader(cubeMesh, program); + + //Rendering.UpdateMeshGLData(cubeMesh); + + //cubeTransform = new Transform(); + + //cubeTransform.position.Z = -0.5f; + //cubeTransform.position.Y = 0f; + + //camera = new Camera(Vector3.UnitZ * 3, Size.X / (float)Size.Y); + //camera.perspective = true; + + //Rendering.BindCamera(camera); + + //lscene = new LightScene(); + //Rendering.BindLightning(lscene); + //Rendering.BindShadowManager(shadowManager); + + //cubeTransform.position.Z = -3f; + //cubeTransform.position.Y = -3f; + //cubeTransform.Rotate(Vector3.UnitX * 45); + + } - cubeMesh = Rendering.CreateMesh(); + public override void OnRender(FrameEventArgs e) + { + _time += 4.0 * e.Time; - Color3 white = new Color3(1f, 1f, 1f); - ObjComplete voxelInformation = ObjLoader.LoadObjFromFile("resources/scene.obj");//new ObjComplete(VoxelData.GenerateVoxelInformation(), new Material[] { new Material() }); - voxelInformation.materials[0].textures = new ID[] {Rendering.CreateTexture(Texture.GetTextureDataFromFile("resources/wod.png"))}; - Rendering.BindMaterials(voxelInformation.materials); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - Rendering.UpdateMeshVerticies(cubeMesh, voxelInformation.meshInformation.verticies); - Rendering.UpdateMeshUVs(cubeMesh, voxelInformation.meshInformation.uv); - Rendering.UpdateMeshNormals(cubeMesh, voxelInformation.meshInformation.normals); - Rendering.UpdateMeshMaterials(cubeMesh, voxelInformation.meshInformation.materials); - Rendering.UpdateMeshTriangles(cubeMesh, voxelInformation.meshInformation.triangles); - Rendering.UpdateMeshShader(cubeMesh, program); + GL.BindVertexArray(_vaoModel); - Rendering.UpdateMeshGLData(cubeMesh); + _diffuseMap.Use(TextureUnit.Texture0); + _specularMap.Use(TextureUnit.Texture1); + _lightingShader.Use(); - cubeTransform = new Transform(); + _lightingShader.SetMatrix4("view", _camera.GetViewMatrix()); + _lightingShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); - cubeTransform.position.Z = -0.5f; - cubeTransform.position.Y = 0f; + _lightingShader.SetVector3("viewPos", _camera.Position); - camera = new Camera(); - camera.perspective = true; + _lightingShader.SetInt("material.diffuse", 0); + _lightingShader.SetInt("material.specular", 1); + _lightingShader.SetVector3("material.specular", new Vector3(0.5f, 0.5f, 0.5f)); + _lightingShader.SetFloat("material.shininess", 32.0f); - Rendering.BindCamera(camera); + /* + Here we set all the uniforms for the 5/6 types of lights we have. We have to set them manually and index + the proper PointLight struct in the array to set each uniform variable. This can be done more code-friendly + by defining light types as classes and set their values in there, or by using a more efficient uniform approach + by using 'Uniform buffer objects', but that is something we'll discuss in the 'Advanced GLSL' tutorial. + */ + // Directional light + _lightingShader.SetVector3("dirLight.direction", new Vector3(-0.2f, -1.0f, -0.3f)); + _lightingShader.SetVector3("dirLight.ambient", new Vector3(0.05f, 0.05f, 0.05f)); + _lightingShader.SetVector3("dirLight.diffuse", new Vector3(0.4f, 0.4f, 0.4f)); + _lightingShader.SetVector3("dirLight.specular", new Vector3(0.5f, 0.5f, 0.5f)); - lscene = new LightScene(); - Rendering.BindLightning(lscene); - Rendering.BindShadowManager(shadowManager); + // Point lights + for (int i = 0; i < _pointLightPositions.Length; i++) + { + _lightingShader.SetVector3($"pointLights[{i}].position", _pointLightPositions[i]); + _lightingShader.SetVector3($"pointLights[{i}].ambient", new Vector3(0.05f, 0.05f, 0.05f)); + _lightingShader.SetVector3($"pointLights[{i}].diffuse", new Vector3(0.8f, 0.8f, 0.8f)); + _lightingShader.SetVector3($"pointLights[{i}].specular", new Vector3(1.0f, 1.0f, 1.0f)); + _lightingShader.SetFloat($"pointLights[{i}].constant", 1.0f); + _lightingShader.SetFloat($"pointLights[{i}].linear", 0.09f); + _lightingShader.SetFloat($"pointLights[{i}].quadratic", 0.032f); + } - cubeTransform.position.Z = -3f; - cubeTransform.position.Y = -3f; - cubeTransform.Rotate(Vector3.UnitX * 45); + // Spot light + _lightingShader.SetVector3("spotLight.position", _camera.Position); + _lightingShader.SetVector3("spotLight.direction", _camera.Front); + _lightingShader.SetVector3("spotLight.ambient", new Vector3(0.0f, 0.0f, 0.0f)); + _lightingShader.SetVector3("spotLight.diffuse", new Vector3(1.0f, 1.0f, 1.0f)); + _lightingShader.SetVector3("spotLight.specular", new Vector3(1.0f, 1.0f, 1.0f)); + _lightingShader.SetFloat("spotLight.constant", 1.0f); + _lightingShader.SetFloat("spotLight.linear", 0.09f); + _lightingShader.SetFloat("spotLight.quadratic", 0.032f); + _lightingShader.SetFloat("spotLight.cutOff", Mathematics.MathF.Cos(MathHelper.DegreesToRadians(12.5f))); + _lightingShader.SetFloat("spotLight.outerCutOff", Mathematics.MathF.Cos(MathHelper.DegreesToRadians(17.5f))); + + for (int i = 0; i < _cubePositions.Length; i++) + { + Matrix4 model = Matrix4.CreateTranslation(_cubePositions[i]); + float angle = 20.0f * i; + model = model * Matrix4.CreateFromAxisAngle(new Vector3(1.0f, 0.3f, 0.5f), angle); + _lightingShader.SetMatrix4("model", model); + GL.DrawArrays(PrimitiveType.Triangles, 0, 36); } - public override void Render() + GL.BindVertexArray(_vaoLamp); + + _lampShader.Use(); + + _lampShader.SetMatrix4("view", _camera.GetViewMatrix()); + _lampShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); + // We use a loop to draw all the lights at the proper position + for (int i = 0; i < _pointLightPositions.Length; i++) { - Rendering.BindTransform(cubeTransform); - Rendering.BindRenderable(cubeMesh); - - //Rendering.EnterShadowMode(); - //Rendering.Render(); - - Rendering.ResetTarget(); - Rendering.ClearTarget(); - Rendering.Render(); + Matrix4 lampMatrix = Matrix4.CreateScale(0.2f); + lampMatrix = lampMatrix * Matrix4.CreateTranslation(_pointLightPositions[i]); + + _lampShader.SetMatrix4("model", lampMatrix); + + GL.DrawArrays(PrimitiveType.Triangles, 0, 36); + } + + SwapBuffers(); + //Rendering.BindTransform(cubeTransform); + //Rendering.BindRenderable(cubeMesh); + + //Rendering.EnterShadowMode(); + //Rendering.OnRender(); + + //Rendering.ResetTarget(); + //Rendering.ClearTarget(); + //Rendering.Render(); + + //Rendering.BindTransform(teapotTransform); + //teapotMesh.OnRender(); - //Rendering.BindTransform(teapotTransform); - //teapotMesh.Render(); + //Rendering.SwapBuffers(); + } - Rendering.SwapBuffers(); + //float t = 0; + public override void OnUpdate(FrameEventArgs e) + { + if (!IsFocused) // Check to see if the window is focused + { + return; } - float t = 0; - public override void Update() + var input = KeyboardState; + + if (input.IsKeyDown(Keys.Escape)) { - t += context.deltaTime; + Close(); + } + const float cameraSpeed = 1.5f; + const float sensitivity = 0.2f; - //teapotTransform.position.Z = -3f; - //teapotTransform.Rotate(Vector3.UnitX * context.deltaTime); + if (input.IsKeyDown(Keys.W)) + { + _camera.Position += _camera.Front * cameraSpeed * (float)e.Time; // Forward + } + + if (input.IsKeyDown(Keys.S)) + { + _camera.Position -= _camera.Front * cameraSpeed * (float)e.Time; // Backwards + } + if (input.IsKeyDown(Keys.A)) + { + _camera.Position -= _camera.Right * cameraSpeed * (float)e.Time; // Left + } + if (input.IsKeyDown(Keys.D)) + { + _camera.Position += _camera.Right * cameraSpeed * (float)e.Time; // Right + } + if (input.IsKeyDown(Keys.Space)) + { + _camera.Position += _camera.Up * cameraSpeed * (float)e.Time; // Up + } + if (input.IsKeyDown(Keys.LeftShift)) + { + _camera.Position -= _camera.Up * cameraSpeed * (float)e.Time; // Down + } + // Get the mouse state + var mouse = MouseState; - while (context.nonQueriedKeys.Count > 0) + if (_firstMove) // This bool variable is initially set to true. + { + _lastPos = new Vector2(mouse.X, mouse.Y); + _firstMove = false; + } + else + { + // Calculate the offset of the mouse position + var deltaX = mouse.X - _lastPos.X; + var deltaY = mouse.Y - _lastPos.Y; + _lastPos = new Vector2(mouse.X, mouse.Y); + + // Apply the camera pitch and yaw (we clamp the pitch in the camera class) + _camera.Yaw += deltaX * sensitivity; + _camera.Pitch -= deltaY * sensitivity; // Reversed since y-coordinates range from bottom to top + } + /* + t += context.deltaTime; + + //Rendering.currentCamera.transform.position = new Vector3(t, t, t); + //teapotTransform.position.Z = -3f; + //teapotTransform.Rotate(Vector3.UnitX * context.deltaTime); + var fpsString = "FPS="; + var fps = (1000 / context.deltaTime); + + bool isRaw = false; + bool isDebug = false; + //Remember to comment this out (he didn't) + //Rendering.currentCamera.transform.position = new Vector3((float)e.Time, (float)e.Time, (float)e.Time); + const float cameraSpeed = 1.5f; + const float sensitivity = 0.2f; + Logger.Get("MainLogger").Log(LogMessageType.DEBUG, $"Keyboard: {e.Time}"); + + if (fps >= 120) + { + if (isRaw) { - KeyEvent e = context.nonQueriedKeys.Dequeue(); - //Logger.Get("MainLogger").Log(LogMessageType.DEBUG, $"Keyboard: {e.eventType.ToString()}, {e.key.ToString()}"); - - if (e.key == Key.Q && e.eventType == KeyEventType.KeyDown) - { - Rendering.EnableWireframe(); - } - if (e.key == Key.E && e.eventType == KeyEventType.KeyDown) - { - Rendering.DisableWireframe(); - } + fpsString = $"FPS=~{fps}"; } + else + { + if (fps >= 1200) + fpsString = "FPS=~120"; + } } - - public override void Resize() + else if (fps >= 90 && fps <= 120) { - logger.Log(LogMessageType.INFORMATION, "Resize event"); + fpsString = "FPS=~90"; } + else if (fps >= 60 && fps <= 90) + { + fpsString = "FPS=~60"; + } + else if (fps >= 30 && fps >= 60) + { + fpsString = "FPS=~30"; + } + + //var counter = 0; + + //if (counter >= 20) + //{ + // for (var i = 0; i < counter; i++) + // counter++; + if (isDebug) + Console.WriteLine(fpsString); + //Thread.Sleep(250); + // } + //Rendering.currentCamera.transform.position.X += (float)e.Time; + + while (context.nonQueriedKeys.Count > 0) + { + KeyEvent keyEvent = context.nonQueriedKeys.Dequeue();//GContext.Local.Keys; + //Logger.Get("MainLogger").Log(LogMessageType.DEBUG, $"Keyboard: {e.eventType.ToString()}, {e.Key.ToString()}"); + // if (keyEvent.GetKeyDown(Key.Q)) + // { + // Rendering.EnableWireframe(); + // } + + // if (keyEvent.GetKeyDown(Key.E)) //if (e.Key == Key.E && e.GetKeyDown(Key.E)) + // { + //Rendering.DisableWireframe(); + // } + if (keyEvent.GetKeyDown(Key.W)) + { + //Rendering.currentCamera.Position -= cameraSpeed * (float)e.Time; + } + if (keyEvent.GetKeyDown(Key.S)) + { + //Rendering.currentCamera.transform.position.Z += cameraSpeed * (float)e.Time; + } + if (keyEvent.GetKeyDown(Key.A)) + { + //Rendering.currentCamera.transform.position.X += cameraSpeed * (float)e.Time; + } + if (keyEvent.GetKeyDown(Key.D)) + { + // Rendering.currentCamera.transform.position.X -= cameraSpeed * (float)e.Time; + } + if (keyEvent.GetKeyDown(Key.Space)) + { + //Rendering.currentCamera.transform.position.Y += cameraSpeed * (float)e.Time; + } + if (keyEvent.GetKeyDown(Key.LeftShift)) + { + // Rendering.currentCamera.transform.position.Y -= cameraSpeed * (float)e.Time; + } + }*/ + } + + public override void OnMouseWheel(MouseWheelEventArgs e) + { + // camera.Fov -= e.OffsetY; + // Rendering.currentCamera.fov -= e.OffsetY; + _camera.Fov -= e.OffsetY; + } + + public override void OnResize(ResizeEventArgs args) + { + logger.Log(LogMessageType.INFORMATION, "OnResize event"); + //camera.AspectRatio = Size.X / (float)Size.Y; + GL.Viewport(0, 0, Size.X, Size.Y); + // We need to update the aspect ratio once the window has been resized. + _camera.AspectRatio = Size.X / (float)Size.Y; + } + + public override void OnUnload() + { + logger.Log(LogMessageType.INFORMATION, "OnUnload event"); + } + + public uint cubeMapTextures = LoadCubemap(new List() + { + "right.jpg", + "left.jpg", + "top.jpg", + "bottom.jpg", + "front.jpg", + "back.jpg" + }); + + public static uint LoadCubemap(List faces) + { + uint textureID; + + //GL.TextureParameter() + return 0; + } +} + + +/* +class TestHandler : GraphicsBehaviour +{ + Logger logger = new Logger("GraphicsTest", "TestHandler"); + ID fshader; + ID vshader; + ID program; + Camera camera; + + LightScene lscene; - public override void Unload() + Transform cubeTransform; + Transform teapotTransform; + + ID cubeMesh; + ID teapotMesh; + private ID shadowManager; + public override void Init() + { + + Rendering.BindContext(context); + Rendering.BindResourceManager(resourceManager); + + fshader = Rendering.CreateShader( File.ReadAllText("resources/shader.frag"), ShaderType.FragmentShader); + vshader = Rendering.CreateShader(File.ReadAllText("resources/shader.vert"), ShaderType.VertexShader); + shadowManager = Rendering.CreateShadowManager(); + + program = Rendering.CreateShaderProgram(vshader, fshader); + + cubeMesh = Rendering.CreateMesh(); + + Color3 white = new Color3(1f, 1f, 1f); + ObjComplete voxelInformation = ObjLoader.LoadObjFromFile("resources/scene.obj");//new ObjComplete(VoxelData.GenerateVoxelInformation(), new Material[] { new Material() }); + voxelInformation.materials[0].textures = new ID[] {Rendering.CreateTexture(Texture.GetTextureDataFromFile("resources/wod.png"))}; + Rendering.BindMaterials(voxelInformation.materials); + + Rendering.UpdateMeshVerticies(cubeMesh, voxelInformation.meshInformation.verticies); + Rendering.UpdateMeshUVs(cubeMesh, voxelInformation.meshInformation.uv); + Rendering.UpdateMeshNormals(cubeMesh, voxelInformation.meshInformation.normals); + Rendering.UpdateMeshMaterials(cubeMesh, voxelInformation.meshInformation.materials); + Rendering.UpdateMeshTriangles(cubeMesh, voxelInformation.meshInformation.triangles); + Rendering.UpdateMeshShader(cubeMesh, program); + + Rendering.UpdateMeshGLData(cubeMesh); + + cubeTransform = new Transform(); + + cubeTransform.position.Z = -0.5f; + cubeTransform.position.Y = 0f; + + camera = new Camera(); + camera.perspective = true; + + Rendering.BindCamera(camera); + + lscene = new LightScene(); + Rendering.BindLightning(lscene); + Rendering.BindShadowManager(shadowManager); + + cubeTransform.position.Z = -3f; + cubeTransform.position.Y = -3f; + cubeTransform.Rotate(Vector3.UnitX * 45); + + } + + public override void Render() + { + Rendering.BindTransform(cubeTransform); + Rendering.BindRenderable(cubeMesh); + + //Rendering.EnterShadowMode(); + //Rendering.Render(); + + Rendering.ResetTarget(); + Rendering.ClearTarget(); + Rendering.Render(); + + //Rendering.BindTransform(teapotTransform); + //teapotMesh.Render(); + + Rendering.SwapBuffers(); + } + + float t = 0; + public override void Update() + { + t += context.deltaTime; + + + //teapotTransform.position.Z = -3f; + //teapotTransform.Rotate(Vector3.UnitX * context.deltaTime); + + + while (context.nonQueriedKeys.Count > 0) { - logger.Log(LogMessageType.INFORMATION, "Unload event"); + KeyEvent e = context.nonQueriedKeys.Dequeue(); + //Logger.Get("MainLogger").Log(LogMessageType.DEBUG, $"Keyboard: {e.eventType.ToString()}, {e.key.ToString()}"); + + //FreeCamera camera = new FreeCamera(); + //camera.Update(e); + + + if (e.key == Key.Q && e.eventType == KeyEventType.KeyDown) + { + Rendering.EnableWireframe(); + } + if (e.key == Key.E && e.eventType == KeyEventType.KeyDown) + { + Rendering.DisableWireframe(); + } + + + } } - */ + public override void Resize() + { + logger.Log(LogMessageType.INFORMATION, "Resize event"); + } + + public override void Unload() + { + logger.Log(LogMessageType.INFORMATION, "Unload event"); + } } +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/awesomeface.png b/source/OrkEngine3D.Graphics.Tests/resources/awesomeface.png new file mode 100644 index 0000000..abb680c Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/awesomeface.png differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/back.jpg b/source/OrkEngine3D.Graphics.Tests/resources/back.jpg new file mode 100644 index 0000000..f766a76 Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/back.jpg differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/bottom.jpg b/source/OrkEngine3D.Graphics.Tests/resources/bottom.jpg new file mode 100644 index 0000000..83969d4 Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/bottom.jpg differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/container.png b/source/OrkEngine3D.Graphics.Tests/resources/container.png new file mode 100644 index 0000000..45307af Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/container.png differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/container2.png b/source/OrkEngine3D.Graphics.Tests/resources/container2.png new file mode 100644 index 0000000..596e8da Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/container2.png differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/container2_specular.png b/source/OrkEngine3D.Graphics.Tests/resources/container2_specular.png new file mode 100644 index 0000000..681bf6e Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/container2_specular.png differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/front.jpg b/source/OrkEngine3D.Graphics.Tests/resources/front.jpg new file mode 100644 index 0000000..fb78775 Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/front.jpg differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/left.jpg b/source/OrkEngine3D.Graphics.Tests/resources/left.jpg new file mode 100644 index 0000000..9694b8a Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/left.jpg differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/right.jpg b/source/OrkEngine3D.Graphics.Tests/resources/right.jpg new file mode 100644 index 0000000..78961d5 Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/right.jpg differ diff --git a/source/OrkEngine3D.Graphics.Tests/resources/shader2.frag b/source/OrkEngine3D.Graphics.Tests/resources/shader2.frag new file mode 100644 index 0000000..3c1978c --- /dev/null +++ b/source/OrkEngine3D.Graphics.Tests/resources/shader2.frag @@ -0,0 +1,110 @@ +#version 400 core +out vec4 FragColor; + +in vec3 Normal; +in vec2 fUV; +in vec3 Pos; +in vec4 lightFragPos; +flat in int mat; + +uniform vec3 camera_pos; + +struct Light{ + float strength; + vec3 color; + vec3 position; +}; + + +uniform Light ambient; +uniform Light lights[256]; +uniform int lights_count; + +struct Material { + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float shininess; +}; + +uniform Material materials[8]; + +uniform sampler2D material_textures[8 * 4]; + +Material GetMaterial(int m){ + Material material = materials[m]; + return material; +} + +int GetTextureID(int m, int t){ + return m * 16 + t; +} + +vec3 CalculateAmbientLightning(Light l, Material material){ + return (l.color * l.strength) * material.ambient; +} + +vec3 CalculateDiffuseLightning(Light l, Material material){ + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(l.position - Pos); + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = (l.color * l.strength) * (diff * material.diffuse); + return diffuse; +} + +vec3 CalculateSpecularLightning(Light l, Material material, vec3 norm){ + vec3 lightDir = normalize(l.position - Pos); + + vec3 viewDir = normalize(camera_pos - Pos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + vec3 specular = (l.color * l.strength) * (spec * material.specular); + return specular; +} + +vec3 CombineLightning(vec3 ambient, vec3 diffuse, vec3 specular, vec3 objcolor){ + return (ambient + diffuse + specular) * objcolor; +} + +uniform sampler2D material_shadowMap; + +float ShadowCalculation(vec4 fragPosLightSpace) +{ + vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; + projCoords = projCoords * 0.5 + 0.5; + float closestDepth = texture(material_shadowMap, projCoords.xy).r; + float currentDepth = projCoords.z; + float shadow = currentDepth > closestDepth ? 1.0 : 0.0; + return shadow; +} + +void main() +{ + /////FragColor = vec4(1.0); + Material material = GetMaterial(mat); + + Light ambientLight = ambient; + Light currentLight = lights[0]; + + + vec3 col = texture2D(material_textures[0], fUV).rgb; + + vec3 amb = vec3(0, 0, 0); + vec3 dif = vec3(0, 0, 0); + vec3 spec = vec3(0, 0, 0); + + amb += CalculateAmbientLightning(ambientLight, material); + + for(int i = 0; i < lights_count; i++){ + dif += CalculateDiffuseLightning(lights[i], material); + spec += CalculateSpecularLightning(lights[i], material, Normal); + } + + float shadow = ShadowCalculation(lightFragPos); + vec3 lighting = (amb + (1.0 - shadow) * (dif + spec)) * col; + + ////vec3 result = CombineLightning(amb, dif, spec, objectColor); + FragColor = vec4(lighting, 1.0); + +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/shader2.vert b/source/OrkEngine3D.Graphics.Tests/resources/shader2.vert new file mode 100644 index 0000000..bfdc47e --- /dev/null +++ b/source/OrkEngine3D.Graphics.Tests/resources/shader2.vert @@ -0,0 +1,26 @@ +#version 400 core +in vec3 vert_position; +in vec4 vert_color; +in vec2 vert_uv; +in vec3 vert_normal; +in float vert_material; + +out vec2 fUV; +out vec3 Normal; +out vec3 Pos; +out vec4 lightFragPos; +flat out int mat; + +uniform mat4 matx_model; +uniform mat4 matx_view; +uniform mat4 matx_light; + +void main() +{ + gl_Position = matx_view * matx_model * vec4(vert_position, 1.0); + Normal = vert_normal * mat3(inverse(matx_model)); + fUV = vert_uv; + Pos = vec3(matx_model * vec4(vert_position, 1.0)); + lightFragPos = matx_light * vec4(Pos, 1.0); + mat = int(floor(vert_material)); +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/shaders/lighting.frag b/source/OrkEngine3D.Graphics.Tests/resources/shaders/lighting.frag new file mode 100644 index 0000000..c0c554c --- /dev/null +++ b/source/OrkEngine3D.Graphics.Tests/resources/shaders/lighting.frag @@ -0,0 +1,148 @@ +#version 330 core +//In this tutorial it might seem like a lot is going on, but really we just combine the last tutorials, 3 pieces of source code into one +//and added 3 extra point lights. +struct Material { + sampler2D diffuse; + sampler2D specular; + float shininess; +}; +//This is the directional light struct, where we only need the directions +struct DirLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +uniform DirLight dirLight; +//This is our pointlight where we need the position aswell as the constants defining the attenuation of the light. +struct PointLight { + vec3 position; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +//We have a total of 4 point lights now, so we define a preprossecor directive to tell the gpu the size of our point light array +#define NR_POINT_LIGHTS 4 +uniform PointLight pointLights[NR_POINT_LIGHTS]; +//This is our spotlight where we need the position, attenuation along with the cutoff and the outer cutoff. Plus the direction of the light +struct SpotLight{ + vec3 position; + vec3 direction; + float cutOff; + float outerCutOff; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; +uniform SpotLight spotLight; + +uniform Material material; +uniform vec3 viewPos; + +out vec4 FragColor; + +in vec3 Normal; +in vec3 FragPos; +in vec2 TexCoords; + +//Here we have some function prototypes, these are the signatures the gpu will use to know how the +//parameters of each light calculation is layed out. +//We have one function per light, since this makes it so we dont have to take up to much space in the main function. +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); + +void main() +{ + //properties + vec3 norm = normalize(Normal); + vec3 viewDir = normalize(viewPos - FragPos); + + //phase 1: Directional lighting + vec3 result = CalcDirLight(dirLight, norm, viewDir); + //phase 2: Point lights + for(int i = 0; i < NR_POINT_LIGHTS; i++) + result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); + //phase 3: Spot light + result += CalcSpotLight(spotLight, norm, FragPos, viewDir); + + FragColor = vec4(result, 1.0); +} + +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) +{ + vec3 lightDir = normalize(-light.direction); + //diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + //specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + //combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + return (ambient + diffuse + specular); +} + +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + //diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + //specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + //attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + + light.quadratic * (distance * distance)); + //combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + return (ambient + diffuse + specular); +} +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + + //diffuse shading + vec3 lightDir = normalize(light.position - FragPos); + float diff = max(dot(normal, lightDir), 0.0); + + //specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + //attenuation + float distance = length(light.position - FragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + + light.quadratic * (distance * distance)); + + //spotlight intensity + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + + //combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + return (ambient + diffuse + specular); +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.frag b/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.frag new file mode 100644 index 0000000..0fe7024 --- /dev/null +++ b/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.frag @@ -0,0 +1,7 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0); // set all 4 vector values to 1.0 +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.vert b/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.vert new file mode 100644 index 0000000..cd9a9cb --- /dev/null +++ b/source/OrkEngine3D.Graphics.Tests/resources/shaders/shader.vert @@ -0,0 +1,27 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; +//layout(location = 0) in vec3 aPosition; + +//layout(location = 1) in vec2 aTexCoord; + +//out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +out vec3 Normal; +out vec3 FragPos; +out vec2 TexCoords; + +void main(void) +{ + //texCoord = aTexCoord; + + gl_Position = vec4(aPos, 1.0) * model * view * projection; + FragPos = vec3(vec4(aPos, 1.0) * model); + Normal = aNormal * mat3(transpose(inverse(model))); + TexCoords = aTexCoords; +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics.Tests/resources/top.jpg b/source/OrkEngine3D.Graphics.Tests/resources/top.jpg new file mode 100644 index 0000000..be317c1 Binary files /dev/null and b/source/OrkEngine3D.Graphics.Tests/resources/top.jpg differ diff --git a/source/OrkEngine3D.Graphics/LightScene.cs b/source/OrkEngine3D.Graphics/LightScene.cs index 2b805ec..4132562 100644 --- a/source/OrkEngine3D.Graphics/LightScene.cs +++ b/source/OrkEngine3D.Graphics/LightScene.cs @@ -1,31 +1,25 @@ using OrkEngine3D.Mathematics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace OrkEngine3D.Graphics +namespace OrkEngine3D.Graphics; + +public class LightScene { - public class LightScene - { - public Light ambient = new Light(0.2f, new Color3(1f, 1f, 1f), new Vector3(0, 0, 0)); - public Light[] lights = new Light[] { - new Light(0.9f, new Color3(1f, 1f, 1f), new Vector3(10, 0, 0)), - }; - } + public Light ambient = new Light(0.2f, new Color3(1f, 1f, 1f), new Vector3(0, 0, 0)); + public Light[] lights = new Light[] { + new Light(0.9f, new Color3(1f, 1f, 1f), new Vector3(10, 0, 0)), + }; +} - public struct Light - { - public float strength; - public Color3 color; - public Vector3 position; +public struct Light +{ + public float strength; + public Color3 color; + public Vector3 position; - public Light(float strength, Color3 color, Vector3 pos) - { - this.strength = strength; - this.color = color; - this.position = pos; - } + public Light(float strength, Color3 color, Vector3 pos) + { + this.strength = strength; + this.color = color; + this.position = pos; } } diff --git a/source/OrkEngine3D.Graphics/MeshData/MeshInformation.cs b/source/OrkEngine3D.Graphics/MeshData/MeshInformation.cs index 845869a..a3b0219 100644 --- a/source/OrkEngine3D.Graphics/MeshData/MeshInformation.cs +++ b/source/OrkEngine3D.Graphics/MeshData/MeshInformation.cs @@ -1,27 +1,26 @@ using OrkEngine3D.Mathematics; -namespace OrkEngine3D.Graphics.MeshData +namespace OrkEngine3D.Graphics.MeshData; + +/// +/// A readonly struct for passing a mesh out of a function. +/// +public readonly struct MeshInformation { - /// - /// A readonly struct for passing a mesh out of a function. - /// - public readonly struct MeshInformation - { - public readonly Vector3[] verticies; - public readonly Color4[] colors; - public readonly Vector2[] uv; - public readonly Vector3[] normals; - public readonly uint[] triangles; - public readonly int[] materials; + public readonly Vector3[] verticies; + public readonly Color4[] colors; + public readonly Vector2[] uv; + public readonly Vector3[] normals; + public readonly uint[] triangles; + public readonly int[] materials; - public MeshInformation(Vector3[] verticies, Color4[] colors, Vector2[] uv, Vector3[] normals, uint[] triangles, int[] materials) - { - this.verticies = verticies; - this.colors = colors; - this.uv = uv; - this.triangles = triangles; - this.normals = normals; - this.materials = materials; - } + public MeshInformation(Vector3[] verticies, Color4[] colors, Vector2[] uv, Vector3[] normals, uint[] triangles, int[] materials) + { + this.verticies = verticies; + this.colors = colors; + this.uv = uv; + this.triangles = triangles; + this.normals = normals; + this.materials = materials; } } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/MeshData/ObjLoader.cs b/source/OrkEngine3D.Graphics/MeshData/ObjLoader.cs index 7b1155b..dd9b06a 100644 --- a/source/OrkEngine3D.Graphics/MeshData/ObjLoader.cs +++ b/source/OrkEngine3D.Graphics/MeshData/ObjLoader.cs @@ -7,222 +7,220 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace OrkEngine3D.Graphics.MeshData +namespace OrkEngine3D.Graphics.MeshData; + +public static class ObjLoader { - public static class ObjLoader + public static readonly Logger logger = Logger.Get("MeshLoader", "Graphics"); + public static ObjComplete LoadObjFromFile(string path) { - public static readonly Logger logger = Logger.Get("MeshLoader", "Graphics"); - public static ObjComplete LoadObjFromFile(string path) - { - string dir = Path.GetDirectoryName(path); - string text = File.ReadAllText(path); - logger.Log(LogMessageType.DEBUG, "Loading OBJ"); - string material = "__null"; + string dir = Path.GetDirectoryName(path); + string text = File.ReadAllText(path); + logger.Log(LogMessageType.DEBUG, "Loading OBJ"); + string material = "__null"; - string[] lines = text.Split('\n'); - List vertices = new List(); - List uvs = new List(); - List normals = new List(); + string[] lines = text.Split('\n'); + List vertices = new List(); + List uvs = new List(); + List normals = new List(); - List vmaterials = new List(); + List vmaterials = new List(); - List tvertices = new List(); - List tuvs = new List(); - List tnormals = new List(); + List tvertices = new List(); + List tuvs = new List(); + List tnormals = new List(); - string mtl = ""; + string mtl = ""; - for (int i = 0; i < lines.Length; i++) + for (int i = 0; i < lines.Length; i++) + { + string line = lines[i].Trim(); + + if (line.StartsWith("v ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); + float x = float.Parse(c[1], CultureInfo.InvariantCulture); + float y = float.Parse(c[2], CultureInfo.InvariantCulture); + float z = float.Parse(c[3], CultureInfo.InvariantCulture); + vertices.Add(new Vector3(x, y, z)); + } + if (line.StartsWith("vt ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 3) + logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); + float x = float.Parse(c[1], CultureInfo.InvariantCulture); + float y = float.Parse(c[2], CultureInfo.InvariantCulture); + uvs.Add(new Vector2(x, y)); + } + if (line.StartsWith("vn ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); + float x = float.Parse(c[1], CultureInfo.InvariantCulture); + float y = float.Parse(c[2], CultureInfo.InvariantCulture); + float z = float.Parse(c[3], CultureInfo.InvariantCulture); + normals.Add(new Vector3(x, y, z)); + } + if (line.StartsWith("f ")) { - string line = lines[i].Trim(); + var c = line.Split(' '); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - if (line.StartsWith("v ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - float x = float.Parse(c[1], CultureInfo.InvariantCulture); - float y = float.Parse(c[2], CultureInfo.InvariantCulture); - float z = float.Parse(c[3], CultureInfo.InvariantCulture); - vertices.Add(new Vector3(x, y, z)); - } - if (line.StartsWith("vt ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 3) - logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - float x = float.Parse(c[1], CultureInfo.InvariantCulture); - float y = float.Parse(c[2], CultureInfo.InvariantCulture); - uvs.Add(new Vector2(x, y)); - } - if (line.StartsWith("vn ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - float x = float.Parse(c[1], CultureInfo.InvariantCulture); - float y = float.Parse(c[2], CultureInfo.InvariantCulture); - float z = float.Parse(c[3], CultureInfo.InvariantCulture); - normals.Add(new Vector3(x, y, z)); - } - if (line.StartsWith("f ")) + for (int s = 1; s < 4; s++) { - var c = line.Split(' '); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - - for (int s = 1; s < 4; s++) - { - string set = c[s]; - string[] t = set.Split('/'); + string set = c[s]; + string[] t = set.Split('/'); - if (t.Length < 3) - logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); + if (t.Length < 3) + logger.Log(LogMessageType.FATAL, "Invalid OBJ file!"); - uint v = uint.Parse(t[0]); - uint u = uint.Parse(t[1]); - uint n = uint.Parse(t[2]); + uint v = uint.Parse(t[0]); + uint u = uint.Parse(t[1]); + uint n = uint.Parse(t[2]); - tvertices.Add(v - 1); - tuvs.Add(u - 1); - tnormals.Add(n - 1); - vmaterials.Add(material); + tvertices.Add(v - 1); + tuvs.Add(u - 1); + tnormals.Add(n - 1); + vmaterials.Add(material); - } - } - if (line.StartsWith("mtllib ")) - { - mtl = line.Substring("mtllib ".Length).Trim(); - } - if (line.StartsWith("usemtl ")) - { - material = line.Substring("mtllib ".Length).Trim(); } } - - - - Dictionary materials = LoadMTLFromFile(dir + "/" + mtl); - - List fvertices = new List(); - List fuvs = new List(); - List fnormals = new List(); - List ftriangles = new List(); - List fmaterials = new List(); - - for (int i = 0; i < tvertices.Count; i++) + if (line.StartsWith("mtllib ")) + { + mtl = line.Substring("mtllib ".Length).Trim(); + } + if (line.StartsWith("usemtl ")) { - uint vertexIndex = tvertices[i]; - uint normalIndex = tnormals[i]; - uint uvIndex = tuvs[i]; - fvertices.Add(vertices[(int)vertexIndex]); - fnormals.Add(normals[(int)normalIndex]); - fuvs.Add(uvs[(int)uvIndex]); - ftriangles.Add((uint)i); - fmaterials.Add(materials.Keys.ToList().IndexOf(vmaterials[i])); + material = line.Substring("mtllib ".Length).Trim(); } + } - tvertices.Clear(); - tuvs.Clear(); - tnormals.Clear(); - return new ObjComplete(new MeshInformation(fvertices.ToArray(), new Color4[0], fuvs.ToArray(), fnormals.ToArray(), ftriangles.ToArray(), fmaterials.ToArray()), materials.Values.ToArray()); - } + Dictionary materials = LoadMTLFromFile(dir + "/" + mtl); - private static Dictionary LoadMTLFromFile(string filepath) + List fvertices = new List(); + List fuvs = new List(); + List fnormals = new List(); + List ftriangles = new List(); + List fmaterials = new List(); + + for (int i = 0; i < tvertices.Count; i++) { - logger.Log(LogMessageType.WARNING, "MTL Loader uses OrkGraphics Flavoured MTL! It doesnt work with all MTL files"); - string content = File.ReadAllText(filepath); - Material material = new Material(); - string materialname = "__null"; - string[] lines = content.Split('\n', StringSplitOptions.TrimEntries); - List textures = new List(); + uint vertexIndex = tvertices[i]; + uint normalIndex = tnormals[i]; + uint uvIndex = tuvs[i]; + fvertices.Add(vertices[(int)vertexIndex]); + fnormals.Add(normals[(int)normalIndex]); + fuvs.Add(uvs[(int)uvIndex]); + ftriangles.Add((uint)i); + fmaterials.Add(materials.Keys.ToList().IndexOf(vmaterials[i])); + } - Dictionary materials = new Dictionary(); + tvertices.Clear(); + tuvs.Clear(); + tnormals.Clear(); - for (int i = 0; i < lines.Length; i++) - { - string line = lines[i]; + return new ObjComplete(new MeshInformation(fvertices.ToArray(), new Color4[0], fuvs.ToArray(), fnormals.ToArray(), ftriangles.ToArray(), fmaterials.ToArray()), materials.Values.ToArray()); + } - if (line.StartsWith("Ka ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); - float r = float.Parse(c[1], CultureInfo.InvariantCulture); - float g = float.Parse(c[2], CultureInfo.InvariantCulture); - float b = float.Parse(c[3], CultureInfo.InvariantCulture); - material.ambient = new Color3(r, g, b); - } - if (line.StartsWith("Kd ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); - float r = float.Parse(c[1], CultureInfo.InvariantCulture); - float g = float.Parse(c[2], CultureInfo.InvariantCulture); - float b = float.Parse(c[3], CultureInfo.InvariantCulture); - material.diffuse = new Color3(r, g, b); - } - if (line.StartsWith("Ks ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 4) - logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); - float r = float.Parse(c[1], CultureInfo.InvariantCulture); - float g = float.Parse(c[2], CultureInfo.InvariantCulture); - float b = float.Parse(c[3], CultureInfo.InvariantCulture); - material.specular = new Color3(r, g, b); - } - if (line.StartsWith("Ns ")) - { - var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); - if (c.Length < 2) - logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); - material.shininess = float.Parse(c[1], CultureInfo.InvariantCulture); - } - if (line.StartsWith("Tx ")) - { - string path = line.Substring("Tx ".Length).Trim(); - textures.Add(Rendering.CreateTexture(Texture.GetTextureDataFromFile(path))); - } - if(line.StartsWith("newmtl ")) - { + private static Dictionary LoadMTLFromFile(string filepath) + { + logger.Log(LogMessageType.WARNING, "MTL Loader uses OrkGraphics Flavoured MTL! It doesnt work with all MTL files"); + string content = File.ReadAllText(filepath); + Material material = new Material(); + string materialname = "__null"; + string[] lines = content.Split('\n', StringSplitOptions.TrimEntries); + List textures = new List(); - material.textures = textures.ToArray(); - textures.Clear(); - materials.Add(materialname, material); - material = new Material(); - materialname = line.Substring("newmtl ".Length).Trim(); + Dictionary materials = new Dictionary(); - } + for (int i = 0; i < lines.Length; i++) + { + string line = lines[i]; + + if (line.StartsWith("Ka ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); + float r = float.Parse(c[1], CultureInfo.InvariantCulture); + float g = float.Parse(c[2], CultureInfo.InvariantCulture); + float b = float.Parse(c[3], CultureInfo.InvariantCulture); + material.ambient = new Color3(r, g, b); } + if (line.StartsWith("Kd ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); + float r = float.Parse(c[1], CultureInfo.InvariantCulture); + float g = float.Parse(c[2], CultureInfo.InvariantCulture); + float b = float.Parse(c[3], CultureInfo.InvariantCulture); + material.diffuse = new Color3(r, g, b); + } + if (line.StartsWith("Ks ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 4) + logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); + float r = float.Parse(c[1], CultureInfo.InvariantCulture); + float g = float.Parse(c[2], CultureInfo.InvariantCulture); + float b = float.Parse(c[3], CultureInfo.InvariantCulture); + material.specular = new Color3(r, g, b); + } + if (line.StartsWith("Ns ")) + { + var c = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (c.Length < 2) + logger.Log(LogMessageType.FATAL, "Invalid MTL file!"); + material.shininess = float.Parse(c[1], CultureInfo.InvariantCulture); + } + if (line.StartsWith("Tx ")) + { + string path = line.Substring("Tx ".Length).Trim(); + //TODO fix + //textures.Add(Rendering.CreateTexture(Texture.GetTextureDataFromFile(path))); + } + if(line.StartsWith("newmtl ")) + { - material.textures = textures.ToArray(); - materials.Add(materialname, material); + material.textures = textures.ToArray(); + textures.Clear(); + materials.Add(materialname, material); + material = new Material(); + materialname = line.Substring("newmtl ".Length).Trim(); + } - return materials; } + + material.textures = textures.ToArray(); + materials.Add(materialname, material); + + + return materials; } +} - public struct ObjComplete - { - public MeshInformation meshInformation; - public Material[] materials; +public struct ObjComplete +{ + public MeshInformation meshInformation; + public Material[] materials; - public ObjComplete(MeshInformation meshInformation, Material[] materials) - { - this.meshInformation = meshInformation; - this.materials = materials; - } + public ObjComplete(MeshInformation meshInformation, Material[] materials) + { + this.meshInformation = meshInformation; + this.materials = materials; } } diff --git a/source/OrkEngine3D.Graphics/MeshData/VoxelData.cs b/source/OrkEngine3D.Graphics/MeshData/VoxelData.cs index 958cc8d..5a76562 100644 --- a/source/OrkEngine3D.Graphics/MeshData/VoxelData.cs +++ b/source/OrkEngine3D.Graphics/MeshData/VoxelData.cs @@ -1,85 +1,84 @@ using System.Collections.Generic; using OrkEngine3D.Mathematics; -namespace OrkEngine3D.Graphics.MeshData +namespace OrkEngine3D.Graphics.MeshData; + +/// +/// VoxelData is a class that contains all the data nesseccary to generate a voxel/cube mesh +/// +public static class VoxelData { - /// - /// VoxelData is a class that contains all the data nesseccary to generate a voxel/cube mesh - /// - public static class VoxelData - { - public static readonly Vector3[] voxelVerts = new Vector3[8] { + public static readonly Vector3[] voxelVerts = new Vector3[8] { - new Vector3(0.0f, 0.0f, 0.0f), - new Vector3(1.0f, 0.0f, 0.0f), - new Vector3(1.0f, 1.0f, 0.0f), - new Vector3(0.0f, 1.0f, 0.0f), - new Vector3(0.0f, 0.0f, 1.0f), - new Vector3(1.0f, 0.0f, 1.0f), - new Vector3(1.0f, 1.0f, 1.0f), - new Vector3(0.0f, 1.0f, 1.0f), + new Vector3(0.0f, 0.0f, 0.0f), + new Vector3(1.0f, 0.0f, 0.0f), + new Vector3(1.0f, 1.0f, 0.0f), + new Vector3(0.0f, 1.0f, 0.0f), + new Vector3(0.0f, 0.0f, 1.0f), + new Vector3(1.0f, 0.0f, 1.0f), + new Vector3(1.0f, 1.0f, 1.0f), + new Vector3(0.0f, 1.0f, 1.0f), - }; + }; - public static readonly int[,] voxelTris = new int[6, 6] { + public static readonly int[,] voxelTris = new int[6, 6] { - {0, 3, 1, 1, 3, 2}, // Back Face - {5, 6, 4, 4, 6, 7}, // Front Face - {3, 7, 2, 2, 7, 6}, // Top Face - {1, 5, 0, 0, 5, 4}, // Bottom Face - {4, 7, 0, 0, 7, 3}, // Left Face - {1, 2, 5, 5, 2, 6} // Right Face + {0, 3, 1, 1, 3, 2}, // Back Face + {5, 6, 4, 4, 6, 7}, // Front Face + {3, 7, 2, 2, 7, 6}, // Top Face + {1, 5, 0, 0, 5, 4}, // Bottom Face + {4, 7, 0, 0, 7, 3}, // Left Face + {1, 2, 5, 5, 2, 6} // Right Face - }; + }; - public static readonly Vector2[] voxelUvs = new Vector2[6] { + public static readonly Vector2[] voxelUvs = new Vector2[6] { - new Vector2 (0.0f, 0.0f), - new Vector2 (0.0f, 1.0f), - new Vector2 (1.0f, 0.0f), - new Vector2 (1.0f, 0.0f), - new Vector2 (0.0f, 1.0f), - new Vector2 (1.0f, 1.0f) + new Vector2 (0.0f, 0.0f), + new Vector2 (0.0f, 1.0f), + new Vector2 (1.0f, 0.0f), + new Vector2 (1.0f, 0.0f), + new Vector2 (0.0f, 1.0f), + new Vector2 (1.0f, 1.0f) - }; + }; - public static readonly Vector3[] faceChecks = new Vector3[6] { + public static readonly Vector3[] faceChecks = new Vector3[6] { - new Vector3(0.0f, 0.0f, -1.0f), - new Vector3(0.0f, 0.0f, 1.0f), - new Vector3(0.0f, 1.0f, 0.0f), - new Vector3(0.0f, -1.0f, 0.0f), - new Vector3(-1.0f, 0.0f, 0.0f), - new Vector3(1.0f, 0.0f, 0.0f) + new Vector3(0.0f, 0.0f, -1.0f), + new Vector3(0.0f, 0.0f, 1.0f), + new Vector3(0.0f, 1.0f, 0.0f), + new Vector3(0.0f, -1.0f, 0.0f), + new Vector3(-1.0f, 0.0f, 0.0f), + new Vector3(1.0f, 0.0f, 0.0f) }; - public static MeshInformation GenerateVoxelInformation(){ - uint vertexIndex = 0; - List vertices = new List (); - List triangles = new List (); - List uvs = new List (); - List normals = new List(); + public static MeshInformation GenerateVoxelInformation(){ + uint vertexIndex = 0; + List vertices = new List (); + List triangles = new List (); + List uvs = new List (); + List normals = new List(); - for (int p = 0; p < 6; p++) { - for (int i = 0; i < 6; i++) { + for (int p = 0; p < 6; p++) { + for (int i = 0; i < 6; i++) { - int triangleIndex = VoxelData.voxelTris [p, i]; - vertices.Add (VoxelData.voxelVerts [triangleIndex] - (Vector3.One * 0.5f)); - triangles.Add (vertexIndex); - normals.Add(faceChecks[p]); + int triangleIndex = VoxelData.voxelTris [p, i]; + vertices.Add (VoxelData.voxelVerts [triangleIndex] - (Vector3.One * 0.5f)); + triangles.Add (vertexIndex); + normals.Add(faceChecks[p]); - uvs.Add (VoxelData.voxelUvs [i]); + uvs.Add (VoxelData.voxelUvs [i]); - vertexIndex++; + vertexIndex++; - } } - - return new MeshInformation(vertices.ToArray(), new Color4[0], uvs.ToArray(), normals.ToArray(), triangles.ToArray(), new int[0]); } - + return new MeshInformation(vertices.ToArray(), new Color4[0], uvs.ToArray(), normals.ToArray(), triangles.ToArray(), new int[0]); } + + } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/OMF/OMF1/OrkModelFile.cs b/source/OrkEngine3D.Graphics/OMF/OMF1/OrkModelFile.cs index e9785cb..a5711f4 100644 --- a/source/OrkEngine3D.Graphics/OMF/OMF1/OrkModelFile.cs +++ b/source/OrkEngine3D.Graphics/OMF/OMF1/OrkModelFile.cs @@ -1,289 +1,284 @@ using Newtonsoft.Json; using OrkEngine3D.Mathematics; -using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; /// /// The OMF1 namespace. All types have been renamed to C# naming conventions. /// Currently following OMF1 1.0.0 specification. /// -namespace OrkEngine3D.Graphics.OMF.OMF1 +namespace OrkEngine3D.Graphics.OMF.OMF1; + +/// +/// The model itself. +/// +public struct OrkModelFile { - /// - /// The model itself. - /// - public struct OrkModelFile + public string version = "OMF1 1.0.0"; + public string copyright = "Copyright not specified"; + public string author = "Author not specified"; + public Node[] nodes = new Node[0]; + public Mesh[] meshes = new Mesh[0]; + public Material[] materials = new Material[0]; + + public OrkModelFile() { - public string version = "OMF1 1.0.0"; - public string copyright = "Copyright not specified"; - public string author = "Author not specified"; - public Node[] nodes = new Node[0]; - public Mesh[] meshes = new Mesh[0]; - public Material[] materials = new Material[0]; - - public OrkModelFile() + } + + public static OrkModelFile LoadFromJSONData(string data) + { + return JsonConvert.DeserializeObject(data); + } + + public static MeshData.ObjComplete OMFToObjComplete(OrkModelFile file){ + MeshData.ObjComplete complete = new MeshData.ObjComplete(); + complete.materials = new TK.Material[file.materials.Length]; + + for(int i = 0; i < complete.materials.Length; i++) { + Material material = file.materials[i]; + complete.materials[i] = new TK.Material{ + diffuse = material.diffuse.ToColor3(), + specular = material.specular.ToColor3(), + ambient = material.ambient.ToColor3(), + shininess = material.shininess, + }; } - - public static OrkModelFile LoadFromJSONData(string data) + Mesh mesh = file.meshes[0]; + + Vector3[] verticies = new Vector3[mesh.verticies.Length]; + for (int i = 0; i < mesh.verticies.Length; i++) { - return JsonConvert.DeserializeObject(data); + verticies[i] = mesh.verticies[i].ToOrkMaths(); } - public static MeshData.ObjComplete OMFToObjComplete(OrkModelFile file){ - MeshData.ObjComplete complete = new MeshData.ObjComplete(); - complete.materials = new TK.Material[file.materials.Length]; - - for(int i = 0; i < complete.materials.Length; i++) - { - Material material = file.materials[i]; - complete.materials[i] = new TK.Material{ - diffuse = material.diffuse.ToColor3(), - specular = material.specular.ToColor3(), - ambient = material.ambient.ToColor3(), - shininess = material.shininess, - }; - } - Mesh mesh = file.meshes[0]; - - Vector3[] verticies = new Vector3[mesh.verticies.Length]; - for (int i = 0; i < mesh.verticies.Length; i++) - { - verticies[i] = mesh.verticies[i].ToOrkMaths(); - } - - Vector2[] uvs = new Vector2[mesh.uvs.Length]; - for (int i = 0; i < mesh.verticies.Length; i++) - { - uvs[i] = mesh.uvs[i].ToOrkMaths(); - } - - Vector3[] normals = new Vector3[mesh.normals.Length]; - for (int i = 0; i < mesh.normals.Length; i++) - { - normals[i] = mesh.normals[i].ToOrkMaths(); - } - - Color4[] colors = new Color4[mesh.colors.Length]; - for (int i = 0; i < mesh.colors.Length; i++) - { - colors[i] = mesh.colors[i].ToColor4(); - } - - int[] materials = mesh.materials.Cast().ToArray(); - uint[] triangles = mesh.triangles; - - MeshData.MeshInformation meshInfo = new MeshData.MeshInformation(verticies, colors, uvs, normals, triangles, materials); - - complete.meshInformation = meshInfo; - - return complete; + Vector2[] uvs = new Vector2[mesh.uvs.Length]; + for (int i = 0; i < mesh.verticies.Length; i++) + { + uvs[i] = mesh.uvs[i].ToOrkMaths(); } - public static OrkModelFile ObjCompleteToOMF(MeshData.ObjComplete obj){ - OrkModelFile modelFile = new OrkModelFile(); - modelFile.author = "OrkEngine OMF Converter"; - modelFile.copyright = "Copyright OrkEngine 2021"; - modelFile.version = "1.1.0.0"; - - modelFile.materials = new Material[obj.materials.Length]; - for(int i = 0; i < modelFile.materials.Length; i++) - { - TK.Material material = obj.materials[i]; - modelFile.materials[i] = new Material{ - diffuse = material.diffuse.ToOMFVec3(), - specular = material.specular.ToOMFVec3(), - ambient = material.ambient.ToOMFVec3(), - shininess = material.shininess, - }; - } + Vector3[] normals = new Vector3[mesh.normals.Length]; + for (int i = 0; i < mesh.normals.Length; i++) + { + normals[i] = mesh.normals[i].ToOrkMaths(); + } - modelFile.meshes = new Mesh[1]; - Mesh mesh = new Mesh(); - MeshData.MeshInformation meshInfo = obj.meshInformation; - mesh.verticies = new Vec3[meshInfo.verticies.Length]; - for (int i = 0; i < mesh.verticies.Length; i++) - { - mesh.verticies[i] = meshInfo.verticies[i].ToOMFVec3(); - } + Color4[] colors = new Color4[mesh.colors.Length]; + for (int i = 0; i < mesh.colors.Length; i++) + { + colors[i] = mesh.colors[i].ToColor4(); + } - mesh.uvs = new Vec2[meshInfo.uv.Length]; - for (int i = 0; i < mesh.verticies.Length; i++) - { - mesh.uvs[i] = meshInfo.uv[i].ToOMFVec2(); - } + int[] materials = mesh.materials.Cast().ToArray(); + uint[] triangles = mesh.triangles; - mesh.normals = new Vec3[meshInfo.normals.Length]; - for (int i = 0; i < mesh.normals.Length; i++) - { - mesh.normals[i] = meshInfo.normals[i].ToOMFVec3(); - } + MeshData.MeshInformation meshInfo = new MeshData.MeshInformation(verticies, colors, uvs, normals, triangles, materials); - mesh.colors = new Vec3[meshInfo.colors.Length]; - for (int i = 0; i < mesh.colors.Length; i++) - { - mesh.colors[i] = meshInfo.colors[i].ToOMFVec3(); - } + complete.meshInformation = meshInfo; + + return complete; + } - mesh.materials = meshInfo.materials.Cast().ToArray(); - mesh.triangles = meshInfo.triangles; + public static OrkModelFile ObjCompleteToOMF(MeshData.ObjComplete obj){ + OrkModelFile modelFile = new OrkModelFile(); + modelFile.author = "OrkEngine OMF Converter"; + modelFile.copyright = "Copyright OrkEngine 2021"; + modelFile.version = "1.1.0.0"; - modelFile.meshes[0] = mesh; - modelFile.nodes = new Node[]{ - new Node{ - name = "root", - mesh = new uint[] { 0 } - } + modelFile.materials = new Material[obj.materials.Length]; + for(int i = 0; i < modelFile.materials.Length; i++) + { + TK.Material material = obj.materials[i]; + modelFile.materials[i] = new Material{ + diffuse = material.diffuse.ToOMFVec3(), + specular = material.specular.ToOMFVec3(), + ambient = material.ambient.ToOMFVec3(), + shininess = material.shininess, }; + } - return modelFile; - + modelFile.meshes = new Mesh[1]; + Mesh mesh = new Mesh(); + MeshData.MeshInformation meshInfo = obj.meshInformation; + mesh.verticies = new Vec3[meshInfo.verticies.Length]; + for (int i = 0; i < mesh.verticies.Length; i++) + { + mesh.verticies[i] = meshInfo.verticies[i].ToOMFVec3(); } - public static OrkModelFile LoadFromFile(string path) + mesh.uvs = new Vec2[meshInfo.uv.Length]; + for (int i = 0; i < mesh.verticies.Length; i++) { - return LoadFromJSONData(File.ReadAllText(path)); + mesh.uvs[i] = meshInfo.uv[i].ToOMFVec2(); } - public static string SerializeModel(OrkModelFile file, bool compact = false) + mesh.normals = new Vec3[meshInfo.normals.Length]; + for (int i = 0; i < mesh.normals.Length; i++) { - return JsonConvert.SerializeObject(file, (compact ? Formatting.None : Formatting.Indented)); + mesh.normals[i] = meshInfo.normals[i].ToOMFVec3(); } - public static void SaveToFile(string path, OrkModelFile file, bool compact = false) + mesh.colors = new Vec3[meshInfo.colors.Length]; + for (int i = 0; i < mesh.colors.Length; i++) { - File.WriteAllText(path, SerializeModel(file, compact)); + mesh.colors[i] = meshInfo.colors[i].ToOMFVec3(); } + + mesh.materials = meshInfo.materials.Cast().ToArray(); + mesh.triangles = meshInfo.triangles; + + modelFile.meshes[0] = mesh; + modelFile.nodes = new Node[]{ + new Node{ + name = "root", + mesh = new uint[] { 0 } + } + }; + + return modelFile; + } - /// - /// A node, or bone of the model - /// - public struct Node + public static OrkModelFile LoadFromFile(string path) { - public string name = "NULL"; - public Transformation transformation = new Transformation(); - public uint[] mesh = new uint[0]; - - public Node() - { - } + return LoadFromJSONData(File.ReadAllText(path)); } - /// - /// The mesh of a model - /// - public struct Mesh + public static string SerializeModel(OrkModelFile file, bool compact = false) { - public Vec3[] verticies = new Vec3[0]; - public Vec3[] normals = new Vec3[0]; - public Vec3[] colors = new Vec3[0]; - public Vec2[] uvs = new Vec2[0]; - public uint[] triangles = new uint[0]; - public uint[] materials = new uint[0]; - - public Mesh() - { - } + return JsonConvert.SerializeObject(file, (compact ? Formatting.None : Formatting.Indented)); } - /// - /// The material of a model - /// - public struct Material + public static void SaveToFile(string path, OrkModelFile file, bool compact = false) { - public string name = "NULL"; - public Vec3 ambient = new Vec3(); - public Vec3 diffuse = new Vec3(); - public Vec3 specular = new Vec3(); - public float shininess = 0.0f; - public string[] textures = new string[0]; - - public Material() - { - } + File.WriteAllText(path, SerializeModel(file, compact)); } +} - /// - /// Model transformation - /// - public struct Transformation +/// +/// A node, or bone of the model +/// +public struct Node +{ + public string name = "NULL"; + public Transformation transformation = new Transformation(); + public uint[] mesh = new uint[0]; + + public Node() { - public Vec3 position = new Vec3(); - public Vec3 rotation = new Vec3(); - public Vec3 scale = new Vec3(); - public Vec3 origin = new Vec3(); + } +} - public Transformation() - { - } +/// +/// The mesh of a model +/// +public struct Mesh +{ + public Vec3[] verticies = new Vec3[0]; + public Vec3[] normals = new Vec3[0]; + public Vec3[] colors = new Vec3[0]; + public Vec2[] uvs = new Vec2[0]; + public uint[] triangles = new uint[0]; + public uint[] materials = new uint[0]; + + public Mesh() + { } +} - /// - /// A 2D vector - /// - public struct Vec2 +/// +/// The material of a model +/// +public struct Material +{ + public string name = "NULL"; + public Vec3 ambient = new Vec3(); + public Vec3 diffuse = new Vec3(); + public Vec3 specular = new Vec3(); + public float shininess = 0.0f; + public string[] textures = new string[0]; + + public Material() { - public float x, y = 0; + } +} - public Vec2(float x, float y) - { - this.x = x; - this.y = y; - } +/// +/// Model transformation +/// +public struct Transformation +{ + public Vec3 position = new Vec3(); + public Vec3 rotation = new Vec3(); + public Vec3 scale = new Vec3(); + public Vec3 origin = new Vec3(); - public Vector2 ToOrkMaths(){ - return new Vector2(x, y); - } + public Transformation() + { } +} + +/// +/// A 2D vector +/// +public struct Vec2 +{ + public float x, y = 0; - /// - /// A 3D vector - /// - public struct Vec3 + public Vec2(float x, float y) { - public float x, y, z = 0; + this.x = x; + this.y = y; + } - public Vec3(float x, float y, float z) - { - this.x = x; - this.y = y; - this.z = z; - } + public Vector2 ToOrkMaths(){ + return new Vector2(x, y); + } +} - public Vector3 ToOrkMaths(){ - return new Vector3(x, y, z); - } - - public Color3 ToColor3(){ - return new Color3(x, y, z); - } +/// +/// A 3D vector +/// +public struct Vec3 +{ + public float x, y, z = 0; - public Color4 ToColor4(){ - return new Color4(1f, x, y, z); - } + public Vec3(float x, float y, float z) + { + this.x = x; + this.y = y; + this.z = z; } - public static class Extentions - { - public static Vec3 ToOMFVec3(this Vector3 vec){ - return new Vec3(vec.X, vec.Y, vec.Z); - } + public Vector3 ToOrkMaths(){ + return new Vector3(x, y, z); + } + + public Color3 ToColor3(){ + return new Color3(x, y, z); + } - public static Vec3 ToOMFVec3(this Color4 vec){ - return new Vec3(vec.Red, vec.Green, vec.Blue); - } + public Color4 ToColor4(){ + return new Color4(1f, x, y, z); + } +} - public static Vec3 ToOMFVec3(this Color3 vec){ - return new Vec3(vec.Red, vec.Green, vec.Blue); - } +public static class Extentions +{ + public static Vec3 ToOMFVec3(this Vector3 vec){ + return new Vec3(vec.X, vec.Y, vec.Z); + } - public static Vec2 ToOMFVec2(this Vector2 vec){ - return new Vec2(vec.X, vec.Y); - } + public static Vec3 ToOMFVec3(this Color4 vec){ + return new Vec3(vec.Red, vec.Green, vec.Blue); + } + + public static Vec3 ToOMFVec3(this Color3 vec){ + return new Vec3(vec.Red, vec.Green, vec.Blue); + } + + public static Vec2 ToOMFVec2(this Vector2 vec){ + return new Vec2(vec.X, vec.Y); } } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/OrkEngine3D.Graphics.csproj b/source/OrkEngine3D.Graphics/OrkEngine3D.Graphics.csproj index 5d8caf9..70c36af 100644 --- a/source/OrkEngine3D.Graphics/OrkEngine3D.Graphics.csproj +++ b/source/OrkEngine3D.Graphics/OrkEngine3D.Graphics.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net7.0 @@ -19,14 +19,14 @@ - + + - diff --git a/source/OrkEngine3D.Graphics/TK/Camera.cs b/source/OrkEngine3D.Graphics/TK/Camera.cs index 9b42940..fa04bb3 100644 --- a/source/OrkEngine3D.Graphics/TK/Camera.cs +++ b/source/OrkEngine3D.Graphics/TK/Camera.cs @@ -1,51 +1,178 @@ +using OpenTK.Mathematics; using OrkEngine3D.Core.Components; -using OrkEngine3D.Mathematics; +using System; +//using OrkEngine3D.Mathematics; -namespace OrkEngine3D.Graphics.TK +namespace OrkEngine3D.Graphics.TK; + +/// +/// The graphics end camera +/// +public class Camera { - /// - /// The graphics end camera - /// - public class Camera - { - /// - /// Is the camera perspective or not? - /// - public bool perspective = true; - - /// - /// Camera FOV - /// - public float fov = 90; - - /// - /// The near plane in units - /// Things closer than this wont render - /// - public float nearPlane = 0.1f; - /// - /// The far plane in units - /// Things further away than this wont render - /// - public float farPlane = 1000f; - - /// - /// The cameras transform, should be updated every frame - /// - public Transform transform = new Transform(); - - /// - /// Get the camera matrix, projection * view. - /// - /// The current graphics context - /// The camera matrix - public Matrix GetMatrix() + private Vector3 _front = -Vector3.UnitZ; + private Vector3 _up = Vector3.UnitY; + private Vector3 _right = Vector3.UnitX; + + // Rotation around the X axis (radians) + private float _pitch; + + private float _yaw = -MathHelper.PiOver2; + private float _fov = MathHelper.PiOver2; + + public Camera(Vector3 position, float aspectRatio) + { + Position = position; + AspectRatio = aspectRatio; + } + + // The position of the camera + public Vector3 Position { get; set; } + + // This is simply the aspect ratio of the viewport, used for the projection matrix + public float AspectRatio { private get; set; } + + public Vector3 Front => _front; + + public Vector3 Up => _up; + + public Vector3 Right => _right; + + public float Pitch + { + get => MathHelper.RadiansToDegrees(_pitch); + set { - GraphicsContext ctx = Rendering.currentContext; - if (perspective) - return Matrix.PerspectiveFovRH(fov, (float)ctx.window.Size.X / (float)ctx.window.Size.Y, nearPlane, farPlane);// * Matrix.LookAtRH(transform.position, transform.forward, transform.up); - else - return Matrix.OrthoRH((float)ctx.window.Size.X / (float)ctx.window.Size.Y, 1, nearPlane, farPlane) * Matrix.LookAtRH(transform.position, transform.forward, transform.up); + // We clamp the pitch value between -89 and 89 to prevent the camera from going upside down, and a bunch + // of weird "bugs" when you are using euler angles for rotation. + // If you want to read more about this you can try researching a topic called gimbal lock + var angle = MathHelper.Clamp(value, -89f, 89f); + _pitch = MathHelper.DegreesToRadians(angle); + UpdateVectors(); } } + + // We convert from degrees to radians as soon as the property is set to improve performance. + public float Yaw + { + get => MathHelper.RadiansToDegrees(_yaw); + set + { + _yaw = MathHelper.DegreesToRadians(value); + UpdateVectors(); + } + } + + // The field of view (FOV) is the vertical angle of the camera view. + // This has been discussed more in depth in a previous tutorial, + // but in this tutorial, you have also learned how we can use this to simulate a zoom feature. + // We convert from degrees to radians as soon as the property is set to improve performance. + public float Fov + { + get => MathHelper.RadiansToDegrees(_fov); + set + { + var angle = MathHelper.Clamp(value, 1f, 90f); + _fov = MathHelper.DegreesToRadians(angle); + } + } + + /// + /// Is the camera perspective or not? + /// + public bool perspective = true; + + /// + /// Camera FOV + /// + public float fov = 90; + + /// + /// The near plane in units + /// Things closer than this wont render + /// + public float nearPlane = 0.1f; + /// + /// The far plane in units + /// Things further away than this wont render + /// + public float farPlane = 1000f; + + //come back to this + // + // The cameras transform, should be updated every frame + // + //public Transform transform = new Transform(); + + // Get the view matrix using the amazing LookAt function described more in depth on the web tutorials + public Matrix4 GetViewMatrix() + { + return Matrix4.LookAt(Position, Position + _front, _up); + } + + // Get the projection matrix using the same method we have used up until this point + public Matrix4 GetProjectionMatrix() + { + return Matrix4.CreatePerspectiveFieldOfView(_fov, AspectRatio, 0.01f, 100f); + } + + // This function is going to update the direction vertices using some of the math learned in the web tutorials. + private void UpdateVectors() + { + // First, the front matrix is calculated using some basic trigonometry. + _front.X = MathF.Cos(_pitch) * MathF.Cos(_yaw); + _front.Y = MathF.Sin(_pitch); + _front.Z = MathF.Cos(_pitch) * MathF.Sin(_yaw); + + // We need to make sure the vectors are all normalized, as otherwise we would get some funky results. + _front = Vector3.Normalize(_front); + + // Calculate both the right and the up vector using cross product. + // Note that we are calculating the right from the global up; this behaviour might + // not be what you need for all cameras so keep this in mind if you do not want a FPS camera. + _right = Vector3.Normalize(Vector3.Cross(_front, Vector3.UnitY)); + _up = Vector3.Normalize(Vector3.Cross(_right, _front)); + } + + /* + /// + /// Is the camera perspective or not? + /// + public bool perspective = true; + + /// + /// Camera FOV + /// + public float fov = 90; + + /// + /// The near plane in units + /// Things closer than this wont render + /// + public float nearPlane = 0.1f; + /// + /// The far plane in units + /// Things further away than this wont render + /// + public float farPlane = 1000f; + + /// + /// The cameras transform, should be updated every frame + /// + public Transform transform = new Transform(); + + /// + /// Get the camera matrix, projection * view. + /// + /// The current graphics context + /// The camera matrix + public Matrix GetMatrix() + { + GraphicsContext ctx = Rendering.currentContext; + if (perspective) + return Matrix.PerspectiveFovRH(fov, (float)ctx.window.Size.X / (float)ctx.window.Size.Y, nearPlane, farPlane); //* Matrix.LookAtRH(transform.position, transform.forward, transform.up); + else + return Matrix.OrthoRH((float)ctx.window.Size.X / (float)ctx.window.Size.Y, 1, nearPlane, farPlane) * Matrix.LookAtRH(transform.position, transform.forward, transform.up); + } + */ } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/GContext.cs b/source/OrkEngine3D.Graphics/TK/GContext.cs new file mode 100644 index 0000000..a2b7c7f --- /dev/null +++ b/source/OrkEngine3D.Graphics/TK/GContext.cs @@ -0,0 +1,180 @@ +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; +using OpenTK.Mathematics; +using OpenTK.Graphics.OpenGL4; +using System; +using OrkEngine3D.Graphics.TK.Resources; +using OrkEngine3D.Diagnostics.Logging; +using Vector2 = OrkEngine3D.Mathematics.Vector2; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +namespace OrkEngine3D.Graphics.TK; + +public class GContext +{ + public GameWindow window; + public GLResourceManager glmanager; + public GraphicsBehaviour handler; + + public GContext(string title, GraphicsBehaviour handler, bool msaa = true) + { + var nws = NativeWindowSettings.Default; + var gws = GameWindowSettings.Default; + + nws.Title = title; + nws.Size = new Vector2i(800, 600); + nws.API = ContextAPI.OpenGL; + nws.NumberOfSamples = 4; + nws.APIVersion = new Version(4, 0, 0); + + window = new GameWindow(gws, nws); + + window.Load += OnLoad; + window.RenderFrame += OnRender; + + window.UpdateFrame += OnUpdate; + window.Unload += Unload; + window.Resize += OnResize; + + window.MouseMove += MouseMove; + window.KeyDown += KeyDown; + window.KeyUp += KeyUp; + + window.MouseWheel += MouseWheel; + + this.handler = handler; + handler.context = this; + glmanager = new GLResourceManager(); + } + + private void MouseWheel(MouseWheelEventArgs e) + { + handler.OnMouseWheel(e); + } + + public void Run(){ + window.Run(); + } + + private void OnLoad(){ + GL.Enable(EnableCap.DepthTest); + GL.Enable(EnableCap.Multisample); + GL.DebugMessageCallback(MessageCallback, IntPtr.Zero); + + handler.OnLoad(); + } + + public Vector2 mouseDelta = Vector2.Zero; + private void OnRender(FrameEventArgs e){ + mouseDelta = Vector2.Zero; + deltaTime = (float)e.Time; + + handler.OnRender(e); + } + + public void SwapBuffers() + { + window.SwapBuffers(); + } + + public Queue nonQueriedKeys = new Queue(); + + private void KeyDown(KeyboardKeyEventArgs e){ + nonQueriedKeys.Enqueue(new KeyEvent(KeyEventType.KeyDown, (Key)e.Key)); + } + + private void KeyUp(KeyboardKeyEventArgs e){ + nonQueriedKeys.Enqueue(new KeyEvent(KeyEventType.KeyUp, (Key)e.Key)); + } + + private void MouseMove(MouseMoveEventArgs e) + { + mouseDelta.X += e.DeltaX; + mouseDelta.Y += e.DeltaY; + } + + public float deltaTime = 0; + private void OnUpdate(FrameEventArgs e){ + deltaTime = (float)e.Time; + handler.OnUpdate(e); + } + + public void ResetFrameBuffer() + { + GL.Viewport(0, 0, window.Size.X, window.Size.Y); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + } + + private void Unload() + { + glmanager.Unload(); + handler.OnUnload(); + } + + private void OnResize(ResizeEventArgs args) + { + GL.Viewport(0, 0, args.Width, args.Height); + handler.OnResize(args); + } + + void MessageCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam) + { + if(severity == DebugSeverity.DebugSeverityHigh){ + Logger.Get("GraphicsLogger", "OrkEngine3D.Graphics").Log(LogMessageType.ERROR, + $"GL ERROR type = {type.ToString()}, severity = {severity.ToString()}, message = {Marshal.PtrToStringAuto(message)}"); + } else{ + Logger.Get("GraphicsLogger", "OrkEngine3D.Graphics").Log(LogMessageType.INFORMATION, + $"GL CALLBACK: {(type == DebugType.DebugTypeError ? "**GL ERROR**" : "")} type = {type.ToString()}, severity = {severity.ToString()}, message = {Marshal.PtrToStringAuto(message)}"); + } + } + + +} +public enum KeyEventType +{ + KeyDown, + KeyUp, +} +public struct KeyEvent +{ + + public KeyEventType eventType { get; set; } + public Key Key { get; set; } + + public KeyEvent(KeyEventType eventType, Key key) + { + this.eventType = eventType; + this.Key = key; + } + + [Obsolete("Use GetKeyDown(Key key)")] + public bool GetKeyDown() + { + if (eventType == KeyEventType.KeyDown) return true; + + return false; + } + + [Obsolete("Use GetKeyUp(Key key)")] + public bool GetKeyUp() + { + if (eventType == KeyEventType.KeyUp) return true; + + return false; + } + + public bool GetKeyDown(Key key) + { + if (Key == key && eventType == KeyEventType.KeyDown) return true; + + return false; + } + + public bool GetKeyUp(Key key) + { + if (Key == key && eventType == KeyEventType.KeyUp) return true; + + return false; + } +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/GraphicsBehaviour.cs b/source/OrkEngine3D.Graphics/TK/GraphicsBehaviour.cs new file mode 100644 index 0000000..f8d48d8 --- /dev/null +++ b/source/OrkEngine3D.Graphics/TK/GraphicsBehaviour.cs @@ -0,0 +1,59 @@ +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.GraphicsLibraryFramework; +using OrkEngine3D.Graphics.TK.Resources; + +namespace OrkEngine3D.Graphics.TK; + +public abstract class GraphicsBehaviour +{ + public GContext context; + + public CursorState CursorState + { + get => context.window.CursorState; + set => context.window.CursorState = value; + } + + public bool IsFocused => context.window.IsFocused; + + public MouseState MouseState => context.window.MouseState; + + public KeyboardState KeyboardState => context.window.KeyboardState; + + public Vector2i Size => context.window.Size; + + public GLResourceManager resourceManager { get { return context.glmanager; } } + + /// + /// On screen resize event + /// + public abstract void OnResize(ResizeEventArgs args); + + /// + /// Unload references, same as Dispose() + /// + public abstract void OnUnload(); + + /// + /// On application render event + /// + public abstract void OnRender(FrameEventArgs e); + + /// + /// On application update event + /// + public abstract void OnUpdate(FrameEventArgs e); + + //TODO: add more call events + public abstract void OnMouseWheel(MouseWheelEventArgs e); + + /// + /// On application load event + /// + public abstract void OnLoad(); + + public virtual void Close() { context.window.Close(); } + + public virtual void SwapBuffers() { context.window.SwapBuffers(); } +} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/GraphicsContext.cs b/source/OrkEngine3D.Graphics/TK/GraphicsContext.cs deleted file mode 100644 index 39c23ca..0000000 --- a/source/OrkEngine3D.Graphics/TK/GraphicsContext.cs +++ /dev/null @@ -1,143 +0,0 @@ -using OpenTK.Windowing.Common; -using OpenTK.Windowing.Desktop; -using OpenTK.Mathematics; -using OpenTK.Graphics.OpenGL4; -using System; -using OrkEngine3D.Graphics.TK.Resources; -using OrkEngine3D.Diagnostics.Logging; -using OrkEngine3D.Mathematics; -using Vector3 = OrkEngine3D.Mathematics.Vector3; -using Color4 = OrkEngine3D.Mathematics.Color4; -using Vector2 = OrkEngine3D.Mathematics.Vector2; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using OpenTK.Windowing.GraphicsLibraryFramework; - -namespace OrkEngine3D.Graphics.TK -{ - public class GraphicsContext - { - public GameWindow window; - public GLResourceManager glmanager; - public GraphicsHandler handler; - public GraphicsContext(string title, GraphicsHandler handler, bool msaa = true){ - var nws = NativeWindowSettings.Default; - var gws = GameWindowSettings.Default; - - nws.Title = title; - nws.Size = new Vector2i(800, 600); - nws.API = ContextAPI.OpenGL; - nws.NumberOfSamples = 4; - nws.APIVersion = new Version(4, 0, 0); - - window = new GameWindow(gws, nws); - - window.Load += OnLoad; - window.RenderFrame += OnRender; - - window.UpdateFrame += OnUpdate; - window.Unload += Unload; - window.Resize += OnResize; - - window.MouseMove += MouseMove; - window.KeyDown += KeyDown; - window.KeyUp += KeyUp; - - this.handler = handler; - handler.context = this; - glmanager = new GLResourceManager(); - } - public void Run(){ - window.Run(); - } - - private void OnLoad(){ - GL.Enable(EnableCap.DepthTest); - GL.Enable(EnableCap.Multisample); - GL.DebugMessageCallback(MessageCallback, IntPtr.Zero); - - handler.Init(); - - } - - public Vector2 mouseDelta = Vector2.Zero; - private void OnRender(FrameEventArgs e){ - mouseDelta = Vector2.Zero; - deltaTime = (float)e.Time; - - handler.Render(); - } - - public void SwapBuffers() - { - window.SwapBuffers(); - } - - - public Queue nonQueriedKeys = new Queue(); - - private void KeyDown(KeyboardKeyEventArgs e){ - nonQueriedKeys.Enqueue(new KeyEvent(KeyEventType.KeyDown, (Key)e.Key)); - } - - private void KeyUp(KeyboardKeyEventArgs e){ - nonQueriedKeys.Enqueue(new KeyEvent(KeyEventType.KeyUp, (Key)e.Key)); - } - - private void MouseMove(MouseMoveEventArgs e) - { - mouseDelta.X += e.DeltaX; - mouseDelta.Y += e.DeltaY; - } - - - public float deltaTime = 0; - private void OnUpdate(FrameEventArgs e){ - deltaTime = (float)e.Time; - handler.Update(); - } - - public void ResetFrameBuffer() - { - GL.Viewport(0, 0, window.Size.X, window.Size.Y); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); - } - - private void Unload(){ - glmanager.Unload(); - handler.Unload(); - } - - private void OnResize(ResizeEventArgs args){ - GL.Viewport(0, 0, args.Width, args.Height); - handler.Resize(); - } - - void MessageCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam) - { - if(severity == DebugSeverity.DebugSeverityHigh){ - Logger.Get("GraphicsLogger", "OrkEngine3D.Graphics").Log(LogMessageType.ERROR, - $"GL ERROR type = {type.ToString()}, severity = {severity.ToString()}, message = {Marshal.PtrToStringAuto(message)}"); - } else{ - Logger.Get("GraphicsLogger", "OrkEngine3D.Graphics").Log(LogMessageType.INFORMATION, - $"GL CALLBACK: {(type == DebugType.DebugTypeError ? "**GL ERROR**" : "")} type = {type.ToString()}, severity = {severity.ToString()}, message = {Marshal.PtrToStringAuto(message)}"); - } - } - - - } - public enum KeyEventType{ - KeyDown, - KeyUp, - } - public struct KeyEvent{ - public KeyEventType eventType; - public Key key; - - public KeyEvent(KeyEventType eventType, Key key) - { - this.eventType = eventType; - this.key = key; - } - } -} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/GraphicsHandler.cs b/source/OrkEngine3D.Graphics/TK/GraphicsHandler.cs deleted file mode 100644 index aa09ea8..0000000 --- a/source/OrkEngine3D.Graphics/TK/GraphicsHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -using OrkEngine3D.Graphics.TK; -using OrkEngine3D.Graphics.TK.Resources; -namespace OrkEngine3D.Graphics.TK -{ - public abstract class GraphicsHandler - { - public GraphicsContext context; - public GLResourceManager resourceManager { get { return context.glmanager; } } - - /// - /// On screen resize event - /// - public abstract void Resize(); - - /// - /// Unload references, same as Dispose() - /// - public abstract void Unload(); - - /// - /// On application render event - /// - public abstract void Render(); - - /// - /// On application update event - /// - public abstract void Update(); - - /// - /// On application load event - /// - public abstract void Init(); - } -} \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/IRenderTarget.cs b/source/OrkEngine3D.Graphics/TK/IRenderTarget.cs index 54ff88a..fe36866 100644 --- a/source/OrkEngine3D.Graphics/TK/IRenderTarget.cs +++ b/source/OrkEngine3D.Graphics/TK/IRenderTarget.cs @@ -1,16 +1,8 @@ -using OpenTK.Graphics.OpenGL4; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace OrkEngine3D.Graphics.TK; -namespace OrkEngine3D.Graphics.TK +public interface IRenderTarget { - public interface IRenderTarget - { - public void BindTarget(); - public void Clear(); - public void PreRender(); - } + public void BindTarget(); + public void Clear(); + public void PreRender(); } diff --git a/source/OrkEngine3D.Graphics/TK/IRenderable.cs b/source/OrkEngine3D.Graphics/TK/IRenderable.cs index 0603138..0e4cbfe 100644 --- a/source/OrkEngine3D.Graphics/TK/IRenderable.cs +++ b/source/OrkEngine3D.Graphics/TK/IRenderable.cs @@ -1,7 +1,6 @@ -namespace OrkEngine3D.Graphics +namespace OrkEngine3D.Graphics; + +public interface IRenderable { - public interface IRenderable - { - public abstract void Render(); - } + public abstract void Render(); } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Key.cs b/source/OrkEngine3D.Graphics/TK/Key.cs index 034e4ef..a05d5a0 100644 --- a/source/OrkEngine3D.Graphics/TK/Key.cs +++ b/source/OrkEngine3D.Graphics/TK/Key.cs @@ -7,611 +7,610 @@ // of the MIT license. See the LICENSE file for details. // -namespace OrkEngine3D.Graphics.TK +namespace OrkEngine3D.Graphics.TK; + +/// +/// Specifies key codes and modifiers in US keyboard layout. +/// +public enum Key : int { /// - /// Specifies key codes and modifiers in US keyboard layout. - /// - public enum Key : int - { - /// - /// An unknown key. - /// - Unknown = -1, - - /// - /// The spacebar key. - /// - Space = 32, - - /// - /// The apostrophe key. - /// - Apostrophe = 39 /* ' */, - - /// - /// The comma key. - /// - Comma = 44 /* , */, - - /// - /// The minus key. - /// - Minus = 45 /* - */, - - /// - /// The period key. - /// - Period = 46 /* . */, - - /// - /// The slash key. - /// - Slash = 47 /* / */, - - /// - /// The 0 key. - /// - D0 = 48, - - /// - /// The 1 key. - /// - D1 = 49, - - /// - /// The 2 key. - /// - D2 = 50, - - /// - /// The 3 key. - /// - D3 = 51, - - /// - /// The 4 key. - /// - D4 = 52, - - /// - /// The 5 key. - /// - D5 = 53, - - /// - /// The 6 key. - /// - D6 = 54, - - /// - /// The 7 key. - /// - D7 = 55, - - /// - /// The 8 key. - /// - D8 = 56, - - /// - /// The 9 key. - /// - D9 = 57, - - /// - /// The semicolon key. - /// - Semicolon = 59 /* ; */, - - /// - /// The equal key. - /// - Equal = 61 /* = */, - - /// - /// The A key. - /// - A = 65, - - /// - /// The B key. - /// - B = 66, - - /// - /// The C key. - /// - C = 67, - - /// - /// The D key. - /// - D = 68, - - /// - /// The E key. - /// - E = 69, - - /// - /// The F key. - /// - F = 70, - - /// - /// The G key. - /// - G = 71, - - /// - /// The H key. - /// - H = 72, - - /// - /// The I key. - /// - I = 73, - - /// - /// The J key. - /// - J = 74, - - /// - /// The K key. - /// - K = 75, - - /// - /// The L key. - /// - L = 76, - - /// - /// The M key. - /// - M = 77, - - /// - /// The N key. - /// - N = 78, - - /// - /// The O key. - /// - O = 79, - - /// - /// The P key. - /// - P = 80, - - /// - /// The Q key. - /// - Q = 81, - - /// - /// The R key. - /// - R = 82, - - /// - /// The S key. - /// - S = 83, - - /// - /// The T key. - /// - T = 84, - - /// - /// The U key. - /// - U = 85, - - /// - /// The V key. - /// - V = 86, - - /// - /// The W key. - /// - W = 87, - - /// - /// The X key. - /// - X = 88, - - /// - /// The Y key. - /// - Y = 89, - - /// - /// The Z key. - /// - Z = 90, - - /// - /// The left bracket(opening bracket) key. - /// - LeftBracket = 91 /* [ */, - - /// - /// The backslash. - /// - Backslash = 92 /* \ */, - - /// - /// The right bracket(closing bracket) key. - /// - RightBracket = 93 /* ] */, - - /// - /// The grave accent key. - /// - GraveAccent = 96 /* ` */, - - /// - /// The escape key. - /// - Escape = 256, - - /// - /// The enter key. - /// - Enter = 257, - - /// - /// The tab key. - /// - Tab = 258, - - /// - /// The backspace key. - /// - Backspace = 259, - - /// - /// The insert key. - /// - Insert = 260, - - /// - /// The delete key. - /// - Delete = 261, - - /// - /// The right arrow key. - /// - Right = 262, - - /// - /// The left arrow key. - /// - Left = 263, - - /// - /// The down arrow key. - /// - Down = 264, - - /// - /// The up arrow key. - /// - Up = 265, - - /// - /// The page up key. - /// - PageUp = 266, - - /// - /// The page down key. - /// - PageDown = 267, - - /// - /// The home key. - /// - Home = 268, - - /// - /// The end key. - /// - End = 269, - - /// - /// The caps lock key. - /// - CapsLock = 280, - - /// - /// The scroll lock key. - /// - ScrollLock = 281, - - /// - /// The num lock key. - /// - NumLock = 282, - - /// - /// The print screen key. - /// - PrintScreen = 283, - - /// - /// The pause key. - /// - Pause = 284, - - /// - /// The F1 key. - /// - F1 = 290, - - /// - /// The F2 key. - /// - F2 = 291, - - /// - /// The F3 key. - /// - F3 = 292, - - /// - /// The F4 key. - /// - F4 = 293, - - /// - /// The F5 key. - /// - F5 = 294, - - /// - /// The F6 key. - /// - F6 = 295, - - /// - /// The F7 key. - /// - F7 = 296, - - /// - /// The F8 key. - /// - F8 = 297, - - /// - /// The F9 key. - /// - F9 = 298, - - /// - /// The F10 key. - /// - F10 = 299, - - /// - /// The F11 key. - /// - F11 = 300, - - /// - /// The F12 key. - /// - F12 = 301, - - /// - /// The F13 key. - /// - F13 = 302, - - /// - /// The F14 key. - /// - F14 = 303, - - /// - /// The F15 key. - /// - F15 = 304, - - /// - /// The F16 key. - /// - F16 = 305, - - /// - /// The F17 key. - /// - F17 = 306, - - /// - /// The F18 key. - /// - F18 = 307, - - /// - /// The F19 key. - /// - F19 = 308, - - /// - /// The F20 key. - /// - F20 = 309, - - /// - /// The F21 key. - /// - F21 = 310, - - /// - /// The F22 key. - /// - F22 = 311, - - /// - /// The F23 key. - /// - F23 = 312, - - /// - /// The F24 key. - /// - F24 = 313, - - /// - /// The F25 key. - /// - F25 = 314, - - /// - /// The 0 key on the key pad. - /// - KeyPad0 = 320, - - /// - /// The 1 key on the key pad. - /// - KeyPad1 = 321, - - /// - /// The 2 key on the key pad. - /// - KeyPad2 = 322, - - /// - /// The 3 key on the key pad. - /// - KeyPad3 = 323, - - /// - /// The 4 key on the key pad. - /// - KeyPad4 = 324, - - /// - /// The 5 key on the key pad. - /// - KeyPad5 = 325, - - /// - /// The 6 key on the key pad. - /// - KeyPad6 = 326, - - /// - /// The 7 key on the key pad. - /// - KeyPad7 = 327, - - /// - /// The 8 key on the key pad. - /// - KeyPad8 = 328, - - /// - /// The 9 key on the key pad. - /// - KeyPad9 = 329, - - /// - /// The decimal key on the key pad. - /// - KeyPadDecimal = 330, - - /// - /// The divide key on the key pad. - /// - KeyPadDivide = 331, - - /// - /// The multiply key on the key pad. - /// - KeyPadMultiply = 332, - - /// - /// The subtract key on the key pad. - /// - KeyPadSubtract = 333, - - /// - /// The add key on the key pad. - /// - KeyPadAdd = 334, - - /// - /// The enter key on the key pad. - /// - KeyPadEnter = 335, - - /// - /// The equal key on the key pad. - /// - KeyPadEqual = 336, - - /// - /// The left shift key. - /// - LeftShift = 340, - - /// - /// The left control key. - /// - LeftControl = 341, - - /// - /// The left alt key. - /// - LeftAlt = 342, - - /// - /// The left super key. - /// - LeftSuper = 343, - - /// - /// The right shift key. - /// - RightShift = 344, - - /// - /// The right control key. - /// - RightControl = 345, - - /// - /// The right alt key. - /// - RightAlt = 346, - - /// - /// The right super key. - /// - RightSuper = 347, - - /// - /// The menu key. - /// - Menu = 348, - - /// - /// The last valid key in this enum. - /// - LastKey = Menu - } + /// An unknown key. + /// + Unknown = -1, + + /// + /// The spacebar key. + /// + Space = 32, + + /// + /// The apostrophe key. + /// + Apostrophe = 39 /* ' */, + + /// + /// The comma key. + /// + Comma = 44 /* , */, + + /// + /// The minus key. + /// + Minus = 45 /* - */, + + /// + /// The period key. + /// + Period = 46 /* . */, + + /// + /// The slash key. + /// + Slash = 47 /* / */, + + /// + /// The 0 key. + /// + D0 = 48, + + /// + /// The 1 key. + /// + D1 = 49, + + /// + /// The 2 key. + /// + D2 = 50, + + /// + /// The 3 key. + /// + D3 = 51, + + /// + /// The 4 key. + /// + D4 = 52, + + /// + /// The 5 key. + /// + D5 = 53, + + /// + /// The 6 key. + /// + D6 = 54, + + /// + /// The 7 key. + /// + D7 = 55, + + /// + /// The 8 key. + /// + D8 = 56, + + /// + /// The 9 key. + /// + D9 = 57, + + /// + /// The semicolon key. + /// + Semicolon = 59 /* ; */, + + /// + /// The equal key. + /// + Equal = 61 /* = */, + + /// + /// The A key. + /// + A = 65, + + /// + /// The B key. + /// + B = 66, + + /// + /// The C key. + /// + C = 67, + + /// + /// The D key. + /// + D = 68, + + /// + /// The E key. + /// + E = 69, + + /// + /// The F key. + /// + F = 70, + + /// + /// The G key. + /// + G = 71, + + /// + /// The H key. + /// + H = 72, + + /// + /// The I key. + /// + I = 73, + + /// + /// The J key. + /// + J = 74, + + /// + /// The K key. + /// + K = 75, + + /// + /// The L key. + /// + L = 76, + + /// + /// The M key. + /// + M = 77, + + /// + /// The N key. + /// + N = 78, + + /// + /// The O key. + /// + O = 79, + + /// + /// The P key. + /// + P = 80, + + /// + /// The Q key. + /// + Q = 81, + + /// + /// The R key. + /// + R = 82, + + /// + /// The S key. + /// + S = 83, + + /// + /// The T key. + /// + T = 84, + + /// + /// The U key. + /// + U = 85, + + /// + /// The V key. + /// + V = 86, + + /// + /// The W key. + /// + W = 87, + + /// + /// The X key. + /// + X = 88, + + /// + /// The Y key. + /// + Y = 89, + + /// + /// The Z key. + /// + Z = 90, + + /// + /// The left bracket(opening bracket) key. + /// + LeftBracket = 91 /* [ */, + + /// + /// The backslash. + /// + Backslash = 92 /* \ */, + + /// + /// The right bracket(closing bracket) key. + /// + RightBracket = 93 /* ] */, + + /// + /// The grave accent key. + /// + GraveAccent = 96 /* ` */, + + /// + /// The escape key. + /// + Escape = 256, + + /// + /// The enter key. + /// + Enter = 257, + + /// + /// The tab key. + /// + Tab = 258, + + /// + /// The backspace key. + /// + Backspace = 259, + + /// + /// The insert key. + /// + Insert = 260, + + /// + /// The delete key. + /// + Delete = 261, + + /// + /// The right arrow key. + /// + Right = 262, + + /// + /// The left arrow key. + /// + Left = 263, + + /// + /// The down arrow key. + /// + Down = 264, + + /// + /// The up arrow key. + /// + Up = 265, + + /// + /// The page up key. + /// + PageUp = 266, + + /// + /// The page down key. + /// + PageDown = 267, + + /// + /// The home key. + /// + Home = 268, + + /// + /// The end key. + /// + End = 269, + + /// + /// The caps lock key. + /// + CapsLock = 280, + + /// + /// The scroll lock key. + /// + ScrollLock = 281, + + /// + /// The num lock key. + /// + NumLock = 282, + + /// + /// The print screen key. + /// + PrintScreen = 283, + + /// + /// The pause key. + /// + Pause = 284, + + /// + /// The F1 key. + /// + F1 = 290, + + /// + /// The F2 key. + /// + F2 = 291, + + /// + /// The F3 key. + /// + F3 = 292, + + /// + /// The F4 key. + /// + F4 = 293, + + /// + /// The F5 key. + /// + F5 = 294, + + /// + /// The F6 key. + /// + F6 = 295, + + /// + /// The F7 key. + /// + F7 = 296, + + /// + /// The F8 key. + /// + F8 = 297, + + /// + /// The F9 key. + /// + F9 = 298, + + /// + /// The F10 key. + /// + F10 = 299, + + /// + /// The F11 key. + /// + F11 = 300, + + /// + /// The F12 key. + /// + F12 = 301, + + /// + /// The F13 key. + /// + F13 = 302, + + /// + /// The F14 key. + /// + F14 = 303, + + /// + /// The F15 key. + /// + F15 = 304, + + /// + /// The F16 key. + /// + F16 = 305, + + /// + /// The F17 key. + /// + F17 = 306, + + /// + /// The F18 key. + /// + F18 = 307, + + /// + /// The F19 key. + /// + F19 = 308, + + /// + /// The F20 key. + /// + F20 = 309, + + /// + /// The F21 key. + /// + F21 = 310, + + /// + /// The F22 key. + /// + F22 = 311, + + /// + /// The F23 key. + /// + F23 = 312, + + /// + /// The F24 key. + /// + F24 = 313, + + /// + /// The F25 key. + /// + F25 = 314, + + /// + /// The 0 key on the key pad. + /// + KeyPad0 = 320, + + /// + /// The 1 key on the key pad. + /// + KeyPad1 = 321, + + /// + /// The 2 key on the key pad. + /// + KeyPad2 = 322, + + /// + /// The 3 key on the key pad. + /// + KeyPad3 = 323, + + /// + /// The 4 key on the key pad. + /// + KeyPad4 = 324, + + /// + /// The 5 key on the key pad. + /// + KeyPad5 = 325, + + /// + /// The 6 key on the key pad. + /// + KeyPad6 = 326, + + /// + /// The 7 key on the key pad. + /// + KeyPad7 = 327, + + /// + /// The 8 key on the key pad. + /// + KeyPad8 = 328, + + /// + /// The 9 key on the key pad. + /// + KeyPad9 = 329, + + /// + /// The decimal key on the key pad. + /// + KeyPadDecimal = 330, + + /// + /// The divide key on the key pad. + /// + KeyPadDivide = 331, + + /// + /// The multiply key on the key pad. + /// + KeyPadMultiply = 332, + + /// + /// The subtract key on the key pad. + /// + KeyPadSubtract = 333, + + /// + /// The add key on the key pad. + /// + KeyPadAdd = 334, + + /// + /// The enter key on the key pad. + /// + KeyPadEnter = 335, + + /// + /// The equal key on the key pad. + /// + KeyPadEqual = 336, + + /// + /// The left shift key. + /// + LeftShift = 340, + + /// + /// The left control key. + /// + LeftControl = 341, + + /// + /// The left alt key. + /// + LeftAlt = 342, + + /// + /// The left super key. + /// + LeftSuper = 343, + + /// + /// The right shift key. + /// + RightShift = 344, + + /// + /// The right control key. + /// + RightControl = 345, + + /// + /// The right alt key. + /// + RightAlt = 346, + + /// + /// The right super key. + /// + RightSuper = 347, + + /// + /// The menu key. + /// + Menu = 348, + + /// + /// The last valid key in this enum. + /// + LastKey = Menu } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Material.cs b/source/OrkEngine3D.Graphics/TK/Material.cs index 98f0c0c..18d89d2 100644 --- a/source/OrkEngine3D.Graphics/TK/Material.cs +++ b/source/OrkEngine3D.Graphics/TK/Material.cs @@ -1,19 +1,13 @@ using OrkEngine3D.Graphics.TK.Resources; using OrkEngine3D.Mathematics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace OrkEngine3D.Graphics.TK +namespace OrkEngine3D.Graphics.TK; + +public class Material { - public class Material - { - public Color3 ambient = new Color3(1.0f, 1.0f, 1.0f); - public Color3 diffuse = new Color3(1.0f, 1.0f, 1.0f); - public Color3 specular = new Color3(1.0f, 1.0f, 1.0f); - public float shininess = 64f; - public ID[] textures = new ID[0]; - } + public Color3 ambient = new Color3(1.0f, 1.0f, 1.0f); + public Color3 diffuse = new Color3(1.0f, 1.0f, 1.0f); + public Color3 specular = new Color3(1.0f, 1.0f, 1.0f); + public float shininess = 64f; + public ID[] textures = new ID[0]; } diff --git a/source/OrkEngine3D.Graphics/TK/Rendering.cs b/source/OrkEngine3D.Graphics/TK/Rendering.cs index ad5738e..72fcb5c 100644 --- a/source/OrkEngine3D.Graphics/TK/Rendering.cs +++ b/source/OrkEngine3D.Graphics/TK/Rendering.cs @@ -1,208 +1,203 @@ -using OpenTK.Graphics.OpenGL4; -using OrkEngine3D.Core.Components; +using OrkEngine3D.Core.Components; using OrkEngine3D.Graphics.TK.Resources; using OrkEngine3D.Mathematics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using ClearBufferMask = OpenTK.Graphics.OpenGL4.ClearBufferMask; using GL = OpenTK.Graphics.OpenGL4.GL; using ShaderType = OrkEngine3D.Graphics.TK.Resources.ShaderType; -namespace OrkEngine3D.Graphics.TK +namespace OrkEngine3D.Graphics.TK; + +/* +public static class Rendering { - public static class Rendering - { - public static Camera currentCamera { get; private set; } - public static GraphicsContext currentContext { get; private set; } - public static Transform currentTransform { get; private set; } - public static IRenderTarget renderTarget { get; private set; } = WindowTarget.Global; - public static LightScene currentLightning { get; private set; } - public static Material[] currentMaterials { get; private set; } = new Material[] { new Material() }; - public static IRenderable currentRenderObject { get; private set; } - public static GLResourceManager currentResourceManager { get; private set; } - public static ShadowHandler shadowHandler { get; private set; } - public static bool isWireframe { get; private set; } - - private static readonly GLTarget GlTarget = new GLTarget(); - public static bool inShadowMode { get; private set; } - - public static void BindCamera(Camera camera) - { - currentCamera = camera; - } + public static Camera currentCamera { get; private set; } + public static GContext currentContext { get; private set; } + public static Transform currentTransform { get; private set; } + public static IRenderTarget renderTarget { get; private set; } = WindowTarget.Global; + public static LightScene currentLightning { get; private set; } + public static Material[] currentMaterials { get; private set; } = new Material[] { new Material() }; + public static IRenderable currentRenderObject { get; private set; } + public static GLResourceManager currentResourceManager { get; private set; } + public static ShadowHandler shadowHandler { get; private set; } + public static bool isWireframe { get; private set; } + + private static readonly GLTarget GlTarget = new GLTarget(); + public static bool inShadowMode { get; private set; } + + public static void BindCamera(Camera camera) + { + currentCamera = camera; + } - public static void BindContext(GraphicsContext ctx) - { - currentContext = ctx; - } + public static void BindContext(GContext ctx) + { + currentContext = ctx; + } - public static void BindLightning(LightScene light) - { - currentLightning = light; - } + public static void BindLightning(LightScene light) + { + currentLightning = light; + } - public static void BindMaterial(Material material) - { - currentMaterials = new[] { material }; - } + public static void BindMaterial(Material material) + { + currentMaterials = new[] { material }; + } - public static void BindMaterials(params Material[] materials) - { - currentMaterials = materials; - } + public static void BindMaterials(params Material[] materials) + { + currentMaterials = materials; + } - public static void BindTransform(Transform t) - { - currentTransform = t; - } + public static void BindTransform(Transform t) + { + currentTransform = t; + } - public static void BindTarget(ID id) - { - renderTarget = (IRenderTarget)currentResourceManager.GetResource(id); - } + public static void BindTarget(ID id) + { + renderTarget = (IRenderTarget)currentResourceManager.GetResource(id); + } - public static void ResetTarget() - { - renderTarget = GlTarget; - GlTarget.BindTarget(); - } + public static void ResetTarget() + { + renderTarget = GlTarget; + GlTarget.BindTarget(); + } - public static void ClearTarget() - { - renderTarget.Clear(); - } + public static void ClearTarget() + { + renderTarget.Clear(); + } - public static void SwapBuffers() - { - currentContext.SwapBuffers(); - } + public static void SwapBuffers() + { + currentContext.SwapBuffers(); + } - public static void Render(){ - currentRenderObject.Render(); - } + public static void Render(){ + currentRenderObject.Render(); + } - public static void BindRenderable(ID id){ - currentRenderObject = (IRenderable)currentResourceManager.GetResource(id); - } + public static void BindRenderable(ID id){ + currentRenderObject = (IRenderable)currentResourceManager.GetResource(id); + } - public static void BindResourceManager(GLResourceManager manager){ - currentResourceManager = manager; - } + public static void BindResourceManager(GLResourceManager manager){ + currentResourceManager = manager; + } - public static ID CreateMesh(){ - Mesh mesh = new Mesh(currentResourceManager); - return mesh.resourceid; - } + public static ID CreateMesh(){ + Mesh mesh = new Mesh(currentResourceManager); + return mesh.resourceid; + } - public static ID UpdateMeshVerticies(ID id, Vector3[] verticies){ - currentResourceManager.GetResource(id).verticies = verticies; - return id; - } + public static ID UpdateMeshVerticies(ID id, Vector3[] verticies){ + currentResourceManager.GetResource(id).verticies = verticies; + return id; + } - public static ID UpdateMeshTriangles(ID id, uint[] triangles){ - currentResourceManager.GetResource(id).triangles = triangles; - return id; - } + public static ID UpdateMeshTriangles(ID id, uint[] triangles){ + currentResourceManager.GetResource(id).triangles = triangles; + return id; + } - public static ID UpdateMeshUVs(ID id, Vector2[] uv){ - currentResourceManager.GetResource(id).uv = uv; - return id; - } + public static ID UpdateMeshUVs(ID id, Vector2[] uv){ + currentResourceManager.GetResource(id).uv = uv; + return id; + } - public static ID UpdateMeshNormals(ID id, Vector3[] normals){ - currentResourceManager.GetResource(id).normals = normals; - return id; - } + public static ID UpdateMeshNormals(ID id, Vector3[] normals){ + currentResourceManager.GetResource(id).normals = normals; + return id; + } - public static ID UpdateMeshMaterials(ID id, int[] materials){ - currentResourceManager.GetResource(id).materials = materials; - return id; - } + public static ID UpdateMeshMaterials(ID id, int[] materials){ + currentResourceManager.GetResource(id).materials = materials; + return id; + } - public static ID UpdateMeshShader(ID id, ID shader){ - currentResourceManager.GetResource(id).shader = currentResourceManager.GetResource(shader); - return id; - } + public static ID UpdateMeshShader(ID id, ID shader){ + currentResourceManager.GetResource(id).shader = currentResourceManager.GetResource(shader); + return id; + } - public static void UpdateMeshGLData(ID id){ - currentResourceManager.GetResource(id).UpdateGLData(); - } + public static void UpdateMeshGLData(ID id){ + currentResourceManager.GetResource(id).UpdateGLData(); + } - public static ID CreateTexture(TextureData data){ - Texture texture = new Texture(currentResourceManager, data); + public static ID CreateTexture(TextureData data){ + Texture texture = new Texture(currentResourceManager, data); - return texture.resourceid; - } + return texture.resourceid; + } - public static ID CreateShaderProgram(params ID[] shaders){ - Shader[] s = new Shader[shaders.Length]; - for(int i = 0; i < s.Length; i++) s[i] = currentResourceManager.GetResource(shaders[i]); - ShaderProgram shaderProgram = new ShaderProgram(currentResourceManager, s); - return shaderProgram.resourceid; - } + public static ID CreateShaderProgram(params ID[] shaders){ + Shader[] s = new Shader[shaders.Length]; + for(int i = 0; i < s.Length; i++) s[i] = currentResourceManager.GetResource(shaders[i]); + ShaderProgram shaderProgram = new ShaderProgram(currentResourceManager, s); + return shaderProgram.resourceid; + } - public static ID CreateShader(string source, ShaderType type){ - Shader s = new Shader(currentResourceManager, source, type); - return s.resourceid; - } + public static ID CreateShader(string source, ShaderType type){ + Shader s = new Shader(currentResourceManager, source, type); + return s.resourceid; + } - public static ID CreateRenderBuffer(int width, int height){ - RenderBuffer renderBuffer = new RenderBuffer(currentResourceManager, width, height); - return renderBuffer.resourceid; - } + public static ID CreateRenderBuffer(int width, int height){ + RenderBuffer renderBuffer = new RenderBuffer(currentResourceManager, width, height); + return renderBuffer.resourceid; + } - public static void EnableWireframe() - { - isWireframe = true; - } - - public static void DisableWireframe() - { - isWireframe = false; - } + public static void EnableWireframe() + { + isWireframe = true; + } + + public static void DisableWireframe() + { + isWireframe = false; + } - public static ID CreateShadowManager() - { - ShadowHandler shadowHandler = new ShadowHandler(currentResourceManager); - return shadowHandler.resourceid; - } + public static ID CreateShadowManager() + { + ShadowHandler shadowHandler = new ShadowHandler(currentResourceManager); + return shadowHandler.resourceid; + } - public static void BindShadowManager(ID id) - { - shadowHandler = currentResourceManager.GetResource(id); - } + public static void BindShadowManager(ID id) + { + shadowHandler = currentResourceManager.GetResource(id); + } + + public static void EnterShadowMode() + { + shadowHandler.BindTarget(); + inShadowMode = true; + } - public static void EnterShadowMode() + public static void ExitShadowMode() + { + inShadowMode = false; + } + + + internal class GLTarget : IRenderTarget + { + public void BindTarget() { - shadowHandler.BindTarget(); - inShadowMode = true; + currentContext.ResetFrameBuffer(); } - public static void ExitShadowMode() + public void Clear() { - inShadowMode = false; + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } - - internal class GLTarget : IRenderTarget + public void PreRender() { - public void BindTarget() - { - currentContext.ResetFrameBuffer(); - } - - public void Clear() - { - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - } - - public void PreRender() - { - - } + } } } +*/ diff --git a/source/OrkEngine3D.Graphics/TK/Resources/GLResource.cs b/source/OrkEngine3D.Graphics/TK/Resources/GLResource.cs index 395a201..6433e56 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/GLResource.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/GLResource.cs @@ -1,16 +1,15 @@ -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +/// +/// GLResource is a resource wich contains non-managed OpenGL resources, such as shaders, buffers etc +/// +public abstract class GLResource { - /// - /// GLResource is a resource wich contains non-managed OpenGL resources, such as shaders, buffers etc - /// - public abstract class GLResource - { - public ID resourceid; - public GLResource(GLResourceManager manager){ - this.resourceid = new ID(); - if(manager != null) - manager.resources.Add(resourceid, this); - } - public abstract void Unload(); + public ID resourceid; + public GLResource(GLResourceManager manager){ + this.resourceid = new ID(); + if(manager != null) + manager.resources.Add(resourceid, this); } + public abstract void Unload(); } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/GLResourceManager.cs b/source/OrkEngine3D.Graphics/TK/Resources/GLResourceManager.cs index a08466d..73345f2 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/GLResourceManager.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/GLResourceManager.cs @@ -1,26 +1,25 @@ using System.Collections.Generic; using System.Linq; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +public class GLResourceManager { - public class GLResourceManager - { - public Dictionary resources = new Dictionary(); + public Dictionary resources = new Dictionary(); - public void Unload(){ - for (var i = 0; i < resources.Count; i++) - { - resources.Values.ToArray()[i].Unload(); - } - resources.Clear(); + public void Unload(){ + for (var i = 0; i < resources.Count; i++) + { + resources.Values.ToArray()[i].Unload(); } + resources.Clear(); + } - public GLResource GetResource(ID id){ - return resources[id]; - } + public GLResource GetResource(ID id){ + return resources[id]; + } - public T GetResource(ID id) where T : GLResource{ - return (T)GetResource(id); - } + public T GetResource(ID id) where T : GLResource{ + return (T)GetResource(id); } } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/ID.cs b/source/OrkEngine3D.Graphics/TK/Resources/ID.cs index 72defc2..4a48b66 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/ID.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/ID.cs @@ -2,30 +2,29 @@ using System.Text; using System; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +public struct ID { - public struct ID - { - public string hash; - public ID(){ - this.hash = ""; - this.hash = CreateMD5Hash(Guid.NewGuid().ToString()); - } + public string hash; + public ID(){ + this.hash = ""; + this.hash = CreateMD5Hash(Guid.NewGuid().ToString()); + } - private string CreateMD5Hash(string input) + private string CreateMD5Hash(string input) + { + // Step 1, calculate MD5 hash from input + MD5 md5 = MD5.Create(); + byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); + byte[] hashBytes = md5.ComputeHash(inputBytes); + + // Step 2, convert byte array to hex string + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < hashBytes.Length; i++) { - // Step 1, calculate MD5 hash from input - MD5 md5 = MD5.Create(); - byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); - byte[] hashBytes = md5.ComputeHash(inputBytes); - - // Step 2, convert byte array to hex string - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < hashBytes.Length; i++) - { - sb.Append(hashBytes[i].ToString("X2")); - } - return sb.ToString(); + sb.Append(hashBytes[i].ToString("X2")); } + return sb.ToString(); } } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/Mesh.cs b/source/OrkEngine3D.Graphics/TK/Resources/Mesh.cs index 441b24b..14ecd5b 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/Mesh.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/Mesh.cs @@ -1,225 +1,224 @@ -using System; -using System.Collections.Generic; using OpenTK.Graphics.OpenGL4; -using System.Linq; using OrkEngine3D.Mathematics; using OrkEngine3D.Diagnostics.Logging; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +/* +/// +/// A mesh. +/// +public class Mesh : GLResource, IRenderable { + int VBO; + int VAO; + int EBO; + /// - /// A mesh. + /// The verticies of the mesh /// - public class Mesh : GLResource, IRenderable - { - int VBO; - int VAO; - int EBO; - - /// - /// The verticies of the mesh - /// - public Vector3[] verticies = new Vector3[0]; - - /// - /// The UVs of the mesh - /// - public Vector2[] uv = new Vector2[0]; - - /// - /// The vertex colours of the mesh - /// - public Color4[] colors = new Color4[0]; - - /// - /// The mesh normals - /// - public Vector3[] normals = new Vector3[0]; - - /// - /// The triangles of the mesh - /// - public uint[] triangles = new uint[0]; - - /// - /// What shader should the mesh use? - /// - public ShaderProgram shader; - - public int[] materials; - - /// - /// Creates the mesh and allocates all resources - /// - /// - /// The mesh - public Mesh(GLResourceManager manager) : base(manager) - { - VBO = GL.GenBuffer(); - VAO = GL.GenVertexArray(); - EBO = GL.GenBuffer(); - } + public Vector3[] verticies = new Vector3[0]; - /// - /// Updates the GPU end of the mesh, make sure the meshes shader is set, as it will try to locate shader variables - /// + /// + /// The UVs of the mesh + /// + public Vector2[] uv = new Vector2[0]; - public void UpdateGLData(){ - // We cannot locate variables in a non-existent - if(shader == null) - Logger.Get("ShaderLoader", "Graphics").Log(LogMessageType.FATAL, "Shader is null, make sure to set shader before updating data!"); - - // Floats per vertex - int floatsperv = 3 + 3 + 2 + 4 + 1; // Vec3 + Vec3 + Vec2 + Col4 + int - float[] bakedData = new float[verticies.Length * floatsperv]; // The baked vertex data array + /// + /// The vertex colours of the mesh + /// + public Color4[] colors = new Color4[0]; - for (var i = 0; i < verticies.Length; i++) - { - /* - Each vertex is stored in a piece of bakedData, in the order: - pos.x - pos.y - pos.z - uv.x - uv.y - color.r - color.g - color.b - color.a - */ - bakedData[i * floatsperv + 0] = verticies[i].X; - bakedData[i * floatsperv + 1] = verticies[i].Y; - bakedData[i * floatsperv + 2] = verticies[i].Z; - bakedData[i * floatsperv + 3] = (uv.Length > 0 ? uv[i].X : 0); - bakedData[i * floatsperv + 4] = (uv.Length > 0 ? uv[i].Y : 0); - bakedData[i * floatsperv + 5] = (colors.Length > 0 ? colors[i].Red : 0); - bakedData[i * floatsperv + 6] = (colors.Length > 0 ? colors[i].Green : 0); - bakedData[i * floatsperv + 7] = (colors.Length > 0 ? colors[i].Blue : 0); - bakedData[i * floatsperv + 8] = (colors.Length > 0 ? colors[i].Alpha : 0); - bakedData[i * floatsperv + 9] = (normals.Length > 0 ? normals[i].X : 0); - bakedData[i * floatsperv + 10] = (normals.Length > 0 ? normals[i].Y: 0); - bakedData[i * floatsperv + 11] = (normals.Length > 0 ? normals[i].Z : 0); - bakedData[i * floatsperv + 12] = (materials.Length > 0 ? materials[i] : 0); - } + /// + /// The mesh normals + /// + public Vector3[] normals = new Vector3[0]; - GL.BindVertexArray(VAO); // Bind our vertex array + /// + /// The triangles of the mesh + /// + public uint[] triangles = new uint[0]; - GL.BindBuffer(BufferTarget.ElementArrayBuffer, EBO); - GL.BufferData(BufferTarget.ElementArrayBuffer, triangles.Length * sizeof(uint), triangles, BufferUsageHint.StaticDraw); + /// + /// What shader should the mesh use? + /// + public ShaderProgram shader; - GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); // Bind buffer + public int[] materials; - GL.BufferData(BufferTarget.ArrayBuffer, bakedData.Length * sizeof(float), bakedData, BufferUsageHint.StaticDraw); // Set buffer data to baked vertex data + /// + /// Creates the mesh and allocates all resources + /// + /// + /// The mesh + public Mesh(GLResourceManager manager) : base(manager) + { + VBO = GL.GenBuffer(); + VAO = GL.GenVertexArray(); + EBO = GL.GenBuffer(); + } - int vpos = shader.GetAttribLocation("vert_position"); - int vuv = shader.GetAttribLocation("vert_uv"); - int vcol = shader.GetAttribLocation("vert_color"); - int vnorm = shader.GetAttribLocation("vert_normal"); - int vmat = shader.GetAttribLocation("vert_material"); + /// + /// Updates the GPU end of the mesh, make sure the meshes shader is set, as it will try to locate shader variables + /// - GL.VertexAttribPointer(vpos, 3, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 0 * sizeof(float)); - GL.EnableVertexAttribArray(vpos); + public void UpdateGLData(){ + // We cannot locate variables in a non-existent + if(shader == null) + Logger.Get("ShaderLoader", "Graphics").Log(LogMessageType.FATAL, "Shader is null, make sure to set shader before updating data!"); + + // Floats per vertex + int floatsperv = 3 + 3 + 2 + 4 + 1; // Vec3 + Vec3 + Vec2 + Col4 + int + float[] bakedData = new float[verticies.Length * floatsperv]; // The baked vertex data array - GL.VertexAttribPointer(vuv, 2, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 3 * sizeof(float)); - GL.EnableVertexAttribArray(vuv); + for (var i = 0; i < verticies.Length; i++) + { + /* + Each vertex is stored in a piece of bakedData, in the order: + pos.x + pos.y + pos.z + uv.x + uv.y + color.r + color.g + color.b + color.a + * + bakedData[i * floatsperv + 0] = verticies[i].X; + bakedData[i * floatsperv + 1] = verticies[i].Y; + bakedData[i * floatsperv + 2] = verticies[i].Z; + bakedData[i * floatsperv + 3] = (uv.Length > 0 ? uv[i].X : 0); + bakedData[i * floatsperv + 4] = (uv.Length > 0 ? uv[i].Y : 0); + bakedData[i * floatsperv + 5] = (colors.Length > 0 ? colors[i].Red : 0); + bakedData[i * floatsperv + 6] = (colors.Length > 0 ? colors[i].Green : 0); + bakedData[i * floatsperv + 7] = (colors.Length > 0 ? colors[i].Blue : 0); + bakedData[i * floatsperv + 8] = (colors.Length > 0 ? colors[i].Alpha : 0); + bakedData[i * floatsperv + 9] = (normals.Length > 0 ? normals[i].X : 0); + bakedData[i * floatsperv + 10] = (normals.Length > 0 ? normals[i].Y: 0); + bakedData[i * floatsperv + 11] = (normals.Length > 0 ? normals[i].Z : 0); + bakedData[i * floatsperv + 12] = (materials.Length > 0 ? materials[i] : 0); + } - GL.VertexAttribPointer(vcol, 4, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 5 * sizeof(float)); - GL.EnableVertexAttribArray(vcol); + GL.BindVertexArray(VAO); // Bind our vertex array - GL.VertexAttribPointer(vnorm, 3, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 9 * sizeof(float)); - GL.EnableVertexAttribArray(vnorm); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, EBO); + GL.BufferData(BufferTarget.ElementArrayBuffer, triangles.Length * sizeof(uint), triangles, BufferUsageHint.StaticDraw); - GL.VertexAttribPointer(vmat, 1, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 12 * sizeof(float)); - GL.EnableVertexAttribArray(vmat); + GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); // Bind buffer - } + GL.BufferData(BufferTarget.ArrayBuffer, bakedData.Length * sizeof(float), bakedData, BufferUsageHint.StaticDraw); // Set buffer data to baked vertex data - /// - /// Render the mesh. - /// - /// The active camera object - /// The meshes transform - /// The current GraphicsContext - public void Render(){ - if (Rendering.inShadowMode) - { - RenderShadow(); - return; - } - GL.BindVertexArray(VAO); - shader.Use(); - shader.UniformMatrix("matx_view", Rendering.currentCamera.GetMatrix()); - shader.UniformMatrix("matx_model", Rendering.currentTransform.GetMatrix()); - shader.Uniform1("ambient.strength", Rendering.currentLightning.ambient.strength); - shader.Uniform3("ambient.color", Rendering.currentLightning.ambient.color); - shader.Uniform3("ambient.position", Rendering.currentLightning.ambient.position); + int vpos = shader.GetAttribLocation("vert_position"); + int vuv = shader.GetAttribLocation("vert_uv"); + int vcol = shader.GetAttribLocation("vert_color"); + int vnorm = shader.GetAttribLocation("vert_normal"); + int vmat = shader.GetAttribLocation("vert_material"); - shader.Uniform3("camera_pos", Rendering.currentCamera.transform.position); + GL.VertexAttribPointer(vpos, 3, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 0 * sizeof(float)); + GL.EnableVertexAttribArray(vpos); - for (int i = 0; i < Rendering.currentLightning.lights.Length; i++) - { - Light light = Rendering.currentLightning.lights[i]; - shader.Uniform1("lights[0].strength", light.strength); - shader.Uniform3("lights[0].color", light.color); - shader.Uniform3("lights[0].position", light.position); - } + GL.VertexAttribPointer(vuv, 2, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 3 * sizeof(float)); + GL.EnableVertexAttribArray(vuv); - shader.Uniform1("lights_count", Rendering.currentLightning.lights.Length); + GL.VertexAttribPointer(vcol, 4, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 5 * sizeof(float)); + GL.EnableVertexAttribArray(vcol); - for (int i = 0; i < Rendering.currentMaterials.Length; i++) - { - Material material = Rendering.currentMaterials[i]; + GL.VertexAttribPointer(vnorm, 3, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 9 * sizeof(float)); + GL.EnableVertexAttribArray(vnorm); - shader.Uniform3($"materials[{i}].ambient", material.ambient); - shader.Uniform3($"materials[{i}].diffuse", material.diffuse); - shader.Uniform3($"materials[{i}].specular", material.specular); + GL.VertexAttribPointer(vmat, 1, VertexAttribPointerType.Float, false, floatsperv * sizeof(float), 12 * sizeof(float)); + GL.EnableVertexAttribArray(vmat); - shader.Uniform1($"materials[{i}].shininess", material.shininess); + } + /// + /// Render the mesh. + /// + /// The active camera object + /// The meshes transform + /// The current GraphicsContext + public void Render(){ + if (Rendering.inShadowMode) + { + RenderShadow(); + return; + } + GL.BindVertexArray(VAO); + shader.Use(); + shader.UniformMatrix("matx_view", Rendering.currentCamera.GetMatrix()); + shader.UniformMatrix("matx_model", Rendering.currentTransform.GetMatrix()); + shader.Uniform1("ambient.strength", Rendering.currentLightning.ambient.strength); + shader.Uniform3("ambient.color", Rendering.currentLightning.ambient.color); + shader.Uniform3("ambient.position", Rendering.currentLightning.ambient.position); + shader.Uniform3("camera_pos", Rendering.currentCamera.transform.position); - for (byte t = 0; t < material.textures.Length; t++) - { - shader.Uniform1($"material_textures[{i * 4 + t}]", t); - Rendering.currentResourceManager.GetResource(material.textures[t]).Use(t); - } - + for (int i = 0; i < Rendering.currentLightning.lights.Length; i++) + { + Light light = Rendering.currentLightning.lights[i]; + shader.Uniform1("lights[0].strength", light.strength); + shader.Uniform3("lights[0].color", light.color); + shader.Uniform3("lights[0].position", light.position); + } - } - - //TODO: CONTINUE HERE: https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping + shader.Uniform1("lights_count", Rendering.currentLightning.lights.Length); + + for (int i = 0; i < Rendering.currentMaterials.Length; i++) + { + Material material = Rendering.currentMaterials[i]; + + shader.Uniform3($"materials[{i}].ambient", material.ambient); + shader.Uniform3($"materials[{i}].diffuse", material.diffuse); + shader.Uniform3($"materials[{i}].specular", material.specular); + + shader.Uniform1($"materials[{i}].shininess", material.shininess); - if (Rendering.shadowHandler != null) + + + for (byte t = 0; t < material.textures.Length; t++) { - ShadowHandler shadowHandler = Rendering.shadowHandler; - shader.Uniform1($"material_shadowMap", 31); - GL.ActiveTexture(TextureUnit.Texture31); - GL.BindTexture(TextureTarget.Texture2D, shadowHandler.depthMap); + shader.Uniform1($"material_textures[{i * 4 + t}]", t); + Rendering.currentResourceManager.GetResource(material.textures[t]).Use(t); } + - GL.PolygonMode(MaterialFace.FrontAndBack, - Rendering.isWireframe ? - PolygonMode.Line : PolygonMode.Fill); - Rendering.renderTarget.PreRender(); - GL.DrawElements(PrimitiveType.Triangles, triangles.Length, DrawElementsType.UnsignedInt, 0); } + + //TODO: CONTINUE HERE: https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping - private void RenderShadow() + if (Rendering.shadowHandler != null) { - GL.BindVertexArray(VAO); - Rendering.shadowHandler.PreRender(); - Rendering.shadowHandler.shaderProgram.UniformMatrix("model", Rendering.currentTransform.GetMatrix()); - GL.DrawElements(PrimitiveType.Triangles, triangles.Length, DrawElementsType.UnsignedInt, 0); + ShadowHandler shadowHandler = Rendering.shadowHandler; + shader.Uniform1($"material_shadowMap", 31); + GL.ActiveTexture(TextureUnit.Texture31); + GL.BindTexture(TextureTarget.Texture2D, shadowHandler.depthMap); } - /// - /// Unload the mesh - /// - public override void Unload() - { - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - GL.DeleteBuffer(VBO); - GL.DeleteVertexArray(VAO); - } + GL.PolygonMode(MaterialFace.FrontAndBack, + Rendering.isWireframe ? + PolygonMode.Line : PolygonMode.Fill); + Rendering.renderTarget.PreRender(); + GL.DrawElements(PrimitiveType.Triangles, triangles.Length, DrawElementsType.UnsignedInt, 0); + } + + private void RenderShadow() + { + GL.BindVertexArray(VAO); + Rendering.shadowHandler.PreRender(); + Rendering.shadowHandler.shaderProgram.UniformMatrix("model", Rendering.currentTransform.GetMatrix()); + GL.DrawElements(PrimitiveType.Triangles, triangles.Length, DrawElementsType.UnsignedInt, 0); } -} \ No newline at end of file + + /// + /// Unload the mesh + /// + public override void Unload() + { + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.DeleteBuffer(VBO); + GL.DeleteVertexArray(VAO); + } +} + +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/PostProcessingEffect.cs b/source/OrkEngine3D.Graphics/TK/Resources/PostProcessingEffect.cs index dd8a3d4..5289f82 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/PostProcessingEffect.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/PostProcessingEffect.cs @@ -1,13 +1,14 @@ -namespace OrkEngine3D.Graphics.TK.Resources -{ - using OpenTK.Graphics.OpenGL4; +namespace OrkEngine3D.Graphics.TK.Resources; - public class PostProcessingEffect : GLResource - { - public ID Id; - private readonly ID shaderId; +using OpenTK.Graphics.OpenGL4; + +/* +public class PostProcessingEffect : GLResource +{ + public ID Id; + private readonly ID shaderId; - private readonly ID vertexShader = Rendering.CreateShader(@" + private readonly ID vertexShader = Rendering.CreateShader(@" #version 400 core const vec4 data[6] = vec4[] ( @@ -29,29 +30,29 @@ void main() } ", ShaderType.VertexShader); - private readonly ID buffer; - - public PostProcessingEffect(GLResourceManager manager, string shader, int width, int height) : base(manager) { - ID fragShader = Rendering.CreateShader(shader, ShaderType.FragmentShader); - shaderId = Rendering.CreateShaderProgram(vertexShader, fragShader); - buffer = Rendering.CreateRenderBuffer(width, height); - } - public override void Unload() - { - throw new System.NotImplementedException(); - } - - public void PreRender(){ - Rendering.BindTarget(buffer); - } - - public void Render() - { - Rendering.currentResourceManager.GetResource(shaderId).Use(); - Rendering.currentResourceManager.GetResource(buffer).target.Use(0); - Rendering.currentResourceManager.GetResource(shaderId).Uniform1("frame", 0); - GL.DrawArrays(PrimitiveType.Triangles, 0, 6); - } + private readonly ID buffer; + + public PostProcessingEffect(GLResourceManager manager, string shader, int width, int height) : base(manager) { + ID fragShader = Rendering.CreateShader(shader, ShaderType.FragmentShader); + shaderId = Rendering.CreateShaderProgram(vertexShader, fragShader); + buffer = Rendering.CreateRenderBuffer(width, height); + } + public override void Unload() + { + throw new System.NotImplementedException(); + } + + public void PreRender(){ + Rendering.BindTarget(buffer); + } + public void Render() + { + Rendering.currentResourceManager.GetResource(shaderId).Use(); + Rendering.currentResourceManager.GetResource(buffer).target.Use(0); + Rendering.currentResourceManager.GetResource(shaderId).Uniform1("frame", 0); + GL.DrawArrays(PrimitiveType.Triangles, 0, 6); } -} \ No newline at end of file + +} +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/RenderBuffer.cs b/source/OrkEngine3D.Graphics/TK/Resources/RenderBuffer.cs index a581283..aa5a631 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/RenderBuffer.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/RenderBuffer.cs @@ -1,71 +1,68 @@ using OpenTK.Graphics.OpenGL4; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +/* +public class RenderBuffer : GLResource, IRenderTarget { - public class RenderBuffer : GLResource, IRenderTarget - { - public int id; - public int depthBuffer; - public readonly Texture target; + public int id; + public int depthBuffer; + public readonly Texture target; - public RenderBuffer(GLResourceManager manager, int width, int height) : base(manager) - { - id = GL.GenFramebuffer(); + public RenderBuffer(GLResourceManager manager, int width, int height) : base(manager) + { + id = GL.GenFramebuffer(); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, id); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, id); - int renderedTexture; - renderedTexture = GL.GenTexture(); + int renderedTexture; + renderedTexture = GL.GenTexture(); - // "Bind" the newly created texture : all future texture functions will modify this texture - GL.BindTexture(TextureTarget.Texture2D, renderedTexture); + // "Bind" the newly created texture : all future texture functions will modify this texture + GL.BindTexture(TextureTarget.Texture2D, renderedTexture); - // Give an empty image to OpenGL ( the last "0" ) - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 1024, 768, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero); + // Give an empty image to OpenGL ( the last "0" ) + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 1024, 768, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero); - // Poor filtering. Needed ! - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + // Poor filtering. Needed ! + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - target = new Texture(manager, renderedTexture, width, height); + target = new Texture(manager, renderedTexture, width, height); - depthBuffer = GL.GenRenderbuffer(); - GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); - GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, width, height); - GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); + depthBuffer = GL.GenRenderbuffer(); + GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); + GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, width, height); + GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); - GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, renderedTexture, 0); + GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, renderedTexture, 0); - DrawBuffersEnum[] DrawBuffers = { DrawBuffersEnum.ColorAttachment0 }; - GL.DrawBuffers(1, DrawBuffers); - } + DrawBuffersEnum[] DrawBuffers = { DrawBuffersEnum.ColorAttachment0 }; + GL.DrawBuffers(1, DrawBuffers); + } - public void BindTarget() - { - GL.BindFramebuffer(FramebufferTarget.Framebuffer, id); - GL.Viewport(0, 0, target.width, target.height); - } + public void BindTarget() + { + GL.BindFramebuffer(FramebufferTarget.Framebuffer, id); + GL.Viewport(0, 0, target.width, target.height); + } - public void Clear() - { - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - } + public void Clear() + { + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + } - public void PreRender() - { - - } + public void PreRender() + { + + } - public override void Unload() - { - GL.DeleteRenderbuffer(id); - GL.DeleteFramebuffer(id); - } + public override void Unload() + { + GL.DeleteRenderbuffer(id); + GL.DeleteFramebuffer(id); } } +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/Shader.cs b/source/OrkEngine3D.Graphics/TK/Resources/Shader.cs index b361846..f197850 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/Shader.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/Shader.cs @@ -1,34 +1,219 @@ -using OpenTK.Graphics.OpenGL4; +using OpenTK.Graphics.OpenGL4; using OrkEngine3D.Diagnostics.Logging; +using System.Collections.Generic; +using System; +using System.IO; +using OpenTK.Mathematics; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +// A simple class meant to help create shaders. +public class Shader +{ + public readonly int Handle; + + private readonly Dictionary _uniformLocations; + + // This is how you create a simple shader. + // Shaders are written in GLSL, which is a language very similar to C in its semantics. + // The GLSL source is compiled *at runtime*, so it can optimize itself for the graphics card it's currently being used on. + // A commented example of GLSL can be found in shader.vert. + public Shader(string vertPath, string fragPath) + { + // There are several different types of shaders, but the only two you need for basic rendering are the vertex and fragment shaders. + // The vertex shader is responsible for moving around vertices, and uploading that data to the fragment shader. + // The vertex shader won't be too important here, but they'll be more important later. + // The fragment shader is responsible for then converting the vertices to "fragments", which represent all the data OpenGL needs to draw a pixel. + // The fragment shader is what we'll be using the most here. + + // Load vertex shader and compile + var shaderSource = File.ReadAllText(vertPath); + + // GL.CreateShader will create an empty shader (obviously). The ShaderType enum denotes which type of shader will be created. + var vertexShader = GL.CreateShader((OpenTK.Graphics.OpenGL4.ShaderType)ShaderType.VertexShader); + + // Now, bind the GLSL source code + GL.ShaderSource(vertexShader, shaderSource); + + // And then compile + CompileShader(vertexShader); + + // We do the same for the fragment shader. + shaderSource = File.ReadAllText(fragPath); + var fragmentShader = GL.CreateShader((OpenTK.Graphics.OpenGL4.ShaderType)ShaderType.FragmentShader); + GL.ShaderSource(fragmentShader, shaderSource); + CompileShader(fragmentShader); + + // These two shaders must then be merged into a shader program, which can then be used by OpenGL. + // To do this, create a program... + Handle = GL.CreateProgram(); + + // Attach both shaders... + GL.AttachShader(Handle, vertexShader); + GL.AttachShader(Handle, fragmentShader); + + // And then link them together. + LinkProgram(Handle); + + // When the shader program is linked, it no longer needs the individual shaders attached to it; the compiled code is copied into the shader program. + // Detach them, and then delete them. + GL.DetachShader(Handle, vertexShader); + GL.DetachShader(Handle, fragmentShader); + GL.DeleteShader(fragmentShader); + GL.DeleteShader(vertexShader); + + // The shader is now ready to go, but first, we're going to cache all the shader uniform locations. + // Querying this from the shader is very slow, so we do it once on initialization and reuse those values + // later. + + // First, we have to get the number of active uniforms in the shader. + GL.GetProgram(Handle, GetProgramParameterName.ActiveUniforms, out var numberOfUniforms); + + // Next, allocate the dictionary to hold the locations. + _uniformLocations = new Dictionary(); + + // Loop over all the uniforms, + for (var i = 0; i < numberOfUniforms; i++) + { + // get the name of this uniform, + var key = GL.GetActiveUniform(Handle, i, out _, out _); + + // get the location, + var location = GL.GetUniformLocation(Handle, key); + + // and then add it to the dictionary. + _uniformLocations.Add(key, location); + } + } + + private static void CompileShader(int shader) + { + // Try to compile the shader + GL.CompileShader(shader); + + // Check for compilation errors + GL.GetShader(shader, ShaderParameter.CompileStatus, out var code); + if (code != (int)All.True) + { + // We can use `GL.GetShaderInfoLog(shader)` to get information about the error. + var infoLog = GL.GetShaderInfoLog(shader); + throw new Exception($"Error occurred whilst compiling Shader({shader}).\n\n{infoLog}"); + } + } + + private static void LinkProgram(int program) + { + // We link the program + GL.LinkProgram(program); + + // Check for linking errors + GL.GetProgram(program, GetProgramParameterName.LinkStatus, out var code); + if (code != (int)All.True) + { + // We can use `GL.GetProgramInfoLog(program)` to get information about the error. + throw new Exception($"Error occurred whilst linking Program({program})"); + } + } + + // A wrapper function that enables the shader program. + public void Use() + { + GL.UseProgram(Handle); + } + + // The shader sources provided with this project use hardcoded layout(location)-s. If you want to do it dynamically, + // you can omit the layout(location=X) lines in the vertex shader, and use this in VertexAttribPointer instead of the hardcoded values. + public int GetAttribLocation(string attribName) + { + return GL.GetAttribLocation(Handle, attribName); + } + + // Uniform setters + // Uniforms are variables that can be set by user code, instead of reading them from the VBO. + // You use VBOs for vertex-related data, and uniforms for almost everything else. + + // Setting a uniform is almost always the exact same, so I'll explain it here once, instead of in every method: + // 1. Bind the program you want to set the uniform on + // 2. Get a handle to the location of the uniform with GL.GetUniformLocation. + // 3. Use the appropriate GL.Uniform* function to set the uniform. + + /// + /// Set a uniform int on this shader. + /// + /// The name of the uniform + /// The data to set + public void SetInt(string name, int data) + { + GL.UseProgram(Handle); + GL.Uniform1(_uniformLocations[name], data); + } + + /// + /// Set a uniform float on this shader. + /// + /// The name of the uniform + /// The data to set + public void SetFloat(string name, float data) + { + GL.UseProgram(Handle); + GL.Uniform1(_uniformLocations[name], data); + } + + /// + /// Set a uniform Matrix4 on this shader + /// + /// The name of the uniform + /// The data to set + /// + /// + /// The matrix is transposed before being sent to the shader. + /// + /// + public void SetMatrix4(string name, Matrix4 data) + { + GL.UseProgram(Handle); + GL.UniformMatrix4(_uniformLocations[name], true, ref data); + } + + /// + /// Set a uniform Vector3 on this shader. + /// + /// The name of the uniform + /// The data to set + public void SetVector3(string name, Vector3 data) + { + GL.UseProgram(Handle); + GL.Uniform3(_uniformLocations[name], data); + } +} + +/* +public class Shader : GLResource { - public class Shader : GLResource - { - public int id; + public int id; - /// - /// Generate an OpenGL shader - /// - /// The GLResourceManager - /// The shader code - /// The shader type - /// The shader object - public Shader(GLResourceManager manager, string source, ShaderType type) : base(manager) - { - id = GL.CreateShader((OpenTK.Graphics.OpenGL4.ShaderType)type); - GL.ShaderSource(id, source); - GL.CompileShader(id); - GL.GetShaderInfoLog(id, out string log); + /// + /// Generate an OpenGL shader + /// + /// The GLResourceManager + /// The shader code + /// The shader type + /// The shader object + public Shader(GLResourceManager manager, string source, ShaderType type) : base(manager) + { + id = GL.CreateShader((OpenTK.Graphics.OpenGL4.ShaderType)type); + GL.ShaderSource(id, source); + GL.CompileShader(id); + GL.GetShaderInfoLog(id, out string log); - if(!string.IsNullOrEmpty(log)){ - Logger.Get("ShaderCompiler", "Graphics").Log(LogMessageType.ERROR, type.ToString() + ": " + log); - } + if(!string.IsNullOrEmpty(log)){ + Logger.Get("ShaderCompiler", "Graphics").Log(LogMessageType.ERROR, type.ToString() + ": " + log); } + } - public override void Unload() - { - GL.DeleteShader(id); - } + public override void Unload() + { + GL.DeleteShader(id); } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/ShaderException.cs b/source/OrkEngine3D.Graphics/TK/Resources/ShaderException.cs index baf03e7..0715d09 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/ShaderException.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/ShaderException.cs @@ -1,18 +1,17 @@ -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +public class ShaderException : System.Exception { - public class ShaderException : System.Exception - { - public ShaderException() {} - public ShaderException(string message) : base(message) {} - public ShaderException(string message, System.Exception inner) : base(message, inner) {} - public ShaderException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) {} - } + public ShaderException() {} + public ShaderException(string message) : base(message) {} + public ShaderException(string message, System.Exception inner) : base(message, inner) {} + public ShaderException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) {} +} - public class ProgramException : System.Exception - { - public ProgramException() {} - public ProgramException(string message) : base(message) {} - public ProgramException(string message, System.Exception inner) : base(message, inner) {} - public ProgramException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) {} - } +public class ProgramException : System.Exception +{ + public ProgramException() {} + public ProgramException(string message) : base(message) {} + public ProgramException(string message, System.Exception inner) : base(message, inner) {} + public ProgramException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) {} } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/ShaderProgram.cs b/source/OrkEngine3D.Graphics/TK/Resources/ShaderProgram.cs index f5cb6f7..63a7513 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/ShaderProgram.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/ShaderProgram.cs @@ -1,226 +1,226 @@ -using System; using System.Collections.Generic; using OpenTK.Graphics.OpenGL4; using OrkEngine3D.Diagnostics.Logging; using OrkEngine3D.Mathematics; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +/* +public class ShaderProgram : GLResource { - public class ShaderProgram : GLResource + private static int lastBound = -1; + public int id; + + /// + /// The active uniforms in the shader + /// + /// Uniform name + /// Uniform ID + public Dictionary uniforms = new Dictionary(); + + /// + /// Create and compile the shader + /// + /// The GLResourceManager + /// The shader objects + /// The shader program + + public ShaderProgram(GLResourceManager manager, params Shader[] shaders) : base(manager) { - private static int lastBound = -1; - public int id; - - /// - /// The active uniforms in the shader - /// - /// Uniform name - /// Uniform ID - public Dictionary uniforms = new Dictionary(); - - /// - /// Create and compile the shader - /// - /// The GLResourceManager - /// The shader objects - /// The shader program - - public ShaderProgram(GLResourceManager manager, params Shader[] shaders) : base(manager) + id = GL.CreateProgram(); + for (var i = 0; i < shaders.Length; i++) { - id = GL.CreateProgram(); - for (var i = 0; i < shaders.Length; i++) - { - GL.AttachShader(id, shaders[i].id); - } - GL.LinkProgram(id); - GL.GetProgramInfoLog(id, out string log); - - if(!string.IsNullOrEmpty(log)){ - Logger.Get("ProgramLinker", "Graphics").Log(LogMessageType.ERROR, log); - } - - for (var i = 0; i < shaders.Length; i++) - { - GL.DetachShader(id, shaders[i].id); - } + GL.AttachShader(id, shaders[i].id); } + GL.LinkProgram(id); + GL.GetProgramInfoLog(id, out string log); - /// - /// Get the location of a vertex attribute - /// - /// The name of the attribute - /// The OpenGL location - public int GetAttribLocation(string name) + if(!string.IsNullOrEmpty(log)){ + Logger.Get("ProgramLinker", "Graphics").Log(LogMessageType.ERROR, log); + } + + for (var i = 0; i < shaders.Length; i++) { - return GL.GetAttribLocation(id, name); + GL.DetachShader(id, shaders[i].id); } + } - /// - /// Get the location of a uniform - /// - /// The name of the uniform - /// The OpenGL location + /// + /// Get the location of a vertex attribute + /// + /// The name of the attribute + /// The OpenGL location + public int GetAttribLocation(string name) + { + return GL.GetAttribLocation(id, name); + } - public int GetUniformLocation(string name) - { - if(uniforms.ContainsKey(name)) - return uniforms[name]; + /// + /// Get the location of a uniform + /// + /// The name of the uniform + /// The OpenGL location - int uniformID = GL.GetUniformLocation(id, name); + public int GetUniformLocation(string name) + { + if(uniforms.ContainsKey(name)) + return uniforms[name]; - uniforms.Add(name, uniformID); + int uniformID = GL.GetUniformLocation(id, name); - if(uniformID == -1){ - Logger.Get("ShaderProgram " + id, "Graphics").Log(LogMessageType.WARNING, "Invalid uniform " + name + ", returned ID -1"); - } + uniforms.Add(name, uniformID); - return GetUniformLocation(name); + if(uniformID == -1){ + Logger.Get("ShaderProgram " + id, "Graphics").Log(LogMessageType.WARNING, "Invalid uniform " + name + ", returned ID -1"); } - /// - /// Use the shader - /// - public void Use(){ - lastBound = id; - GL.UseProgram(id); - } + return GetUniformLocation(name); + } - /// - /// Dispatch compute shader if the ShaderProgram contains one - /// - public void DispatchCompute(int width, int height, int depth){ - Use(); - GL.DispatchCompute(width, height, depth); - GL.Finish(); - } + /// + /// Use the shader + /// + public void Use(){ + lastBound = id; + GL.UseProgram(id); + } - /// - /// Unload the ShaderProgram - /// - public override void Unload() - { - GL.DeleteProgram(id); - } + /// + /// Dispatch compute shader if the ShaderProgram contains one + /// + public void DispatchCompute(int width, int height, int depth){ + Use(); + GL.DispatchCompute(width, height, depth); + GL.Finish(); + } - #region Uniforms - // UNIFORM SETTING - public void Uniform1(string name, int value){ - if(lastBound != id) - Use(); - GL.Uniform1(GetUniformLocation(name), value); - } - public void Uniform1(string name, float value){ - if(lastBound != id) - Use(); - GL.Uniform1(GetUniformLocation(name), value); - } - public void Uniform1(string name, double value){ - if(lastBound != id) - Use(); - GL.Uniform1(GetUniformLocation(name), value); - } - public void Uniform1(string name, byte value){ - if(lastBound != id) - Use(); - GL.Uniform1(GetUniformLocation(name), value); - } + /// + /// Unload the ShaderProgram + /// + public override void Unload() + { + GL.DeleteProgram(id); + } + #region Uniforms + // UNIFORM SETTING + public void Uniform1(string name, int value){ + if(lastBound != id) + Use(); + GL.Uniform1(GetUniformLocation(name), value); + } + public void Uniform1(string name, float value){ + if(lastBound != id) + Use(); + GL.Uniform1(GetUniformLocation(name), value); + } + public void Uniform1(string name, double value){ + if(lastBound != id) + Use(); + GL.Uniform1(GetUniformLocation(name), value); + } + public void Uniform1(string name, byte value){ + if(lastBound != id) + Use(); + GL.Uniform1(GetUniformLocation(name), value); + } - public void Uniform2(string name, int x, int y){ - if(lastBound != id) - Use(); - GL.Uniform2(GetUniformLocation(name), x, y); - } - public void Uniform2(string name, float x, float y){ - if(lastBound != id) - Use(); - GL.Uniform2(GetUniformLocation(name), x, y); - } - public void Uniform2(string name, double x, double y){ - if(lastBound != id) - Use(); - GL.Uniform2(GetUniformLocation(name), x, y); - } - public void Uniform2(string name, byte x, byte y){ - if(lastBound != id) - Use(); - GL.Uniform2(GetUniformLocation(name), x, y); - } - public void Uniform2(string name, Vector2 value){ - if(lastBound != id) - Use(); - GL.Uniform2(GetUniformLocation(name), value.X, value.Y); - } - public void Uniform3(string name, int x, int y, int z){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), x, y, z); - } - public void Uniform3(string name, float x, float y, float z){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), x, y, z); - } - public void Uniform3(string name, double x, double y, double z){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), x, y, z); - } - public void Uniform3(string name, byte x, byte y, byte z){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), x, y, z); - } - public void Uniform3(string name, Vector3 value){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), value.X, value.Y, value.Z); - } - public void Uniform3(string name, Color3 value){ - if(lastBound != id) - Use(); - GL.Uniform3(GetUniformLocation(name), value.Red, value.Green, value.Blue); - } + public void Uniform2(string name, int x, int y){ + if(lastBound != id) + Use(); + GL.Uniform2(GetUniformLocation(name), x, y); + } + public void Uniform2(string name, float x, float y){ + if(lastBound != id) + Use(); + GL.Uniform2(GetUniformLocation(name), x, y); + } + public void Uniform2(string name, double x, double y){ + if(lastBound != id) + Use(); + GL.Uniform2(GetUniformLocation(name), x, y); + } + public void Uniform2(string name, byte x, byte y){ + if(lastBound != id) + Use(); + GL.Uniform2(GetUniformLocation(name), x, y); + } + public void Uniform2(string name, Vector2 value){ + if(lastBound != id) + Use(); + GL.Uniform2(GetUniformLocation(name), value.X, value.Y); + } - public void Uniform4(string name, int x, int y, int z, int w){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), x, y, z, w); - } - public void Uniform4(string name, float x, float y, float z, float w){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), x, y, z, w); - } - public void Uniform4(string name, double x, double y, double z, double w){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), x, y, z, w); - } - public void Uniform4(string name, byte x, byte y, byte z, byte w){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), x, y, z, w); - } - public void Uniform4(string name, Vector4 value){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), value.X, value.Y, value.Z, value.W); - } - public void Uniform4(string name, Color4 value){ - if(lastBound != id) - Use(); - GL.Uniform4(GetUniformLocation(name), value.Red, value.Green, value.Blue, value.Alpha); - } - public void UniformMatrix(string name, Matrix value){ - UniformMatrix(name, false, value); - } - public void UniformMatrix(string name, bool transpose, Matrix value){ - if(lastBound != id) - Use(); - GL.UniformMatrix4(GetUniformLocation(name), 1, transpose, value.ToArray()); - } - #endregion + public void Uniform3(string name, int x, int y, int z){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), x, y, z); + } + public void Uniform3(string name, float x, float y, float z){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), x, y, z); + } + public void Uniform3(string name, double x, double y, double z){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), x, y, z); + } + public void Uniform3(string name, byte x, byte y, byte z){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), x, y, z); + } + public void Uniform3(string name, Vector3 value){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), value.X, value.Y, value.Z); + } + public void Uniform3(string name, Color3 value){ + if(lastBound != id) + Use(); + GL.Uniform3(GetUniformLocation(name), value.Red, value.Green, value.Blue); + } + + public void Uniform4(string name, int x, int y, int z, int w){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), x, y, z, w); + } + public void Uniform4(string name, float x, float y, float z, float w){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), x, y, z, w); + } + public void Uniform4(string name, double x, double y, double z, double w){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), x, y, z, w); + } + public void Uniform4(string name, byte x, byte y, byte z, byte w){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), x, y, z, w); + } + public void Uniform4(string name, Vector4 value){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), value.X, value.Y, value.Z, value.W); + } + public void Uniform4(string name, Color4 value){ + if(lastBound != id) + Use(); + GL.Uniform4(GetUniformLocation(name), value.Red, value.Green, value.Blue, value.Alpha); + } + public void UniformMatrix(string name, Matrix value){ + UniformMatrix(name, false, value); + } + public void UniformMatrix(string name, bool transpose, Matrix value){ + if(lastBound != id) + Use(); + GL.UniformMatrix4(GetUniformLocation(name), 1, transpose, value.ToArray()); } -} \ No newline at end of file + #endregion +} +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/ShaderType.cs b/source/OrkEngine3D.Graphics/TK/Resources/ShaderType.cs index ed4d76e..7308741 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/ShaderType.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/ShaderType.cs @@ -1,18 +1,17 @@ -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +// Lets not show ANY OpenTK here shall we? +/// +/// Shader types +/// +public enum ShaderType { - // Lets not show ANY OpenTK here shall we? - /// - /// Shader types - /// - public enum ShaderType - { - ComputeShader = OpenTK.Graphics.OpenGL4.ShaderType.ComputeShader, - FragmentShader = OpenTK.Graphics.OpenGL4.ShaderType.FragmentShader, - VertexShader = OpenTK.Graphics.OpenGL4.ShaderType.VertexShader, - FragmentShaderArb = OpenTK.Graphics.OpenGL4.ShaderType.FragmentShaderArb, - VertexShaderArb = OpenTK.Graphics.OpenGL4.ShaderType.VertexShaderArb, - GeometryShader = OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader, - TessControlShader = OpenTK.Graphics.OpenGL4.ShaderType.TessControlShader, - TessEvaluationShader = OpenTK.Graphics.OpenGL4.ShaderType.TessEvaluationShader - } + ComputeShader = OpenTK.Graphics.OpenGL4.ShaderType.ComputeShader, + FragmentShader = OpenTK.Graphics.OpenGL4.ShaderType.FragmentShader, + VertexShader = OpenTK.Graphics.OpenGL4.ShaderType.VertexShader, + FragmentShaderArb = OpenTK.Graphics.OpenGL4.ShaderType.FragmentShaderArb, + VertexShaderArb = OpenTK.Graphics.OpenGL4.ShaderType.VertexShaderArb, + GeometryShader = OpenTK.Graphics.OpenGL4.ShaderType.GeometryShader, + TessControlShader = OpenTK.Graphics.OpenGL4.ShaderType.TessControlShader, + TessEvaluationShader = OpenTK.Graphics.OpenGL4.ShaderType.TessEvaluationShader } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/ShadowHandler.cs b/source/OrkEngine3D.Graphics/TK/Resources/ShadowHandler.cs index 4eddf1a..511f2b3 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/ShadowHandler.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/ShadowHandler.cs @@ -1,12 +1,12 @@ using System; using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; using OrkEngine3D.Diagnostics.Logging; using OrkEngine3D.Mathematics; -using Vector3 = OpenTK.Mathematics.Vector3; +//using Vector3 = OpenTK.Mathematics.Vector3; namespace OrkEngine3D.Graphics.TK.Resources; +/* public class ShadowHandler : GLResource { public int depthMapFBO; @@ -87,4 +87,6 @@ public void PreRender() shaderProgram.Use(); shaderProgram.UniformMatrix("lightSpaceMatrix", lightSpaceMatrix); } -} \ No newline at end of file +} + +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/Texture.cs b/source/OrkEngine3D.Graphics/TK/Resources/Texture.cs index a16580d..7ef7706 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/Texture.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/Texture.cs @@ -1,148 +1,230 @@ using System.Collections.Generic; using System.IO; using System; -using System.Collections; using OpenTK.Graphics.OpenGL4; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using OrkEngine3D.Diagnostics.Logging; +using StbImageSharp; -namespace OrkEngine3D.Graphics.TK.Resources +namespace OrkEngine3D.Graphics.TK.Resources; + +// A helper class, much like Shader, meant to simplify loading textures. +public class Texture { - public class Texture : GLResource + public readonly int Handle; + + public static Texture LoadFromFile(string path) { - public int id; - public readonly int width; - public readonly int height; - - /// - /// Generate a texture from data - /// - /// he OpenGL manager - /// The texture data - /// The texture object - public Texture(GLResourceManager manager, TextureData data) : base(manager) - { - this.width = data.width; - this.height = data.height; + // Generate handle + int handle = GL.GenTexture(); - id = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, id); + // Bind the handle + GL.ActiveTexture(TextureUnit.Texture0); + GL.BindTexture(TextureTarget.Texture2D, handle); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + // For this example, we're going to use .NET's built-in System.Drawing library to load textures. - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.width, data.height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data.pixels); - } + // OpenGL has it's texture origin in the lower left corner instead of the top left corner, + // so we tell StbImageSharp to flip the image when loading. + StbImage.stbi_set_flip_vertically_on_load(1); - /// - /// Generate a texture object from id - /// WARNING: UNSAFE! - /// - /// The OpenGL texture ID - /// Width of the texture - /// Height of the texture - public Texture(GLResourceManager manager, int id, int width, int height) : base(manager) + // Here we open a stream to the file and pass it to StbImageSharp to load. + using (Stream stream = File.OpenRead(path)) { - this.id = id; - this.width = width; - this.height = height; + ImageResult image = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); + + // Now that our pixels are prepared, it's time to generate a texture. We do this with GL.TexImage2D. + // Arguments: + // The type of texture we're generating. There are various different types of textures, but the only one we need right now is Texture2D. + // Level of detail. We can use this to start from a smaller mipmap (if we want), but we don't need to do that, so leave it at 0. + // Target format of the pixels. This is the format OpenGL will store our image with. + // Width of the image + // Height of the image. + // Border of the image. This must always be 0; it's a legacy parameter that Khronos never got rid of. + // The format of the pixels, explained above. Since we loaded the pixels as RGBA earlier, we need to use PixelFormat.Rgba. + // Data type of the pixels. + // And finally, the actual pixels. + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, image.Data); } - /// - /// Use a texture for rendering - /// - /// The texure ID(in shader) - public void Use(byte id){ - if(id > 31 && id < 0) - Logger.Get("TextureBinder", "Graphics").Log(LogMessageType.FATAL, "Texture index may only be 0-31"); - GL.ActiveTexture((TextureUnit)Enum.Parse(typeof(TextureUnit), "Texture"+id.ToString())); - GL.BindTexture(TextureTarget.Texture2D, this.id); - } + // Now that our texture is loaded, we can set a few settings to affect how the image appears on rendering. + + // First, we set the min and mag filter. These are used for when the texture is scaled down and up, respectively. + // Here, we use Linear for both. This means that OpenGL will try to blend pixels, meaning that textures scaled too far will look blurred. + // You could also use (amongst other options) Nearest, which just grabs the nearest pixel, which makes the texture look pixelated if scaled too far. + // NOTE: The default settings for both of these are LinearMipmap. If you leave these as default but don't generate mipmaps, + // your image will fail to render at all (usually resulting in pure black instead). + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + + // Now, set the wrapping mode. S is for the X axis, and T is for the Y axis. + // We set this to Repeat so that textures will repeat when wrapped. Not demonstrated here since the texture coordinates exactly match + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + + // Next, generate mipmaps. + // Mipmaps are smaller copies of the texture, scaled down. Each mipmap level is half the size of the previous one + // Generated mipmaps go all the way down to just one pixel. + // OpenGL will automatically switch between mipmaps when an object gets sufficiently far away. + // This prevents moir effects, as well as saving on texture bandwidth. + // Here you can see and read about the mori effect https://en.wikipedia.org/wiki/Moir%C3%A9_pattern + // Here is an example of mips in action https://en.wikipedia.org/wiki/File:Mipmap_Aliasing_Comparison.png + GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + + return new Texture(handle); + } - /// - /// Unload the texture - /// + public Texture(int glHandle) + { + Handle = glHandle; + } - public override void Unload() - { - GL.DeleteTexture(id); - } + // Activate texture + // Multiple textures can be bound, if your shader needs more than just one. + // If you want to do that, use GL.ActiveTexture to set which slot GL.BindTexture binds to. + // The OpenGL standard requires that there be at least 16, but there can be more depending on your graphics card. + public void Use(TextureUnit unit) + { + GL.ActiveTexture(unit); + GL.BindTexture(TextureTarget.Texture2D, Handle); + } +} +/* +public class Texture : GLResource +{ + public int id; + public readonly int width; + public readonly int height; - /// - /// Get the texture data from a file - /// - /// The path to the file - /// The files texturedata - public static TextureData GetTextureDataFromFile(string path){ - return GetTextureDataFromFileData(File.ReadAllBytes(path)); - } + /// + /// Generate a texture from data + /// + /// he OpenGL manager + /// The texture data + /// The texture object + public Texture(GLResourceManager manager, TextureData data) : base(manager) + { + this.width = data.width; + this.height = data.height; + id = GL.GenTexture(); + GL.BindTexture(TextureTarget.Texture2D, id); - /// - /// Get the texture data from the contents of a .png etc. The raw file data. - /// - /// The raw file data - /// The texture data - public static TextureData GetTextureDataFromFileData(byte[] data) - { - //Load the image - Image image = Image.Load(data); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - //ImageSharp loads from the top-left pixel, whereas OpenGL loads from the bottom-left, causing the texture to be flipped vertically. - //This will correct that, making the texture display properly. - image.Mutate(x => x.Flip(FlipMode.Horizontal).Flip(FlipMode.Vertical)); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.width, data.height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data.pixels); + } - //Convert ImageSharp's format into a byte array, so we can use it with OpenGL. - var pixels = new List(4 * image.Width * image.Height); + /// + /// Generate a texture object from id + /// WARNING: UNSAFE! + /// + /// The OpenGL texture ID + /// Width of the texture + /// Height of the texture + public Texture(GLResourceManager manager, int id, int width, int height) : base(manager) + { + this.id = id; + this.width = width; + this.height = height; + } - for (int y = 0; y < image.Height; y++) { - var row = image.GetPixelRowSpan(y); + /// + /// Use a texture for rendering + /// + /// The texure ID(in shader) + public void Use(byte id){ + if(id > 31 && id < 0) + Logger.Get("TextureBinder", "Graphics").Log(LogMessageType.FATAL, "Texture index may only be 0-31"); + GL.ActiveTexture((TextureUnit)Enum.Parse(typeof(TextureUnit), "Texture"+id.ToString())); + GL.BindTexture(TextureTarget.Texture2D, this.id); + } - for (int x = 0; x < image.Width; x++) { - pixels.Add(row[x].R); - pixels.Add(row[x].G); - pixels.Add(row[x].B); - pixels.Add(row[x].A); - } - } + /// + /// Unload the texture + /// - return new TextureData(image.Width, image.Height, pixels.ToArray()); - } + public override void Unload() + { + GL.DeleteTexture(id); + } + + /// + /// Get the texture data from a file + /// + /// The path to the file + /// The files texturedata + public static TextureData GetTextureDataFromFile(string path){ + return GetTextureDataFromFileData(File.ReadAllBytes(path)); } + /// - /// The data of a texture, contains width, height and pixels + /// Get the texture data from the contents of a .png etc. The raw file data. /// - public struct TextureData{ - /// - /// Width of the texture - /// - public int width; - - /// - /// Height of the texture - /// - public int height; - - /// - /// Pixels in bytes, RGBA format - /// - public byte[] pixels; - - /// - /// Generate a texture data struct - /// - /// The texture height - /// The tetxure width - /// The pixels in bytes, RGBA format - public TextureData(int width, int height, byte[] pixels){ - this.width = width; - this.height = height; - this.pixels = pixels; + /// The raw file data + /// The texture data + public static TextureData GetTextureDataFromFileData(byte[] data) + { + //Load the image + Image image = Image.Load(data); + + //ImageSharp loads from the top-left pixel, whereas OpenGL loads from the bottom-left, causing the texture to be flipped vertically. + //This will correct that, making the texture display properly. + image.Mutate(x => x.Flip(FlipMode.Horizontal).Flip(FlipMode.Vertical)); + + //Convert ImageSharp's format into a byte array, so we can use it with OpenGL. + var pixels = new List(4 * image.Width * image.Height); + + for (int y = 0; y < image.Height; y++) { + var row = image.GetPixelRowSpan(y); + + for (int x = 0; x < image.Width; x++) { + pixels.Add(row[x].R); + pixels.Add(row[x].G); + pixels.Add(row[x].B); + pixels.Add(row[x].A); + } } + + return new TextureData(image.Width, image.Height, pixels.ToArray()); + } +} + +/// +/// The data of a texture, contains width, height and pixels +/// +public struct TextureData{ + /// + /// Width of the texture + /// + public int width; + + /// + /// Height of the texture + /// + public int height; + + /// + /// Pixels in bytes, RGBA format + /// + public byte[] pixels; + + /// + /// Generate a texture data struct + /// + /// The texture height + /// The tetxure width + /// The pixels in bytes, RGBA format + public TextureData(int width, int height, byte[] pixels){ + this.width = width; + this.height = height; + this.pixels = pixels; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Resources/VertexData.cs b/source/OrkEngine3D.Graphics/TK/Resources/VertexData.cs index 88bdfbe..39394de 100644 --- a/source/OrkEngine3D.Graphics/TK/Resources/VertexData.cs +++ b/source/OrkEngine3D.Graphics/TK/Resources/VertexData.cs @@ -5,40 +5,40 @@ using System.Runtime.InteropServices; -namespace OrkEngine3D.Graphics.TK.Resources{ - - [Obsolete("Why is this still here? Just to suffer?", true)] - public class VertexData : IEnumerable where T : struct{ - List data = new List(); - public int Length => data.Count; - - public int GetSize(){ - return Marshal.SizeOf(typeof(T)); - } - - public void SetData(IEnumerable data){ - this.data.Clear(); - this.data.AddRange(data); - } - - public IEnumerator GetEnumerator() - { - return data.GetEnumerator(); - } - - public VertexData Add(T value){ - data.Add(value); - return this; - } - - public VertexData AddRange(IEnumerable values){ - data.AddRange(values); - return this; - } - - internal T[] ToArray() - { - return data.ToArray(); - } +namespace OrkEngine3D.Graphics.TK.Resources; + + +[Obsolete("Why is this still here? Just to suffer?", true)] +public class VertexData : IEnumerable where T : struct{ + List data = new List(); + public int Length => data.Count; + + public int GetSize(){ + return Marshal.SizeOf(typeof(T)); + } + + public void SetData(IEnumerable data){ + this.data.Clear(); + this.data.AddRange(data); + } + + public IEnumerator GetEnumerator() + { + return data.GetEnumerator(); + } + + public VertexData Add(T value){ + data.Add(value); + return this; + } + + public VertexData AddRange(IEnumerable values){ + data.AddRange(values); + return this; + } + + internal T[] ToArray() + { + return data.ToArray(); } } \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/Skybox.cs b/source/OrkEngine3D.Graphics/TK/Skybox.cs new file mode 100644 index 0000000..aba6c2b --- /dev/null +++ b/source/OrkEngine3D.Graphics/TK/Skybox.cs @@ -0,0 +1,36 @@ +using OpenTK.Graphics.OpenGL; +using OrkEngine3D.Graphics.TK.Resources; + +namespace OrkEngine3D.Graphics.TK; + +/* TODO: Needs to be tested */ +/* +internal class Skybox +{ + private ShaderProgram skyboxShader; + private Texture skyboxTexture; + private int skyboxVAO; + + public Skybox(GLResourceManager manager, string skyboxImagePath) + { + skyboxShader = new ShaderProgram(manager, new Shader(manager, vertexShaderSource, Resources.ShaderType.VertexShader), new Shader(manager, fragmentShaderSource, Resources.ShaderType.FragmentShader)); + skyboxTexture = new Texture(manager, Texture.GetTextureDataFromFile(skyboxImagePath)); + skyboxVAO = GL.GenVertexArray(); + GL.BindVertexArray(skyboxVAO); + } + + public void Render() + { + GL.DepthMask(false); + skyboxShader.Use(); + GL.BindVertexArray(skyboxVAO); + skyboxTexture.Use(0); + GL.DrawArrays(PrimitiveType.Triangles, 0, 36); + GL.DepthMask(true); + } + + private const string vertexShaderSource = "#version 330 core\nlayout (location = 0) in vec3 aPos;\nout vec3 TexCoords;\nuniform mat4 projection;\nuniform mat4 view;\nvoid main()\n{\n TexCoords = aPos;\n vec4 pos = projection * view * vec4(aPos, 1.0);\n gl_Position = pos.xyww;\n}\n"; + + private const string fragmentShaderSource = "#version 330 core\nout vec4 FragColor;\nin vec3 TexCoords;\nuniform sampler2D skybox;\nvoid main()\n{\n FragColor = texture(skybox, TexCoords);\n}\n"; +} +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Graphics/TK/WindowTarget.cs b/source/OrkEngine3D.Graphics/TK/WindowTarget.cs index ce47a18..24c0a0c 100644 --- a/source/OrkEngine3D.Graphics/TK/WindowTarget.cs +++ b/source/OrkEngine3D.Graphics/TK/WindowTarget.cs @@ -1,30 +1,26 @@ using OpenTK.Graphics.OpenGL4; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace OrkEngine3D.Graphics.TK +namespace OrkEngine3D.Graphics.TK; + +/* +public class WindowTarget : IRenderTarget { - public class WindowTarget : IRenderTarget + public static readonly WindowTarget Global = new WindowTarget(); + private WindowTarget() { } + public void BindTarget() { - public static readonly WindowTarget Global = new WindowTarget(); - private WindowTarget() { } - public void BindTarget() - { - GL.Viewport(0, 0, Rendering.currentContext.window.Size.X, Rendering.currentContext.window.Size.Y); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); - } + GL.Viewport(0, 0, Rendering.currentContext.window.Size.X, Rendering.currentContext.window.Size.Y); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + } - public void Clear() - { - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - } + public void Clear() + { + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + } - public void PreRender() - { - - } + public void PreRender() + { + } } +*/ \ No newline at end of file diff --git a/source/OrkEngine3D.Mathematics/.editorconfig b/source/OrkEngine3D.Mathematics/.editorconfig deleted file mode 100644 index dc93c10..0000000 --- a/source/OrkEngine3D.Mathematics/.editorconfig +++ /dev/null @@ -1,133 +0,0 @@ -# To learn more about .editorconfig see https://aka.ms/editorconfigdocs -############################### -# Core EditorConfig Options # -############################### -root = true -# All files -[*] -indent_style = space - -# XML project files -[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] -indent_size = 2 - -# XML config files -[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] -indent_size = 2 - -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -insert_final_newline = true -charset = utf-8-bom -############################### -# .NET Coding Conventions # -############################### -[*.{cs,vb}] -# Organize usings -dotnet_sort_system_directives_first = true -# this. preferences -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent -dotnet_style_readonly_field = true:suggestion -# Expression-level preferences -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -############################### -# Naming Conventions # -############################### -# Style Definitions -dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# Use PascalCase for constant fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const -############################### -# C# Coding Conventions # -############################### -[*.cs] -# var preferences -csharp_style_var_for_built_in_types = true:silent -csharp_style_var_when_type_is_apparent = true:silent -csharp_style_var_elsewhere = true:silent -# Expression-bodied members -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent -# Pattern matching preferences -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -# Null-checking preferences -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion -# Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion -# Expression-level preferences -csharp_prefer_braces = true:silent -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_pattern_local_over_anonymous_function = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -############################### -# C# Formatting Rules # -############################### -# New line preferences -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_between_query_expression_clauses = true -# Indentation preferences -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left -# Space preferences -csharp_space_after_cast = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_around_binary_operators = before_and_after -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -# Wrapping preferences -csharp_preserve_single_line_statements = true -csharp_preserve_single_line_blocks = true -############################### -# VB Coding Conventions # -############################### -[*.vb] -# Modifier preferences -visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion diff --git a/source/OrkEngine3D.Mathematics/BoundingBox.cs b/source/OrkEngine3D.Mathematics/BoundingBox.cs deleted file mode 100644 index 7101b52..0000000 --- a/source/OrkEngine3D.Mathematics/BoundingBox.cs +++ /dev/null @@ -1,490 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents an axis-aligned bounding box in three dimensional space. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct BoundingBox : IEquatable, IFormattable -{ - /// - /// The minimum point of the box. - /// - public Vector3 Minimum; - - /// - /// The maximum point of the box. - /// - public Vector3 Maximum; - - /// - /// Initializes a new instance of the struct. - /// - /// The minimum vertex of the bounding box. - /// The maximum vertex of the bounding box. - public BoundingBox(Vector3 minimum, Vector3 maximum) - { - this.Minimum = minimum; - this.Maximum = maximum; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The minimum x-coordinate of the bounding box. - /// The minimum y-coordinate of the bounding box. - /// The minimum z-coordinate of the bounding box. - /// The maximum x-coordinate of the bounding box. - /// The maximum y-coordinate of the bounding box. - /// The maximum z-coordinate of the bounding box. - public BoundingBox(float minimumX, float minimumY, float minimumZ, float maximumX, float maximumY, float maximumZ) - { - this.Minimum = new Vector3(minimumX, minimumY, minimumZ); - this.Maximum = new Vector3(maximumX, maximumY, maximumZ); - } - - /// - /// Retrieves the eight corners of the bounding box. - /// - /// An array of points representing the eight corners of the bounding box. - public Vector3[] GetCorners() - { - Vector3[] results = new Vector3[8]; - results[0] = new Vector3(Minimum.X, Maximum.Y, Maximum.Z); - results[1] = new Vector3(Maximum.X, Maximum.Y, Maximum.Z); - results[2] = new Vector3(Maximum.X, Minimum.Y, Maximum.Z); - results[3] = new Vector3(Minimum.X, Minimum.Y, Maximum.Z); - results[4] = new Vector3(Minimum.X, Maximum.Y, Minimum.Z); - results[5] = new Vector3(Maximum.X, Maximum.Y, Minimum.Z); - results[6] = new Vector3(Maximum.X, Minimum.Y, Minimum.Z); - results[7] = new Vector3(Minimum.X, Minimum.Y, Minimum.Z); - return results; - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray) - { - float distance; - return Collision.RayIntersectsBox(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out float distance) - { - return Collision.RayIntersectsBox(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out Vector3 point) - { - return Collision.RayIntersectsBox(ref ray, ref this, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref Plane plane) - { - return Collision.PlaneIntersectsBox(ref plane, ref this); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - return Collision.BoxIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingBox box) - { - return Collision.BoxIntersectsBox(ref this, ref box); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingSphere sphere) - { - return Collision.BoxIntersectsSphere(ref this, ref sphere); - } - - /// - /// Determines whether the current objects contains a point. - /// - /// The point to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref Vector3 point) - { - return Collision.BoxContainsPoint(ref this, ref point); - } - - /// - /// Determines whether the current objects contains a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - return Collision.BoxContainsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3); - } - - /// - /// Determines whether the current objects contains a . - /// - /// The box to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref BoundingBox box) - { - return Collision.BoxContainsBox(ref this, ref box); - } - - /// - /// Determines whether the current objects contains a . - /// - /// The sphere to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref BoundingSphere sphere) - { - return Collision.BoxContainsSphere(ref this, ref sphere); - } - - /// - /// Generates a supporting point for this instance. - /// - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public void SupportMapping(ref Vector3 direction, out Vector3 result) - { - Collision.SupportPoint(ref this, ref direction, out result); - } - - /// - /// Generates a support mapping for this instance. - /// - /// The direction for which to build the support mapping. - /// The resulting support mapping. - public Vector3 SupportMapping(Vector3 direction) - { - Vector3 result; - SupportMapping(ref direction, out result); - return result; - } - - /// - /// Constructs a that fully contains the given points. - /// - /// The points that will be contained by the box. - /// When the method completes, contains the newly constructed bounding box. - /// Thrown when is null. - public static void FromPoints(Vector3[] points, out BoundingBox result) - { - if (points == null) - throw new ArgumentNullException("points"); - - Vector3 min = new Vector3(float.MaxValue); - Vector3 max = new Vector3(float.MinValue); - - for (int i = 0; i < points.Length; ++i) - { - Vector3.Min(ref min, ref points[i], out min); - Vector3.Max(ref max, ref points[i], out max); - } - - result = new BoundingBox(min, max); - } - - /// - /// Constructs a that fully contains the given points. - /// - /// The points that will be contained by the box. - /// The newly constructed bounding box. - /// Thrown when is null. - public static BoundingBox FromPoints(Vector3[] points) - { - if (points == null) - throw new ArgumentNullException("points"); - - Vector3 min = new Vector3(float.MaxValue); - Vector3 max = new Vector3(float.MinValue); - - for (int i = 0; i < points.Length; ++i) - { - Vector3.Min(ref min, ref points[i], out min); - Vector3.Max(ref max, ref points[i], out max); - } - - return new BoundingBox(min, max); - } - - /// - /// Constructs a from a given sphere. - /// - /// The sphere that will designate the extents of the box. - /// When the method completes, contains the newly constructed bounding box. - public static void FromSphere(ref BoundingSphere sphere, out BoundingBox result) - { - result.Minimum = new Vector3(sphere.Center.X - sphere.Radius, sphere.Center.Y - sphere.Radius, sphere.Center.Z - sphere.Radius); - result.Maximum = new Vector3(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + sphere.Radius); - } - - /// - /// Constructs a from a given sphere. - /// - /// The sphere that will designate the extents of the box. - /// The newly constructed bounding box. - public static BoundingBox FromSphere(BoundingSphere sphere) - { - BoundingBox box; - box.Minimum = new Vector3(sphere.Center.X - sphere.Radius, sphere.Center.Y - sphere.Radius, sphere.Center.Z - sphere.Radius); - box.Maximum = new Vector3(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + sphere.Radius); - return box; - } - - /// - /// Constructs a that is as large as the total combined area of the two specified boxes. - /// - /// The first box to merge. - /// The second box to merge. - /// When the method completes, contains the newly constructed bounding box. - public static void Merge(ref BoundingBox value1, ref BoundingBox value2, out BoundingBox result) - { - Vector3.Min(ref value1.Minimum, ref value2.Minimum, out result.Minimum); - Vector3.Max(ref value1.Maximum, ref value2.Maximum, out result.Maximum); - } - - /// - /// Constructs a that is as large as the total combined area of the two specified boxes. - /// - /// The first box to merge. - /// The second box to merge. - /// The newly constructed bounding box. - public static BoundingBox Merge(BoundingBox value1, BoundingBox value2) - { - BoundingBox box; - Vector3.Min(ref value1.Minimum, ref value2.Minimum, out box.Minimum); - Vector3.Max(ref value1.Maximum, ref value2.Maximum, out box.Maximum); - return box; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(BoundingBox left, BoundingBox right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(BoundingBox left, BoundingBox right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(format, CultureInfo.CurrentCulture), - Maximum.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "Minimum:{0} Maximum:{1}", Minimum.ToString(format, formatProvider), - Maximum.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Minimum.GetHashCode() + Maximum.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(BoundingBox value) - { - return Minimum == value.Minimum && Maximum == value.Maximum; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((BoundingBox)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.BoundingBox(BoundingBox value) - { - return new SlimDX.BoundingBox(value.Minimum, value.Maximum); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator BoundingBox(SlimDX.BoundingBox value) - { - return new BoundingBox(value.Minimum, value.Maximum); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.BoundingBox(BoundingBox value) - { - return new Microsoft.Xna.Framework.BoundingBox(value.Minimum, value.Maximum); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator BoundingBox(Microsoft.Xna.Framework.BoundingBox value) - { - return new BoundingBox(value.Min, value.Max); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/BoundingFrustum.cs b/source/OrkEngine3D.Mathematics/BoundingFrustum.cs deleted file mode 100644 index 6249c45..0000000 --- a/source/OrkEngine3D.Mathematics/BoundingFrustum.cs +++ /dev/null @@ -1,99 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a bounding frustum in three dimensional space. -/// -[Serializable] -public class BoundingFrustum -{ - Plane near; - Plane far; - Plane top; - Plane bottom; - Plane left; - Plane right; - - Matrix matrix; - Gjk gjk = new Gjk(); - - /// - /// Initializes a new instance of the class. - /// - /// The to extract the planes from. - public BoundingFrustum(Matrix value) - { - SetMatrix(ref value); - } - - /// - /// Sets the matrix that represents this instance of . - /// - /// The to extract the planes from. - public void SetMatrix(ref Matrix value) - { - this.matrix = value; - - //Near - near.Normal.X = value.M13; - near.Normal.Y = value.M23; - near.Normal.Z = value.M33; - near.D = value.M43; - - //Far - far.Normal.X = value.M14 - value.M13; - far.Normal.Y = value.M24 - value.M23; - far.Normal.Z = value.M34 - value.M33; - far.D = value.M44 - value.M43; - - //Top - top.Normal.X = value.M14 - value.M12; - top.Normal.Y = value.M24 - value.M22; - top.Normal.Z = value.M34 - value.M32; - top.D = value.M44 - value.M42; - - //Bottom - bottom.Normal.X = value.M14 + value.M12; - bottom.Normal.Y = value.M24 + value.M22; - bottom.Normal.Z = value.M34 + value.M32; - bottom.D = value.M44 + value.M42; - - //Left - left.Normal.X = value.M14 + value.M11; - left.Normal.Y = value.M24 + value.M21; - left.Normal.Z = value.M34 + value.M31; - left.D = value.M44 + value.M41; - - //Right - right.Normal.X = value.M14 - value.M11; - right.Normal.Y = value.M24 - value.M21; - right.Normal.Z = value.M34 - value.M31; - right.D = value.M44 - value.M41; - } -} diff --git a/source/OrkEngine3D.Mathematics/BoundingSphere.cs b/source/OrkEngine3D.Mathematics/BoundingSphere.cs deleted file mode 100644 index 161fd66..0000000 --- a/source/OrkEngine3D.Mathematics/BoundingSphere.cs +++ /dev/null @@ -1,541 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a bounding sphere in three dimensional space. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct BoundingSphere : IEquatable, IFormattable -{ - /// - /// The center of the sphere in three dimensional space. - /// - public Vector3 Center; - - /// - /// The radious of the sphere. - /// - public float Radius; - - /// - /// Initializes a new instance of the struct. - /// - /// The center of the sphere. - /// The radius of the sphere. - public BoundingSphere(Vector3 center, float radius) - { - this.Center = center; - this.Radius = radius; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The x-coordinate for the center of the sphere. - /// The y-coordinate for the center of the sphere. - /// The z-coordinate for the center of the sphere. - /// The radius of the sphere. - public BoundingSphere(float centerX, float centerY, float centerZ, float radius) - { - this.Center = new Vector3(centerX, centerY, centerZ); - this.Radius = radius; - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray) - { - float distance; - return Collision.RayIntersectsSphere(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out float distance) - { - return Collision.RayIntersectsSphere(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out Vector3 point) - { - return Collision.RayIntersectsSphere(ref ray, ref this, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref Plane plane) - { - return Collision.PlaneIntersectsSphere(ref plane, ref this); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - return Collision.SphereIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingBox box) - { - return Collision.BoxIntersectsSphere(ref box, ref this); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingSphere sphere) - { - return Collision.SphereIntersectsSphere(ref this, ref sphere); - } - - /// - /// Determines whether the current objects contains a point. - /// - /// The point to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref Vector3 point) - { - return Collision.SphereContainsPoint(ref this, ref point); - } - - /// - /// Determines whether the current objects contains a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - return Collision.SphereContainsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3); - } - - /// - /// Determines whether the current objects contains a . - /// - /// The box to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref BoundingBox box) - { - return Collision.SphereContainsBox(ref this, ref box); - } - - /// - /// Determines whether the current objects contains a . - /// - /// The sphere to test. - /// The type of containment the two objects have. - public ContainmentType Contains(ref BoundingSphere sphere) - { - return Collision.SphereContainsSphere(ref this, ref sphere); - } - - /// - /// Translates and scales this instance by a . - /// - /// The to transform this instance by. - /// When the method completes, contains the transformed . - /// - /// The result of this operation is undefined if the matrix contains any transformations other than - /// translation, rotation, and uniform scaling. - /// - public void Transform(ref Matrix matrix, out BoundingSphere result) - { - Vector3.TransformCoordinate(ref Center, ref matrix, out result.Center); - - float row1 = (matrix.M11 * matrix.M11) + (matrix.M12 * matrix.M12) + (matrix.M13 * matrix.M13); - float row2 = (matrix.M21 * matrix.M21) + (matrix.M22 * matrix.M22) + (matrix.M23 * matrix.M23); - float row3 = (matrix.M31 * matrix.M31) + (matrix.M32 * matrix.M32) + (matrix.M33 * matrix.M33); - float num = Math.Max(row1, Math.Max(row2, row3)); - - result.Radius = Radius * (float)Math.Sqrt(num); - - } - - /// - /// Translates and scales this instance by a . - /// - /// The to transform this instance by. - /// The transformed . - /// - /// The result of this operation is undefined if the matrix contains any transformations other than - /// translation, rotation, and uniform scaling. - /// - public BoundingSphere Transform(Matrix matrix) - { - BoundingSphere result; - Transform(ref matrix, out result); - return result; - } - - /// - /// Generates a supporting point for this instance. - /// - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public void SupportMapping(ref Vector3 direction, out Vector3 result) - { - Collision.SupportPoint(ref this, ref direction, out result); - } - - /// - /// Generates a support mapping for this instance. - /// - /// The direction for which to build the support mapping. - /// The resulting support mapping. - public Vector3 SupportMapping(Vector3 direction) - { - Vector3 result; - SupportMapping(ref direction, out result); - return result; - } - - /// - /// Constructs a that fully contains the given points. - /// - /// The points that will be contained by the sphere. - /// When the method completes, contains the newly constructed bounding sphere. - public static void FromPoints(Vector3[] points, out BoundingSphere result) - { - //Find the center of all points. - Vector3 center = Vector3.Zero; - for (int i = 0; i < points.Length; ++i) - { - Vector3.Add(ref points[i], ref center, out center); - } - - //This is the center of our sphere. - center /= (float)points.Length; - - //Find the radius of the sphere - float radius = 0f; - for (int i = 0; i < points.Length; ++i) - { - //We are doing a relative distance comparison to find the maximum distance - //from the center of our sphere. - float distance; - Vector3.DistanceSquared(ref center, ref points[i], out distance); - - if (distance > radius) - radius = distance; - } - - //Find the real distance from the DistanceSquared. - radius = (float)Math.Sqrt(radius); - - //Construct the sphere. - result.Center = center; - result.Radius = radius; - } - - /// - /// Constructs a that fully contains the given points. - /// - /// The points that will be contained by the sphere. - /// The newly constructed bounding sphere. - public static BoundingSphere FromPoints(Vector3[] points) - { - BoundingSphere result; - FromPoints(points, out result); - return result; - } - - /// - /// Constructs a from a given box. - /// - /// The box that will designate the extents of the sphere. - /// When the method completes, the newly constructed bounding sphere. - public static void FromBox(ref BoundingBox box, out BoundingSphere result) - { - Vector3.Lerp(ref box.Minimum, ref box.Maximum, 0.5f, out result.Center); - - float x = box.Minimum.X - box.Maximum.X; - float y = box.Minimum.Y - box.Maximum.Y; - float z = box.Minimum.Z - box.Maximum.Z; - - float distance = (float)(Math.Sqrt((x * x) + (y * y) + (z * z))); - result.Radius = distance * 0.5f; - } - - /// - /// Constructs a from a given box. - /// - /// The box that will designate the extents of the sphere. - /// The newly constructed bounding sphere. - public static BoundingSphere FromBox(BoundingBox box) - { - BoundingSphere result; - FromBox(ref box, out result); - return result; - } - - /// - /// Constructs a that is the as large as the total combined area of the two specified spheres. - /// - /// The first sphere to merge. - /// The second sphere to merge. - /// When the method completes, contains the newly constructed bounding sphere. - public static void Merge(ref BoundingSphere value1, ref BoundingSphere value2, out BoundingSphere result) - { - Vector3 difference = value2.Center - value1.Center; - - float length = difference.Length(); - float radius = value1.Radius; - float radius2 = value2.Radius; - - if (radius + radius2 >= length) - { - if (radius - radius2 >= length) - { - result = value1; - return; - } - - if (radius2 - radius >= length) - { - result = value2; - return; - } - } - - Vector3 vector = difference * (1.0f / length); - float min = Math.Min(-radius, length - radius2); - float max = (Math.Max(radius, length + radius2) - min) * 0.5f; - - result.Center = value1.Center + vector * (max + min); - result.Radius = max; - } - - /// - /// Constructs a that is the as large as the total combined area of the two specified spheres. - /// - /// The first sphere to merge. - /// The second sphere to merge. - /// The newly constructed bounding sphere. - public static BoundingSphere Merge(BoundingSphere value1, BoundingSphere value2) - { - BoundingSphere result; - Merge(ref value1, ref value2, out result); - return result; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(BoundingSphere left, BoundingSphere right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(BoundingSphere left, BoundingSphere right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Center:{0} Radius:{1}", Center.ToString(), Radius.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "Center:{0} Radius:{1}", Center.ToString(format, CultureInfo.CurrentCulture), - Radius.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Center:{0} Radius:{1}", Center.ToString(), Radius.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "Center:{0} Radius:{1}", Center.ToString(format, formatProvider), - Radius.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Center.GetHashCode() + Radius.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(BoundingSphere value) - { - return Center == value.Center && Radius == value.Radius; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((BoundingSphere)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.BoundingSphere(BoundingSphere value) - { - return new SlimDX.BoundingSphere(value.Center, value.Radius); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator BoundingSphere(SlimDX.BoundingSphere value) - { - return new BoundingSphere(value.Center, value.Radius); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.BoundingSphere(BoundingSphere value) - { - return new Microsoft.Xna.Framework.BoundingSphere(value.Center, value.Radius); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator BoundingSphere(Microsoft.Xna.Framework.BoundingSphere value) - { - return new BoundingSphere(value.Center, value.Radius); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Collision.cs b/source/OrkEngine3D.Mathematics/Collision.cs deleted file mode 100644 index 1dcf5f5..0000000 --- a/source/OrkEngine3D.Mathematics/Collision.cs +++ /dev/null @@ -1,1724 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Globalization; -using System.Runtime.InteropServices; - -namespace OrkEngine3D.Mathematics; - -/* - * This class is organized so that the least complex objects come first so that the least - * complex objects will have the most methods in most cases. Note that not all shapes exist - * at this time and not all shapes have a corresponding struct. Only the objects that have - * a corresponding struct should come first in naming and in parameter order. The order of - * complexity is as follows: - * - * 1. Point - * 2. Ray - * 3. Segment - * 4. Plane - * 5. Triangle - * 6. Polygon (polygon that lies on a single plane) - * 7. Tetrahedron - * 8. Box - * 9. AABox - * 10. Sphere - * 11. Ellipsoid - * 12. Cylinder - * 13. Cone - * 14. Capsule - * 15. Torus - * 16. Polyhedron - * 17. Frustum -*/ - -/// -/// Contains static methods to help in determining intersections, containment, etc. -/// -public static class Collision -{ - /// - /// Determines the closest point between a point and a segment. - /// - /// The point to test. - /// The starting point of the segment to test. - /// The ending point of the segment to test. - /// When the method completes, contains the closest point between the two objects. - public static void ClosestPointOnSegmentToPoint(ref Vector3 segment1, ref Vector3 segment2, ref Vector3 point, out Vector3 result) - { - Vector3 ab = segment2 - segment1; - float t = Vector3.Dot(point - segment1, ab) / Vector3.Dot(ab, ab); - - if (t < 0.0f) - t = 0.0f; - - if (t > 1.0f) - t = 1.0f; - - result = segment1 + t * ab; - } - - /// - /// Determines the closest point between a and a point. - /// - /// The plane to test. - /// The point to test. - /// When the method completes, contains the closest point between the two objects. - public static void ClosestPointOnPlaneToPoint(ref Plane plane, ref Vector3 point, out Vector3 result) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 126 - - float dot; - Vector3.Dot(ref plane.Normal, ref point, out dot); - float t = dot - plane.D; - - result = point - (t * plane.Normal); - } - - /// - /// Determines the closest point between a point and a triangle. - /// - /// The point to test. - /// The first vertex to test. - /// The second vertex to test. - /// The third vertex to test. - /// When the method completes, contains the closest point between the two objects. - public static void ClosestPointOnTriangleToPoint(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, ref Vector3 point, out Vector3 result) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 136 - - //Check if P in vertex region outside A - Vector3 ab = vertex2 - vertex1; - Vector3 ac = vertex3 - vertex1; - Vector3 ap = point - vertex1; - - float d1 = Vector3.Dot(ab, ap); - float d2 = Vector3.Dot(ac, ap); - if (d1 <= 0.0f && d2 <= 0.0f) - { - result = vertex1; //Barycentric coordinates (1,0,0) - return; - } - - //Check if P in vertex region outside B - Vector3 bp = point - vertex2; - float d3 = Vector3.Dot(ab, bp); - float d4 = Vector3.Dot(ac, bp); - if (d3 >= 0.0f && d4 <= d3) - { - result = vertex2; // barycentric coordinates (0,1,0) - return; - } - - //Check if P in edge region of AB, if so return projection of P onto AB - float vc = d1 * d4 - d3 * d2; - if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) - { - float v = d1 / (d1 - d3); - result = vertex1 + v * ab; //Barycentric coordinates (1-v,v,0) - return; - } - - //Check if P in vertex region outside C - Vector3 cp = point - vertex3; - float d5 = Vector3.Dot(ab, cp); - float d6 = Vector3.Dot(ac, cp); - if (d6 >= 0.0f && d5 <= d6) - { - result = vertex3; //Barycentric coordinates (0,0,1) - return; - } - - //Check if P in edge region of AC, if so return projection of P onto AC - float vb = d5 * d2 - d1 * d6; - if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) - { - float w = d2 / (d2 - d6); - result = vertex1 + w * ac; //Barycentric coordinates (1-w,0,w) - return; - } - - //Check if P in edge region of BC, if so return projection of P onto BC - float va = d3 * d6 - d5 * d4; - if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) - { - float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - result = vertex2 + w * (vertex3 - vertex2); //Barycentric coordinates (0,1-w,w) - return; - } - - //P inside face region. Compute Q through its barycentric coordinates (u,v,w) - float denom = 1.0f / (va + vb + vc); - float v2 = vb * denom; - float w2 = vc * denom; - result = vertex1 + ab * v2 + ac * w2; //= u*vertex1 + v*vertex2 + w*vertex3, u = va * denom = 1.0f - v - w - } - - /// - /// Determines the closest point between a and a point. - /// - /// The box to test. - /// The point to test. - /// When the method completes, contains the closest point between the two objects. - public static void ClosestPointOnBoxToPoint(ref BoundingBox box, ref Vector3 point, out Vector3 result) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 130 - - Vector3 temp; - Vector3.Max(ref point, ref box.Minimum, out temp); - Vector3.Min(ref temp, ref box.Maximum, out result); - } - - /// - /// Determines the closest point between a and a point. - /// - /// - /// The point to test. - /// When the method completes, contains the closest point between the two objects; - /// or, if the point is directly in the center of the sphere, contains . - public static void ClosestPointOnSphereToPoint(ref BoundingSphere sphere, ref Vector3 point, out Vector3 result) - { - //Source: Jorgy343 - //Reference: None - - //Get the unit direction from the sphere's center to the point. - Vector3.Subtract(ref point, ref sphere.Center, out result); - result.Normalize(); - - //Multiply the unit direction by the sphere's radius to get a vector - //the length of the sphere. - result *= sphere.Radius; - - //Add the sphere's center to the direction to get a point on the sphere. - result += sphere.Center; - } - - /// - /// Determines the closest point between a and a . - /// - /// The first sphere to test. - /// The second sphere to test. - /// When the method completes, contains the closest point between the two objects; - /// or, if the point is directly in the center of the sphere, contains . - /// - /// If the two spheres are overlapping, but not directly ontop of each other, the closest point - /// is the 'closest' point of intersection. This can also be considered is the deepest point of - /// intersection. - /// - public static void ClosestPointOnSphereToSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2, out Vector3 result) - { - //Source: Jorgy343 - //Reference: None - - //Get the unit direction from the first sphere's center to the second sphere's center. - Vector3.Subtract(ref sphere2.Center, ref sphere1.Center, out result); - result.Normalize(); - - //Multiply the unit direction by the first sphere's radius to get a vector - //the length of the first sphere. - result *= sphere1.Radius; - - //Add the first sphere's center to the direction to get a point on the first sphere. - result += sphere1.Center; - } - - /// - /// Determines the distance between a and a point. - /// - /// The plane to test. - /// The point to test. - /// The distance between the two objects. - public static float DistancePlanePoint(ref Plane plane, ref Vector3 point) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 127 - - float dot; - Vector3.Dot(ref plane.Normal, ref point, out dot); - return dot - plane.D; - } - - /// - /// Determines the distance between a and a point. - /// - /// The box to test. - /// The point to test. - /// The distance between the two objects. - public static float DistanceBoxPoint(ref BoundingBox box, ref Vector3 point) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 131 - - float distance = 0f; - - if (point.X < box.Minimum.X) - distance += (box.Minimum.X - point.X) * (box.Minimum.X - point.X); - if (point.X > box.Maximum.X) - distance += (point.X - box.Maximum.X) * (point.X - box.Maximum.X); - - if (point.Y < box.Minimum.Y) - distance += (box.Minimum.Y - point.Y) * (box.Minimum.Y - point.Y); - if (point.Y > box.Maximum.Y) - distance += (point.Y - box.Maximum.Y) * (point.Y - box.Maximum.Y); - - if (point.Z < box.Minimum.Z) - distance += (box.Minimum.Z - point.Z) * (box.Minimum.Z - point.Z); - if (point.Z > box.Maximum.Z) - distance += (point.Z - box.Maximum.Z) * (point.Z - box.Maximum.Z); - - return (float)Math.Sqrt(distance); - } - - /// - /// Determines the distance between a and a . - /// - /// The first box to test. - /// The second box to test. - /// The distance between the two objects. - public static float DistanceBoxBox(ref BoundingBox box1, ref BoundingBox box2) - { - float distance = 0f; - - //Distance for X. - if (box1.Minimum.X > box2.Maximum.X) - { - float delta = box2.Maximum.X - box1.Minimum.X; - distance += delta * delta; - } - else if (box2.Minimum.X > box1.Maximum.X) - { - float delta = box1.Maximum.X - box2.Minimum.X; - distance += delta * delta; - } - - //Distance for Y. - if (box1.Minimum.Y > box2.Maximum.Y) - { - float delta = box2.Maximum.Y - box1.Minimum.Y; - distance += delta * delta; - } - else if (box2.Minimum.Y > box1.Maximum.Y) - { - float delta = box1.Maximum.Y - box2.Minimum.Y; - distance += delta * delta; - } - - //Distance for Z. - if (box1.Minimum.Z > box2.Maximum.Z) - { - float delta = box2.Maximum.Z - box1.Minimum.Z; - distance += delta * delta; - } - else if (box2.Minimum.Z > box1.Maximum.Z) - { - float delta = box1.Maximum.Z - box2.Minimum.Z; - distance += delta * delta; - } - - return (float)Math.Sqrt(distance); - } - - /// - /// Determines the distance between a and a point. - /// - /// The sphere to test. - /// The point to test. - /// The distance between the two objects. - public static float DistanceSpherePoint(ref BoundingSphere sphere, ref Vector3 point) - { - //Source: Jorgy343 - //Reference: None - - float distance; - Vector3.Distance(ref sphere.Center, ref point, out distance); - distance -= sphere.Radius; - - return Math.Max(distance, 0f); - } - - /// - /// Determines the distance between a and a . - /// - /// The first sphere to test. - /// The second sphere to test. - /// The distance between the two objects. - public static float DistanceSphereSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2) - { - //Source: Jorgy343 - //Reference: None - - float distance; - Vector3.Distance(ref sphere1.Center, ref sphere2.Center, out distance); - distance -= sphere1.Radius + sphere2.Radius; - - return Math.Max(distance, 0f); - } - - /// - /// Determines whether there is an intersection between a and a point. - /// - /// The ray to test. - /// The point to test. - /// Whether the two objects intersect. - public static bool RayIntersectsPoint(ref Ray ray, ref Vector3 point) - { - //Source: RayIntersectsSphere - //Reference: None - - Vector3 m; - Vector3.Subtract(ref ray.Position, ref point, out m); - - //Same thing as RayIntersectsSphere except that the radius of the sphere (point) - //is the epsilon for zero. - float b = Vector3.Dot(m, ray.Direction); - float c = Vector3.Dot(m, m) - Utilities.ZeroTolerance; - - if (c > 0f && b > 0f) - return false; - - float discriminant = b * b - c; - - if (discriminant < 0f) - return false; - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The first ray to test. - /// The second ray to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersect. - /// - /// This method performs a ray vs ray intersection test based on the following formula - /// from Goldman. - /// s = det([o₂ − o₁, d₂, d₁ ⨯ d₂]) / ‖d₁ ⨯ d₂‖² - /// t = det([o₂ − o₁, d₁, d₁ ⨯ d₂]) / ‖d₁ ⨯ d₂‖² - /// Where o₁ is the position of the first ray, o₂ is the position of the second ray, - /// d₁ is the normalized direction of the first ray, d₂ is the normalized direction - /// of the second ray, det denotes the determinant of a matrix, ⨯ denotes the cross - /// product, [ ] denotes a matrix, and ‖ ‖ denotes the length or magnitude of a vector. - /// - public static bool RayIntersectsRay(ref Ray ray1, ref Ray ray2, out Vector3 point) - { - //Source: Real-Time Rendering, Third Edition - //Reference: Page 780 - - Vector3 cross; - - Vector3.Cross(ref ray1.Direction, ref ray2.Direction, out cross); - float denominator = cross.Length(); - - //Lines are parallel. - if (Math.Abs(denominator) < Utilities.ZeroTolerance) - { - //Lines are parallel and on top of each other. - if (Math.Abs(ray2.Position.X - ray1.Position.X) < Utilities.ZeroTolerance && - Math.Abs(ray2.Position.Y - ray1.Position.Y) < Utilities.ZeroTolerance && - Math.Abs(ray2.Position.Z - ray1.Position.Z) < Utilities.ZeroTolerance) - { - point = Vector3.Zero; - return true; - } - } - - denominator = denominator * denominator; - - //3x3 matrix for the first ray. - float m11 = ray2.Position.X - ray1.Position.X; - float m12 = ray2.Position.Y - ray1.Position.Y; - float m13 = ray2.Position.Z - ray1.Position.Z; - float m21 = ray2.Direction.X; - float m22 = ray2.Direction.Y; - float m23 = ray2.Direction.Z; - float m31 = cross.X; - float m32 = cross.Y; - float m33 = cross.Z; - - //Determinant of first matrix. - float dets = - m11 * m22 * m33 + - m12 * m23 * m31 + - m13 * m21 * m32 - - m11 * m23 * m32 - - m12 * m21 * m33 - - m13 * m22 * m31; - - //3x3 matrix for the second ray. - m21 = ray1.Direction.X; - m22 = ray1.Direction.Y; - m23 = ray1.Direction.Z; - - //Determinant of the second matrix. - float dett = - m11 * m22 * m33 + - m12 * m23 * m31 + - m13 * m21 * m32 - - m11 * m23 * m32 - - m12 * m21 * m33 - - m13 * m22 * m31; - - //t values of the point of intersection. - float s = dets / denominator; - float t = dett / denominator; - - //The points of intersection. - Vector3 point1 = ray1.Position + (s * ray1.Direction); - Vector3 point2 = ray2.Position + (t * ray2.Direction); - - //If the points are not equal, no intersection has occured. - if (Math.Abs(point2.X - point1.X) > Utilities.ZeroTolerance || - Math.Abs(point2.Y - point1.Y) > Utilities.ZeroTolerance || - Math.Abs(point2.Z - point1.Z) > Utilities.ZeroTolerance) - { - point = Vector3.Zero; - return false; - } - - point = point1; - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The plane to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersect. - public static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out float distance) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 175 - - float direction; - Vector3.Dot(ref plane.Normal, ref ray.Direction, out direction); - - if (Math.Abs(direction) < Utilities.ZeroTolerance) - { - distance = 0f; - return false; - } - - float position; - Vector3.Dot(ref plane.Normal, ref ray.Position, out position); - distance = (-plane.D - position) / direction; - - if (distance < 0f) - { - if (distance < -Utilities.ZeroTolerance) - { - distance = 0; - return false; - } - - distance = 0f; - } - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The plane to test - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public static bool RayIntersectsPlane(ref Ray ray, ref Plane plane, out Vector3 point) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 175 - - float distance; - if (!RayIntersectsPlane(ref ray, ref plane, out distance)) - { - point = Vector3.Zero; - return false; - } - - point = ray.Position + (ray.Direction * distance); - return true; - } - - /// - /// Determines whether there is an intersection between a and a triangle. - /// - /// The ray to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - /// - /// This method tests if the ray intersects either the front or back of the triangle. - /// If the ray is parallel to the triangle's plane, no intersection is assumed to have - /// happened. If the intersection of the ray and the triangle is behind the origin of - /// the ray, no intersection is assumed to have happened. In both cases of assumptions, - /// this method returns false. - /// - public static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out float distance) - { - //Source: Fast Minimum Storage Ray / Triangle Intersection - //Reference: http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf - - //Compute vectors along two edges of the triangle. - Vector3 edge1, edge2; - - //Edge 1 - edge1.X = vertex2.X - vertex1.X; - edge1.Y = vertex2.Y - vertex1.Y; - edge1.Z = vertex2.Z - vertex1.Z; - - //Edge2 - edge2.X = vertex3.X - vertex1.X; - edge2.Y = vertex3.Y - vertex1.Y; - edge2.Z = vertex3.Z - vertex1.Z; - - //Cross product of ray direction and edge2 - first part of determinant. - Vector3 directioncrossedge2; - directioncrossedge2.X = (ray.Direction.Y * edge2.Z) - (ray.Direction.Z * edge2.Y); - directioncrossedge2.Y = (ray.Direction.Z * edge2.X) - (ray.Direction.X * edge2.Z); - directioncrossedge2.Z = (ray.Direction.X * edge2.Y) - (ray.Direction.Y * edge2.X); - - //Compute the determinant. - float determinant; - //Dot product of edge1 and the first part of determinant. - determinant = (edge1.X * directioncrossedge2.X) + (edge1.Y * directioncrossedge2.Y) + (edge1.Z * directioncrossedge2.Z); - - //If the ray is parallel to the triangle plane, there is no collision. - //This also means that we are not culling, the ray may hit both the - //back and the front of the triangle. - if (determinant > -Utilities.ZeroTolerance && determinant < Utilities.ZeroTolerance) - { - distance = 0f; - return false; - } - - float inversedeterminant = 1.0f / determinant; - - //Calculate the U parameter of the intersection point. - Vector3 distanceVector; - distanceVector.X = ray.Position.X - vertex1.X; - distanceVector.Y = ray.Position.Y - vertex1.Y; - distanceVector.Z = ray.Position.Z - vertex1.Z; - - float triangleU; - triangleU = (distanceVector.X * directioncrossedge2.X) + (distanceVector.Y * directioncrossedge2.Y) + (distanceVector.Z * directioncrossedge2.Z); - triangleU *= inversedeterminant; - - //Make sure it is inside the triangle. - if (triangleU < 0f || triangleU > 1f) - { - distance = 0f; - return false; - } - - //Calculate the V parameter of the intersection point. - Vector3 distancecrossedge1; - distancecrossedge1.X = (distanceVector.Y * edge1.Z) - (distanceVector.Z * edge1.Y); - distancecrossedge1.Y = (distanceVector.Z * edge1.X) - (distanceVector.X * edge1.Z); - distancecrossedge1.Z = (distanceVector.X * edge1.Y) - (distanceVector.Y * edge1.X); - - float triangleV; - triangleV = ((ray.Direction.X * distancecrossedge1.X) + (ray.Direction.Y * distancecrossedge1.Y)) + (ray.Direction.Z * distancecrossedge1.Z); - triangleV *= inversedeterminant; - - //Make sure it is inside the triangle. - if (triangleV < 0f || triangleU + triangleV > 1f) - { - distance = 0f; - return false; - } - - //Compute the distance along the ray to the triangle. - float raydistance; - raydistance = (edge2.X * distancecrossedge1.X) + (edge2.Y * distancecrossedge1.Y) + (edge2.Z * distancecrossedge1.Z); - raydistance *= inversedeterminant; - - //Is the triangle behind the ray origin? - if (raydistance < 0f) - { - distance = 0f; - return false; - } - - distance = raydistance; - return true; - } - - /// - /// Determines whether there is an intersection between a and a triangle. - /// - /// The ray to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public static bool RayIntersectsTriangle(ref Ray ray, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 point) - { - float distance; - if (!RayIntersectsTriangle(ref ray, ref vertex1, ref vertex2, ref vertex3, out distance)) - { - point = Vector3.Zero; - return false; - } - - point = ray.Position + (ray.Direction * distance); - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The box to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out float distance) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 179 - - distance = 0f; - float tmax = float.MaxValue; - - if (Math.Abs(ray.Direction.X) < Utilities.ZeroTolerance) - { - if (ray.Position.X < box.Minimum.X || ray.Position.X > box.Maximum.X) - { - distance = 0f; - return false; - } - } - else - { - float inverse = 1.0f / ray.Direction.X; - float t1 = (box.Minimum.X - ray.Position.X) * inverse; - float t2 = (box.Maximum.X - ray.Position.X) * inverse; - - if (t1 > t2) - { - float temp = t1; - t1 = t2; - t2 = temp; - } - - distance = Math.Max(t1, distance); - tmax = Math.Min(t2, tmax); - - if (distance > tmax) - { - distance = 0f; - return false; - } - } - - if (Math.Abs(ray.Direction.Y) < Utilities.ZeroTolerance) - { - if (ray.Position.Y < box.Minimum.Y || ray.Position.Y > box.Maximum.Y) - { - distance = 0f; - return false; - } - } - else - { - float inverse = 1.0f / ray.Direction.Y; - float t1 = (box.Minimum.Y - ray.Position.Y) * inverse; - float t2 = (box.Maximum.Y - ray.Position.Y) * inverse; - - if (t1 > t2) - { - float temp = t1; - t1 = t2; - t2 = temp; - } - - distance = Math.Max(t1, distance); - tmax = Math.Min(t2, tmax); - - if (distance > tmax) - { - distance = 0f; - return false; - } - } - - if (Math.Abs(ray.Direction.Z) < Utilities.ZeroTolerance) - { - if (ray.Position.Z < box.Minimum.Z || ray.Position.Z > box.Maximum.Z) - { - distance = 0f; - return false; - } - } - else - { - float inverse = 1.0f / ray.Direction.Z; - float t1 = (box.Minimum.Z - ray.Position.Z) * inverse; - float t2 = (box.Maximum.Z - ray.Position.Z) * inverse; - - if (t1 > t2) - { - float temp = t1; - t1 = t2; - t2 = temp; - } - - distance = Math.Max(t1, distance); - tmax = Math.Min(t2, tmax); - - if (distance > tmax) - { - distance = 0f; - return false; - } - } - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The box to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public static bool RayIntersectsBox(ref Ray ray, ref BoundingBox box, out Vector3 point) - { - float distance; - if (!RayIntersectsBox(ref ray, ref box, out distance)) - { - point = Vector3.Zero; - return false; - } - - point = ray.Position + (ray.Direction * distance); - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The sphere to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - /// - /// - /// This method uses the following math to compute the intersection: - /// ‖x − c‖² = r² Equation of sphere - /// x = s + td Equation of ray - /// - /// Solve for t - /// ‖s + td − c‖² = r² Substitute equation of ray into equation of sphere - /// v ≝ s − c - /// ‖v + td‖² = r² - /// v² + 2v⋅td + t²d² = r² - /// d²t² + (2v⋅d)t + (v² − r²) = 0 - /// t² + (2v⋅d)t + (v² − r²) = 0 If d is a normalized vector - /// - /// Quadratic equation gives us - /// t = (−(2v⋅d) ± √((2v⋅d)² − 4(v² − r)²)) / 2 - /// t = −(v⋅d) ± √((v⋅d)² − (v² − r)²) - /// - /// - /// Entrance of intersection is given by the smaller t - /// t = −(v⋅d) − √((v⋅d)² − (v² − r)²) - /// - /// Exit of intersection is given by the larger t - /// t = −(v⋅d) + √((v⋅d)² − (v² − r)²) - /// - /// If the smaller t value is < 0 than the ray started inside of the sphere. - /// - /// If the descriminant (v⋅d)² − (v² − r)² is < 0 than no intersection occured. If the - /// descriminant (v⋅d)² − (v² − r)² is = 0 than the ray is tangential to the sphere. If - /// the descriminant (v⋅d)² − (v² − r)² is > 0 than the ray passes through the sphere. - /// - /// - public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out float distance) - { - Vector3 v; - Vector3.Subtract(ref ray.Position, ref sphere.Center, out v); - - float b = Vector3.Dot(v, ray.Direction); - float c = Vector3.Dot(v, v) - (sphere.Radius * sphere.Radius); - - if (c > 0f && b > 0f) - { - distance = 0f; - return false; - } - - float discriminant = b * b - c; - - if (discriminant < 0f) - { - distance = 0f; - return false; - } - - distance = -b - (float)Math.Sqrt(discriminant); - - if (distance < 0f) - distance = 0f; - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The sphere to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - /// - /// - /// This method uses the following math to compute the intersection: - /// ‖x − c‖² = r² Equation of sphere - /// x = s + td Equation of ray - /// - /// Solve for t - /// ‖s + td − c‖² = r² Substitute equation of ray into equation of sphere - /// v ≝ s − c - /// ‖v + td‖² = r² - /// v² + 2v⋅td + t²d² = r² - /// d²t² + (2v⋅d)t + (v² − r²) = 0 - /// t² + (2v⋅d)t + (v² − r²) = 0 If d is a normalized vector - /// - /// Quadratic equation gives us - /// t = (−(2v⋅d) ± √((2v⋅d)² − 4(v² − r)²)) / 2 - /// t = −(v⋅d) ± √((v⋅d)² − (v² − r)²) - /// - /// - /// Entrance of intersection is given by the smaller t - /// t = −(v⋅d) − √((v⋅d)² − (v² − r)²) - /// - /// Exit of intersection is given by the larger t - /// t = −(v⋅d) + √((v⋅d)² − (v² − r)²) - /// - /// If the smaller t value is < 0 than the ray started inside of the sphere. - /// - /// If the descriminant (v⋅d)² − (v² − r)² is < 0 than no intersection occured. If the - /// descriminant (v⋅d)² − (v² − r)² is = 0 than the ray is tangential to the sphere. If - /// the descriminant (v⋅d)² − (v² − r)² is > 0 than the ray passes through the sphere. - /// - /// - public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out Vector3 point) - { - float distance; - if (!RayIntersectsSphere(ref ray, ref sphere, out distance)) - { - point = Vector3.Zero; - return false; - } - - point = ray.Position + (ray.Direction * distance); - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The sphere to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// When the method completes, contains the normal vector on the - /// sphere at the point of intersection. - /// Whether the two objects intersected. - /// - /// - /// This method uses the following math to compute the intersection: - /// ‖x − c‖² = r² Equation of sphere - /// x = s + td Equation of ray - /// - /// Solve for t - /// ‖s + td − c‖² = r² Substitute equation of ray into equation of sphere - /// v ≝ s − c - /// ‖v + td‖² = r² - /// v² + 2v⋅td + t²d² = r² - /// d²t² + (2v⋅d)t + (v² − r²) = 0 - /// t² + (2v⋅d)t + (v² − r²) = 0 If d is a normalized vector - /// - /// Quadratic equation gives us - /// t = (−(2v⋅d) ± √((2v⋅d)² − 4(v² − r)²)) / 2 - /// t = −(v⋅d) ± √((v⋅d)² − (v² − r)²) - /// - /// - /// Entrance of intersection is given by the smaller t - /// t = −(v⋅d) − √((v⋅d)² − (v² − r)²) - /// - /// Exit of intersection is given by the larger t - /// t = −(v⋅d) + √((v⋅d)² − (v² − r)²) - /// - /// If the smaller t value is < 0 than the ray started inside of the sphere. - /// - /// If the descriminant (v⋅d)² − (v² − r)² is < 0 than no intersection occured. If the - /// descriminant (v⋅d)² − (v² − r)² is = 0 than the ray is tangential to the sphere. If - /// the descriminant (v⋅d)² − (v² − r)² is > 0 than the ray passes through the sphere. - /// - /// - public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out Vector3 point, out Vector3 normal) - { - float distance; - if (!RayIntersectsSphere(ref ray, ref sphere, out distance)) - { - point = Vector3.Zero; - normal = Vector3.Zero; - return false; - } - - point = ray.Position + (ray.Direction * distance); - normal = point - sphere.Center; - normal.Normalize(); - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The ray to test. - /// The sphere to test. - /// When the method completes, contains the closest point of intersection, - /// or if there was no intersection. - /// When the method completes, contains the normal vector on the - /// sphere at the point of closest intersection. - /// When the method completes, contains the farthest point of intersection, - /// or if there was no intersection. - /// Whent he method completes, contains the normal vector on the - /// sphere at the point of farthest intersection. - /// Whether the two objects intersected. - /// - /// - /// This method uses the following math to compute the intersection: - /// ‖x − c‖² = r² Equation of sphere - /// x = s + td Equation of ray - /// - /// Solve for t - /// ‖s + td − c‖² = r² Substitute equation of ray into equation of sphere - /// v ≝ s − c - /// ‖v + td‖² = r² - /// v² + 2v⋅td + t²d² = r² - /// d²t² + (2v⋅d)t + (v² − r²) = 0 - /// t² + (2v⋅d)t + (v² − r²) = 0 If d is a normalized vector - /// - /// Quadratic equation gives us - /// t = (−(2v⋅d) ± √((2v⋅d)² − 4(v² − r)²)) / 2 - /// t = −(v⋅d) ± √((v⋅d)² − (v² − r)²) - /// - /// - /// Entrance of intersection is given by the smaller t - /// t = −(v⋅d) − √((v⋅d)² − (v² − r)²) - /// - /// Exit of intersection is given by the larger t - /// t = −(v⋅d) + √((v⋅d)² − (v² − r)²) - /// - /// If the smaller t value is < 0 than the ray started inside of the sphere. - /// - /// If the descriminant (v⋅d)² − (v² − r)² is < 0 than no intersection occured. If the - /// descriminant (v⋅d)² − (v² − r)² is = 0 than the ray is tangential to the sphere. If - /// the descriminant (v⋅d)² − (v² − r)² is > 0 than the ray passes through the sphere. - /// - /// - public static bool RayIntersectsSphere(ref Ray ray, ref BoundingSphere sphere, out Vector3 entrancePoint, out Vector3 entranceNormal, out Vector3 exitPoint, out Vector3 exitNormal) - { - Vector3 v; - Vector3.Subtract(ref ray.Position, ref sphere.Center, out v); - - float b = Vector3.Dot(v, ray.Direction); - float c = Vector3.Dot(v, v) - (sphere.Radius * sphere.Radius); - - if (c > 0f && b > 0f) - { - entrancePoint = Vector3.Zero; - entranceNormal = Vector3.Zero; - exitPoint = Vector3.Zero; - exitNormal = Vector3.Zero; - return false; - } - - float discriminant = b * b - c; - - if (discriminant < 0f) - { - entrancePoint = Vector3.Zero; - entranceNormal = Vector3.Zero; - exitPoint = Vector3.Zero; - exitNormal = Vector3.Zero; - return false; - } - - float discriminantSquared = (float)Math.Sqrt(discriminant); - float distance1 = -b - discriminantSquared; - float distance2 = -b + discriminantSquared; - - if (distance1 < 0f) - { - distance1 = 0f; - entrancePoint = Vector3.Zero; - entranceNormal = Vector3.Zero; - } - else - { - entrancePoint = ray.Position + (ray.Direction * distance1); - entranceNormal = entrancePoint - sphere.Center; - entranceNormal.Normalize(); - } - - exitPoint = ray.Position + (ray.Direction * distance2); - exitNormal = exitPoint - sphere.Center; - exitNormal.Normalize(); - - return true; - } - - /// - /// Determines whether there is an intersection between a and a point. - /// - /// The plane to test. - /// The point to test. - /// Whether the two objects intersected. - public static PlaneIntersectionType PlaneIntersectsPoint(ref Plane plane, ref Vector3 point) - { - float distance; - Vector3.Dot(ref plane.Normal, ref point, out distance); - distance += plane.D; - - if (distance > 0f) - return PlaneIntersectionType.Front; - - if (distance < 0f) - return PlaneIntersectionType.Back; - - return PlaneIntersectionType.Intersecting; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The first plane to test. - /// The second plane to test. - /// Whether the two objects intersected. - public static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2) - { - Vector3 direction; - Vector3.Cross(ref plane1.Normal, ref plane2.Normal, out direction); - - //If direction is the zero vector, the planes are parallel and possibly - //coincident. It is not an intersection. The dot product will tell us. - float denominator; - Vector3.Dot(ref direction, ref direction, out denominator); - - if (Math.Abs(denominator) < Utilities.ZeroTolerance) - return false; - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The first plane to test. - /// The second plane to test. - /// When the method completes, contains the line of intersection - /// as a , or a zero ray if there was no intersection. - /// Whether the two objects intersected. - /// - /// Although a ray is set to have an origin, the ray returned by this method is really - /// a line in three dimensions which has no real origin. The ray is considered valid when - /// both the positive direction is used and when the negative direction is used. - /// - public static bool PlaneIntersectsPlane(ref Plane plane1, ref Plane plane2, out Ray line) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 207 - - Vector3 direction; - Vector3.Cross(ref plane1.Normal, ref plane2.Normal, out direction); - - //If direction is the zero vector, the planes are parallel and possibly - //coincident. It is not an intersection. The dot product will tell us. - float denominator; - Vector3.Dot(ref direction, ref direction, out denominator); - - //We assume the planes are normalized, therefore the denominator - //only serves as a parallel and coincident check. Otherwise we need - //to deivide the point by the denominator. - if (Math.Abs(denominator) < Utilities.ZeroTolerance) - { - line = new Ray(); - return false; - } - - Vector3 point; - Vector3 temp = plane1.D * plane2.Normal - plane2.D * plane1.Normal; - Vector3.Cross(ref temp, ref direction, out point); - - line.Position = point; - line.Direction = direction; - line.Direction.Normalize(); - - return true; - } - - /// - /// Determines whether there is an intersection between a and a triangle. - /// - /// The plane to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public static PlaneIntersectionType PlaneIntersectsTriangle(ref Plane plane, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 207 - - PlaneIntersectionType test1 = PlaneIntersectsPoint(ref plane, ref vertex1); - PlaneIntersectionType test2 = PlaneIntersectsPoint(ref plane, ref vertex2); - PlaneIntersectionType test3 = PlaneIntersectsPoint(ref plane, ref vertex3); - - if (test1 == PlaneIntersectionType.Front && test2 == PlaneIntersectionType.Front && test3 == PlaneIntersectionType.Front) - return PlaneIntersectionType.Front; - - if (test1 == PlaneIntersectionType.Back && test2 == PlaneIntersectionType.Back && test3 == PlaneIntersectionType.Back) - return PlaneIntersectionType.Back; - - return PlaneIntersectionType.Intersecting; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The plane to test. - /// The box to test. - /// Whether the two objects intersected. - public static PlaneIntersectionType PlaneIntersectsBox(ref Plane plane, ref BoundingBox box) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 161 - - Vector3 min; - Vector3 max; - - max.X = (plane.Normal.X >= 0.0f) ? box.Minimum.X : box.Maximum.X; - max.Y = (plane.Normal.Y >= 0.0f) ? box.Minimum.Y : box.Maximum.Y; - max.Z = (plane.Normal.Z >= 0.0f) ? box.Minimum.Z : box.Maximum.Z; - min.X = (plane.Normal.X >= 0.0f) ? box.Maximum.X : box.Minimum.X; - min.Y = (plane.Normal.Y >= 0.0f) ? box.Maximum.Y : box.Minimum.Y; - min.Z = (plane.Normal.Z >= 0.0f) ? box.Maximum.Z : box.Minimum.Z; - - float distance; - Vector3.Dot(ref plane.Normal, ref max, out distance); - - if (distance + plane.D > 0.0f) - return PlaneIntersectionType.Front; - - distance = Vector3.Dot(plane.Normal, min); - - if (distance + plane.D < 0.0f) - return PlaneIntersectionType.Back; - - return PlaneIntersectionType.Intersecting; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The plane to test. - /// The sphere to test. - /// Whether the two objects intersected. - public static PlaneIntersectionType PlaneIntersectsSphere(ref Plane plane, ref BoundingSphere sphere) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 160 - - float distance; - Vector3.Dot(ref plane.Normal, ref sphere.Center, out distance); - distance += plane.D; - - if (distance > sphere.Radius) - return PlaneIntersectionType.Front; - - if (distance < -sphere.Radius) - return PlaneIntersectionType.Back; - - return PlaneIntersectionType.Intersecting; - } - - //THIS IMPLEMENTATION IS INCOMPLETE! - //NEEDS TO BE COMPLETED SOON - /// - /// Determines whether there is an intersection between a and a triangle. - /// - /// The box to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public static bool BoxIntersectsTriangle(ref BoundingBox box, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 169 - - //NOTE: I, jimmy, removed an unused variable - float p0, p2, r; - - //Compute box center and extents (if not already given in that format) - Vector3 center = (box.Minimum + box.Maximum) * 0.5f; - float e0 = (box.Maximum.X - box.Minimum.X) * 0.5f; - float e1 = (box.Maximum.Y - box.Minimum.Y) * 0.5f; - float e2 = (box.Maximum.Z - box.Minimum.Z) * 0.5f; - - //Translate triangle as conceptually moving AABB to origin - vertex1 = vertex1 - center; - vertex2 = vertex2 - center; - vertex3 = vertex3 - center; - - //Compute edge vectors for triangle - Vector3 f0 = vertex2 - vertex1; - Vector3 f1 = vertex3 - vertex2; - Vector3 f2 = vertex1 - vertex3; - - //Test axes a00..a22 (category 3) - //Test axis a00 - p0 = vertex1.Z * vertex2.Y - vertex1.Y * vertex2.Z; - p2 = vertex3.Z * (vertex2.Y - vertex1.Y) - vertex3.Z * (vertex2.Z - vertex1.Z); - r = e1 * Math.Abs(f0.Z) + e2 * Math.Abs(f0.Y); - - if (Math.Max(-Math.Max(p0, p2), Math.Min(p0, p2)) > r) - return false; //Axis is a separating axis - - //Repeat similar tests for remaining axes a01..a22 - //... - - //Test the three axes corresponding to the face normals of AABB b (category 1). - //Exit if... - // ... [-e0, e0] and [Math.Min(vertex1.X,vertex2.X,vertex3.X), Math.Max(vertex1.X,vertex2.X,vertex3.X)] do not overlap - if (Math.Max(Math.Max(vertex1.X, vertex2.X), vertex3.X) < -e0 || Math.Min(Math.Min(vertex1.X, vertex2.X), vertex3.X) > e0) - return false; - - // ... [-e1, e1] and [Math.Min(vertex1.Y,vertex2.Y,vertex3.Y), Math.Max(vertex1.Y,vertex2.Y,vertex3.Y)] do not overlap - if (Math.Max(Math.Max(vertex1.Y, vertex2.Y), vertex3.Y) < -e1 || Math.Min(Math.Min(vertex1.Y, vertex2.Y), vertex3.Y) > e1) - return false; - - // ... [-e2, e2] and [Math.Min(vertex1.Z,vertex2.Z,vertex3.Z), Math.Max(vertex1.Z,vertex2.Z,vertex3.Z)] do not overlap - if (Math.Max(Math.Max(vertex1.Z, vertex2.Z), vertex3.Z) < -e2 || Math.Min(Math.Min(vertex1.Z, vertex2.Z), vertex3.Z) > e2) - return false; - - //Test separating axis corresponding to triangle face normal (category 2) - Plane plane; - plane.Normal = Vector3.Cross(f0, f1); - plane.D = Vector3.Dot(plane.Normal, vertex1); - - return PlaneIntersectsBox(ref plane, ref box) == PlaneIntersectionType.Intersecting; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The first box to test. - /// The second box to test. - /// Whether the two objects intersected. - public static bool BoxIntersectsBox(ref BoundingBox box1, ref BoundingBox box2) - { - if (box1.Minimum.X > box2.Maximum.X || box2.Minimum.X > box1.Maximum.X) - return false; - - if (box1.Minimum.Y > box2.Maximum.Y || box2.Minimum.Y > box1.Maximum.Y) - return false; - - if (box1.Minimum.Z > box2.Maximum.Z || box2.Minimum.Z > box1.Maximum.Z) - return false; - - return true; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// The box to test. - /// The sphere to test. - /// Whether the two objects intersected. - public static bool BoxIntersectsSphere(ref BoundingBox box, ref BoundingSphere sphere) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 166 - - Vector3 vector; - Vector3.Clamp(ref sphere.Center, ref box.Minimum, ref box.Maximum, out vector); - float distance = Vector3.DistanceSquared(sphere.Center, vector); - - return distance <= sphere.Radius * sphere.Radius; - } - - /// - /// Determines whether there is an intersection between a and a triangle. - /// - /// The sphere to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public static bool SphereIntersectsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 167 - - Vector3 point; - ClosestPointOnTriangleToPoint(ref sphere.Center, ref vertex1, ref vertex2, ref vertex3, out point); - Vector3 v = point - sphere.Center; - - float dot; - Vector3.Dot(ref v, ref v, out dot); - - return dot <= sphere.Radius * sphere.Radius; - } - - /// - /// Determines whether there is an intersection between a and a . - /// - /// First sphere to test. - /// Second sphere to test. - /// Whether the two objects intersected. - public static bool SphereIntersectsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2) - { - float radiisum = sphere1.Radius + sphere2.Radius; - return Vector3.DistanceSquared(sphere1.Center, sphere2.Center) <= radiisum * radiisum; - } - - /// - /// Determines whether a contains a point. - /// - /// The box to test. - /// The point to test. - /// The type of containment the two objects have. - public static ContainmentType BoxContainsPoint(ref BoundingBox box, ref Vector3 point) - { - if (box.Minimum.X <= point.X && box.Maximum.X >= point.X && - box.Minimum.Y <= point.Y && box.Maximum.Y >= point.Y && - box.Minimum.Z <= point.Z && box.Maximum.Z >= point.Z) - { - return ContainmentType.Contains; - } - - return ContainmentType.Disjoint; - } - - /// - /// Determines whether a contains a triangle. - /// - /// The box to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// The type of containment the two objects have. - public static ContainmentType BoxContainsTriangle(ref BoundingBox box, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - ContainmentType test1 = BoxContainsPoint(ref box, ref vertex1); - ContainmentType test2 = BoxContainsPoint(ref box, ref vertex2); - ContainmentType test3 = BoxContainsPoint(ref box, ref vertex3); - - if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains) - return ContainmentType.Contains; - - if (BoxIntersectsTriangle(ref box, ref vertex1, ref vertex2, ref vertex3)) - return ContainmentType.Intersects; - - return ContainmentType.Disjoint; - } - - /// - /// Determines whether a contains a . - /// - /// The first box to test. - /// The second box to test. - /// The type of containment the two objects have. - public static ContainmentType BoxContainsBox(ref BoundingBox box1, ref BoundingBox box2) - { - if (box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X) - return ContainmentType.Disjoint; - - if (box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y) - return ContainmentType.Disjoint; - - if (box1.Maximum.Z < box2.Minimum.Z || box1.Minimum.Z > box2.Maximum.Z) - return ContainmentType.Disjoint; - - if (box1.Minimum.X <= box2.Minimum.X && (box2.Maximum.X <= box1.Maximum.X && - box1.Minimum.Y <= box2.Minimum.Y && box2.Maximum.Y <= box1.Maximum.Y) && - box1.Minimum.Z <= box2.Minimum.Z && box2.Maximum.Z <= box1.Maximum.Z) - { - return ContainmentType.Contains; - } - - return ContainmentType.Intersects; - } - - /// - /// Determines whether a contains a . - /// - /// The box to test. - /// The sphere to test. - /// The type of containment the two objects have. - public static ContainmentType BoxContainsSphere(ref BoundingBox box, ref BoundingSphere sphere) - { - Vector3 vector; - Vector3.Clamp(ref sphere.Center, ref box.Minimum, ref box.Maximum, out vector); - float distance = Vector3.DistanceSquared(sphere.Center, vector); - - if (distance > sphere.Radius * sphere.Radius) - return ContainmentType.Disjoint; - - if ((((box.Minimum.X + sphere.Radius <= sphere.Center.X) && (sphere.Center.X <= box.Maximum.X - sphere.Radius)) && ((box.Maximum.X - box.Minimum.X > sphere.Radius) && - (box.Minimum.Y + sphere.Radius <= sphere.Center.Y))) && (((sphere.Center.Y <= box.Maximum.Y - sphere.Radius) && (box.Maximum.Y - box.Minimum.Y > sphere.Radius)) && - (((box.Minimum.Z + sphere.Radius <= sphere.Center.Z) && (sphere.Center.Z <= box.Maximum.Z - sphere.Radius)) && (box.Maximum.X - box.Minimum.X > sphere.Radius)))) - { - return ContainmentType.Contains; - } - - return ContainmentType.Intersects; - } - - /// - /// Determines whether a contains a point. - /// - /// The sphere to test. - /// The point to test. - /// The type of containment the two objects have. - public static ContainmentType SphereContainsPoint(ref BoundingSphere sphere, ref Vector3 point) - { - if (Vector3.DistanceSquared(point, sphere.Center) <= sphere.Radius * sphere.Radius) - return ContainmentType.Contains; - - return ContainmentType.Disjoint; - } - - /// - /// Determines whether a contains a triangle. - /// - /// The sphere to test. - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// The type of containment the two objects have. - public static ContainmentType SphereContainsTriangle(ref BoundingSphere sphere, ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - //Source: Jorgy343 - //Reference: None - - ContainmentType test1 = SphereContainsPoint(ref sphere, ref vertex1); - ContainmentType test2 = SphereContainsPoint(ref sphere, ref vertex2); - ContainmentType test3 = SphereContainsPoint(ref sphere, ref vertex3); - - if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains) - return ContainmentType.Contains; - - if (SphereIntersectsTriangle(ref sphere, ref vertex1, ref vertex2, ref vertex3)) - return ContainmentType.Intersects; - - return ContainmentType.Disjoint; - } - - /// - /// Determines whether a contains a . - /// - /// The sphere to test. - /// The box to test. - /// The type of containment the two objects have. - public static ContainmentType SphereContainsBox(ref BoundingSphere sphere, ref BoundingBox box) - { - Vector3 vector; - - if (!BoxIntersectsSphere(ref box, ref sphere)) - return ContainmentType.Disjoint; - - float radiussquared = sphere.Radius * sphere.Radius; - vector.X = sphere.Center.X - box.Minimum.X; - vector.Y = sphere.Center.Y - box.Maximum.Y; - vector.Z = sphere.Center.Z - box.Maximum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Maximum.X; - vector.Y = sphere.Center.Y - box.Maximum.Y; - vector.Z = sphere.Center.Z - box.Maximum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Maximum.X; - vector.Y = sphere.Center.Y - box.Minimum.Y; - vector.Z = sphere.Center.Z - box.Maximum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Minimum.X; - vector.Y = sphere.Center.Y - box.Minimum.Y; - vector.Z = sphere.Center.Z - box.Maximum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Minimum.X; - vector.Y = sphere.Center.Y - box.Maximum.Y; - vector.Z = sphere.Center.Z - box.Minimum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Maximum.X; - vector.Y = sphere.Center.Y - box.Maximum.Y; - vector.Z = sphere.Center.Z - box.Minimum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Maximum.X; - vector.Y = sphere.Center.Y - box.Minimum.Y; - vector.Z = sphere.Center.Z - box.Minimum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - vector.X = sphere.Center.X - box.Minimum.X; - vector.Y = sphere.Center.Y - box.Minimum.Y; - vector.Z = sphere.Center.Z - box.Minimum.Z; - - if (vector.LengthSquared() > radiussquared) - return ContainmentType.Intersects; - - return ContainmentType.Contains; - } - - /// - /// Determines whether a contains a . - /// - /// The first sphere to test. - /// The second sphere to test. - /// The type of containment the two objects have. - public static ContainmentType SphereContainsSphere(ref BoundingSphere sphere1, ref BoundingSphere sphere2) - { - float distance = Vector3.Distance(sphere1.Center, sphere2.Center); - - if (sphere1.Radius + sphere2.Radius < distance) - return ContainmentType.Disjoint; - - if (sphere1.Radius - sphere2.Radius < distance) - return ContainmentType.Intersects; - - return ContainmentType.Contains; - } - - /// - /// Generates a supporting point from a specific triangle. - /// - /// The first vertex of the triangle. - /// The second vertex of the triangle. - /// The third vertex of the triangle - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public static void SupportPoint(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, ref Vector3 direction, out Vector3 result) - { - float dot1 = Vector3.Dot(vertex1, direction); - float dot2 = Vector3.Dot(vertex2, direction); - float dot3 = Vector3.Dot(vertex3, direction); - - if (dot1 > dot2 && dot1 > dot3) - result = vertex1; - else if (dot2 > dot1 && dot2 > dot3) - result = vertex2; - else - result = vertex3; - } - - /// - /// Generates a supporting point from a specific . - /// - /// The box to generate the supporting point for. - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public static void SupportPoint(ref BoundingBox box, ref Vector3 direction, out Vector3 result) - { - result.X = direction.X >= 0.0f ? box.Maximum.X : box.Minimum.X; - result.Y = direction.Y >= 0.0f ? box.Maximum.Y : box.Minimum.Y; - result.Z = direction.Z >= 0.0f ? box.Maximum.Z : box.Minimum.Z; - } - - /// - /// Generates a supporting point from a specific . - /// - /// The sphere to generate the supporting point for. - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public static void SupportPoint(ref BoundingSphere sphere, ref Vector3 direction, out Vector3 result) - { - result = (sphere.Radius / direction.Length()) * direction + sphere.Center; - } - - /// - /// Generates a supporting point from a polyhedra. - /// - /// The points that make up the polyhedra. - /// The direction for which to build the supporting point. - /// When the method completes, contains the supporting point. - public static void SupportPoint(IEnumerable points, ref Vector3 direction, out Vector3 result) - { - float maxdot = float.MinValue; - result = Vector3.Zero; - - foreach (Vector3 point in points) - { - float tempdot = Vector3.Dot(direction, point); - - if (tempdot > maxdot) - { - maxdot = tempdot; - result = point; - } - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Color.cs b/source/OrkEngine3D.Mathematics/Color.cs deleted file mode 100644 index 3fde05c..0000000 --- a/source/OrkEngine3D.Mathematics/Color.cs +++ /dev/null @@ -1,1134 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; -using System.Runtime.InteropServices; -using System.Globalization; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A). -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Size = 4)] -public partial struct Color : IEquatable, IFormattable -{ - - /// - /// The red component of the color. - /// - public byte Red; - - /// - /// The green component of the color. - /// - public byte Green; - - /// - /// The blue component of the color. - /// - public byte Blue; - - /// - /// The alpha component of the color. - /// - public byte Alpha; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Color(byte value) - { - Red = value; - Green = value; - Blue = value; - Alpha = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Color(float value) : this(ToByte(value)) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - /// The alpha component of the color. - public Color(byte red, byte green, byte blue, byte alpha) - { - Red = red; - Green = green; - Blue = blue; - Alpha = alpha; - } - - /// - /// Initializes a new instance of the struct. Alpha is set to 255. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color(byte red, byte green, byte blue) - { - Red = red; - Green = green; - Blue = blue; - Alpha = 255; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - /// The alpha component of the color. - public Color(float red, float green, float blue, float alpha) - { - Red = ToByte(red); - Green = ToByte(green); - Blue = ToByte(blue); - Alpha = ToByte(alpha); - } - - /// - /// Initializes a new instance of the struct. Alpha is set to 255. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color(float red, float green, float blue) - { - Red = ToByte(red); - Green = ToByte(green); - Blue = ToByte(blue); - Alpha = 255; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red, green, blue, and alpha components of the color. - public Color(Vector4 value) - { - Red = ToByte(value.X); - Green = ToByte(value.Y); - Blue = ToByte(value.Z); - Alpha = ToByte(value.W); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red, green, and blue components of the color. - /// The alpha component of the color. - public Color(Vector3 value, float alpha) - { - Red = ToByte(value.X); - Green = ToByte(value.Y); - Blue = ToByte(value.Z); - Alpha = ToByte(alpha); - } - - /// - /// Initializes a new instance of the struct. Alpha is set to 255. - /// - /// The red, green, and blue components of the color. - public Color(Vector3 value) - { - Red = ToByte(value.X); - Green = ToByte(value.Y); - Blue = ToByte(value.Z); - Alpha = 255; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all four color components in RGBA order. - public Color(uint rgba) - { - Alpha = (byte)((rgba >> 24) & 255); - Blue = (byte)((rgba >> 16) & 255); - Green = (byte)((rgba >> 8) & 255); - Red = (byte)(rgba & 255); - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all four color components in RGBA order. - public Color(int rgba) - { - Alpha = (byte)((rgba >> 24) & 255); - Blue = (byte)((rgba >> 16) & 255); - Green = (byte)((rgba >> 8) & 255); - Red = (byte)(rgba & 255); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the red, green, and blue, alpha components of the color. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Color(float[] values) - { - if (values == null) - throw new ArgumentNullException(nameof(values)); - if (values.Length != 4) - throw new ArgumentOutOfRangeException(nameof(values), "There must be four and only four input values for Color."); - - Red = ToByte(values[0]); - Green = ToByte(values[1]); - Blue = ToByte(values[2]); - Alpha = ToByte(values[3]); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the red, green, blue, or alpha components of the color. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Color(byte[] values) - { - if (values == null) - throw new ArgumentNullException(nameof(values)); - if (values.Length != 4) - throw new ArgumentOutOfRangeException(nameof(values), "There must be four and only four input values for Color."); - - Red = values[0]; - Green = values[1]; - Blue = values[2]; - Alpha = values[3]; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the red, green, blue, or alpha component, depending on the index. - /// The index of the component to access. Use 0 for the red(R) component, 1 for the green(G) component, 2 for the blue(B) component, and 3 for the alpha(A) component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public byte this[int index] - { - get - { - switch (index) - { - case 0: return Red; - case 1: return Green; - case 2: return Blue; - case 3: return Alpha; - } - - throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color run from 0 to 3, inclusive."); - } - - set - { - switch (index) - { - case 0: Red = value; break; - case 1: Green = value; break; - case 2: Blue = value; break; - case 3: Alpha = value; break; - default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color run from 0 to 3, inclusive."); - } - } - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToBgra() - { - int value = Blue; - value |= Green << 8; - value |= Red << 16; - value |= Alpha << 24; - - return value; - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToRgba() - { - int value = Red; - value |= Green << 8; - value |= Blue << 16; - value |= Alpha << 24; - - return value; - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToArgb() - { - int value = Alpha; - value |= Red << 8; - value |= Green << 16; - value |= Blue << 24; - - return value; - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToAbgr() - { - int value = Alpha; - value |= Blue << 8; - value |= Green << 16; - value |= Red << 24; - - return value; - } - - /// - /// Converts the color into a three component vector. - /// - /// A three component vector containing the red, green, and blue components of the color. - public Vector3 ToVector3() - { - return new Vector3(Red / 255.0f, Green / 255.0f, Blue / 255.0f); - } - - /// - /// Converts the color into a three component color. - /// - /// A three component color containing the red, green, and blue components of the color. - public Color3 ToColor3() - { - return new Color3(Red / 255.0f, Green / 255.0f, Blue / 255.0f); - } - - /// - /// Converts the color into a four component vector. - /// - /// A four component vector containing all four color components. - public Vector4 ToVector4() - { - return new Vector4(Red / 255.0f, Green / 255.0f, Blue / 255.0f, Alpha / 255.0f); - } - - /// - /// Creates an array containing the elements of the color. - /// - /// A four-element array containing the components of the color in RGBA order. - public byte[] ToArray() - { - return new[] { Red, Green, Blue, Alpha }; - } - - /// - /// Gets the brightness. - /// - /// The Hue-Saturation-Brightness (HSB) saturation for this - public float GetBrightness() - { - float r = Red / 255.0f; - float g = Green / 255.0f; - float b = Blue / 255.0f; - - float max, min; - - max = r; - min = r; - - if (g > max) max = g; - if (b > max) max = b; - - if (g < min) min = g; - if (b < min) min = b; - - return (max + min) / 2; - } - - /// - /// Gets the hue. - /// - /// The Hue-Saturation-Brightness (HSB) saturation for this - public float GetHue() - { - if (Red == Green && Green == Blue) - return 0; // 0 makes as good an UNDEFINED value as any - - float r = Red / 255.0f; - float g = Green / 255.0f; - float b = Blue / 255.0f; - - float max, min; - float delta; - float hue = 0.0f; - - max = r; - min = r; - - if (g > max) max = g; - if (b > max) max = b; - - if (g < min) min = g; - if (b < min) min = b; - - delta = max - min; - - if (r == max) - { - hue = (g - b) / delta; - } - else if (g == max) - { - hue = 2 + (b - r) / delta; - } - else if (b == max) - { - hue = 4 + (r - g) / delta; - } - hue *= 60; - - if (hue < 0.0f) - { - hue += 360.0f; - } - return hue; - } - - /// - /// Gets the saturation. - /// - /// The Hue-Saturation-Brightness (HSB) saturation for this - public float GetSaturation() - { - float r = Red / 255.0f; - float g = Green / 255.0f; - float b = Blue / 255.0f; - - float max, min; - float l, s = 0; - - max = r; - min = r; - - if (g > max) max = g; - if (b > max) max = b; - - if (g < min) min = g; - if (b < min) min = b; - - // if max == min, then there is no color and - // the saturation is zero. - if (max != min) - { - l = (max + min) / 2; - - if (l <= .5) - { - s = (max - min) / (max + min); - } - else - { - s = (max - min) / (2 - max - min); - } - } - return s; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// When the method completes, completes the sum of the two colors. - public static void Add(ref Color left, ref Color right, out Color result) - { - result.Alpha = (byte)(left.Alpha + right.Alpha); - result.Red = (byte)(left.Red + right.Red); - result.Green = (byte)(left.Green + right.Green); - result.Blue = (byte)(left.Blue + right.Blue); - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color Add(Color left, Color right) - { - return new Color((byte)(left.Red + right.Red), (byte)(left.Green + right.Green), (byte)(left.Blue + right.Blue), (byte)(left.Alpha + right.Alpha)); - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// WHen the method completes, contains the difference of the two colors. - public static void Subtract(ref Color left, ref Color right, out Color result) - { - result.Alpha = (byte)(left.Alpha - right.Alpha); - result.Red = (byte)(left.Red - right.Red); - result.Green = (byte)(left.Green - right.Green); - result.Blue = (byte)(left.Blue - right.Blue); - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract - /// The difference of the two colors. - public static Color Subtract(Color left, Color right) - { - return new Color((byte)(left.Red - right.Red), (byte)(left.Green - right.Green), (byte)(left.Blue - right.Blue), (byte)(left.Alpha - right.Alpha)); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// When the method completes, contains the modulated color. - public static void Modulate(ref Color left, ref Color right, out Color result) - { - result.Alpha = (byte)(left.Alpha * right.Alpha / 255); - result.Red = (byte)(left.Red * right.Red / 255); - result.Green = (byte)(left.Green * right.Green / 255); - result.Blue = (byte)(left.Blue * right.Blue / 255); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color Modulate(Color left, Color right) - { - return new Color((byte)(left.Red * right.Red / 255), (byte)(left.Green * right.Green / 255), (byte)(left.Blue * right.Blue / 255), (byte)(left.Alpha * right.Alpha / 255)); - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled color. - public static void Scale(ref Color value, float scale, out Color result) - { - result.Alpha = (byte)(value.Alpha * scale); - result.Red = (byte)(value.Red * scale); - result.Green = (byte)(value.Green * scale); - result.Blue = (byte)(value.Blue * scale); - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// The scaled color. - public static Color Scale(Color value, float scale) - { - return new Color((byte)(value.Red * scale), (byte)(value.Green * scale), (byte)(value.Blue * scale), (byte)(value.Alpha * scale)); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// When the method completes, contains the negated color. - public static void Negate(ref Color value, out Color result) - { - result.Alpha = (byte)(255 - value.Alpha); - result.Red = (byte)(255 - value.Red); - result.Green = (byte)(255 - value.Green); - result.Blue = (byte)(255 - value.Blue); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// The negated color. - public static Color Negate(Color value) - { - return new Color((byte)(255 - value.Red), (byte)(255 - value.Green), (byte)(255 - value.Blue), (byte)(255 - value.Alpha)); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Color value, ref Color min, ref Color max, out Color result) - { - byte alpha = value.Alpha; - alpha = (alpha > max.Alpha) ? max.Alpha : alpha; - alpha = (alpha < min.Alpha) ? min.Alpha : alpha; - - byte red = value.Red; - red = (red > max.Red) ? max.Red : red; - red = (red < min.Red) ? min.Red : red; - - byte green = value.Green; - green = (green > max.Green) ? max.Green : green; - green = (green < min.Green) ? min.Green : green; - - byte blue = value.Blue; - blue = (blue > max.Blue) ? max.Blue : blue; - blue = (blue < min.Blue) ? min.Blue : blue; - - result = new Color(red, green, blue, alpha); - } - - /// - /// Converts the color from a packed BGRA integer. - /// - /// A packed integer containing all four color components in BGRA order - /// A color. - public static Color FromBgra(int color) - { - return new Color((byte)((color >> 16) & 255), (byte)((color >> 8) & 255), (byte)(color & 255), (byte)((color >> 24) & 255)); - } - - /// - /// Converts the color from a packed BGRA integer. - /// - /// A packed integer containing all four color components in BGRA order - /// A color. - public static Color FromBgra(uint color) - { - return FromBgra(unchecked((int)color)); - } - - /// - /// Converts the color from a packed ABGR integer. - /// - /// A packed integer containing all four color components in ABGR order - /// A color. - public static Color FromAbgr(int color) - { - return new Color((byte)(color >> 24), (byte)(color >> 16), (byte)(color >> 8), (byte)color); - } - - /// - /// Converts the color from a packed ABGR integer. - /// - /// A packed integer containing all four color components in ABGR order - /// A color. - public static Color FromAbgr(uint color) - { - return FromAbgr(unchecked((int)color)); - } - - /// - /// Converts the color from a packed RGBA integer. - /// - /// A packed integer containing all four color components in RGBA order - /// A color. - public static Color FromRgba(int color) - { - return new Color(color); - } - - /// - /// Converts the color from a packed RGBA integer. - /// - /// A packed integer containing all four color components in RGBA order - /// A color. - public static Color FromRgba(uint color) - { - return new Color(color); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Color Clamp(Color value, Color min, Color max) - { - Color result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two colors. - /// - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Color start, ref Color end, float amount, out Color result) - { - result.Red = MathUtil.Lerp(start.Red, end.Red, amount); - result.Green = MathUtil.Lerp(start.Green, end.Green, amount); - result.Blue = MathUtil.Lerp(start.Blue, end.Blue, amount); - result.Alpha = MathUtil.Lerp(start.Alpha, end.Alpha, amount); - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two colors. - /// - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Color Lerp(Color start, Color end, float amount) - { - Color result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two colors. - public static void SmoothStep(ref Color start, ref Color end, float amount, out Color result) - { - amount = MathUtil.SmoothStep(amount); - Lerp(ref start, ref end, amount, out result); - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two colors. - public static Color SmoothStep(Color start, Color end, float amount) - { - Color result; - SmoothStep(ref start, ref end, amount, out result); - return result; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the largest components of the source colors. - public static void Max(ref Color left, ref Color right, out Color result) - { - result.Alpha = (left.Alpha > right.Alpha) ? left.Alpha : right.Alpha; - result.Red = (left.Red > right.Red) ? left.Red : right.Red; - result.Green = (left.Green > right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue > right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the largest components of the specified colorss. - /// - /// The first source color. - /// The second source color. - /// A color containing the largest components of the source colors. - public static Color Max(Color left, Color right) - { - Color result; - Max(ref left, ref right, out result); - return result; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the smallest components of the source colors. - public static void Min(ref Color left, ref Color right, out Color result) - { - result.Alpha = (left.Alpha < right.Alpha) ? left.Alpha : right.Alpha; - result.Red = (left.Red < right.Red) ? left.Red : right.Red; - result.Green = (left.Green < right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue < right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// A color containing the smallest components of the source colors. - public static Color Min(Color left, Color right) - { - Color result; - Min(ref left, ref right, out result); - return result; - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// When the method completes, contains the adjusted color. - public static void AdjustContrast(ref Color value, float contrast, out Color result) - { - result.Alpha = value.Alpha; - result.Red = ToByte(0.5f + contrast * (value.Red / 255.0f - 0.5f)); - result.Green = ToByte(0.5f + contrast * (value.Green / 255.0f - 0.5f)); - result.Blue = ToByte(0.5f + contrast * (value.Blue / 255.0f - 0.5f)); - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// The adjusted color. - public static Color AdjustContrast(Color value, float contrast) - { - return new Color( - ToByte(0.5f + contrast * (value.Red / 255.0f - 0.5f)), - ToByte(0.5f + contrast * (value.Green / 255.0f - 0.5f)), - ToByte(0.5f + contrast * (value.Blue / 255.0f - 0.5f)), - value.Alpha); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// When the method completes, contains the adjusted color. - public static void AdjustSaturation(ref Color value, float saturation, out Color result) - { - float grey = value.Red / 255.0f * 0.2125f + value.Green / 255.0f * 0.7154f + value.Blue / 255.0f * 0.0721f; - - result.Alpha = value.Alpha; - result.Red = ToByte(grey + saturation * (value.Red / 255.0f - grey)); - result.Green = ToByte(grey + saturation * (value.Green / 255.0f - grey)); - result.Blue = ToByte(grey + saturation * (value.Blue / 255.0f - grey)); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// The adjusted color. - public static Color AdjustSaturation(Color value, float saturation) - { - float grey = value.Red / 255.0f * 0.2125f + value.Green / 255.0f * 0.7154f + value.Blue / 255.0f * 0.0721f; - - return new Color( - ToByte(grey + saturation * (value.Red / 255.0f - grey)), - ToByte(grey + saturation * (value.Green / 255.0f - grey)), - ToByte(grey + saturation * (value.Blue / 255.0f - grey)), - value.Alpha); - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color operator +(Color left, Color right) - { - return new Color((byte)(left.Red + right.Red), (byte)(left.Green + right.Green), (byte)(left.Blue + right.Blue), (byte)(left.Alpha + right.Alpha)); - } - - /// - /// Assert a color (return it unchanged). - /// - /// The color to assert (unchanged). - /// The asserted (unchanged) color. - public static Color operator +(Color value) - { - return value; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// The difference of the two colors. - public static Color operator -(Color left, Color right) - { - return new Color((byte)(left.Red - right.Red), (byte)(left.Green - right.Green), (byte)(left.Blue - right.Blue), (byte)(left.Alpha - right.Alpha)); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// A negated color. - public static Color operator -(Color value) - { - return new Color(-value.Red, -value.Green, -value.Blue, -value.Alpha); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color operator *(float scale, Color value) - { - return new Color((byte)(value.Red * scale), (byte)(value.Green * scale), (byte)(value.Blue * scale), (byte)(value.Alpha * scale)); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color operator *(Color value, float scale) - { - return new Color((byte)(value.Red * scale), (byte)(value.Green * scale), (byte)(value.Blue * scale), (byte)(value.Alpha * scale)); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color operator *(Color left, Color right) - { - return new Color((byte)(left.Red * right.Red / 255.0f), (byte)(left.Green * right.Green / 255.0f), (byte)(left.Blue * right.Blue / 255.0f), (byte)(left.Alpha * right.Alpha / 255.0f)); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Color left, Color right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Color left, Color right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(Color value) - { - return value.ToColor3(); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(Color value) - { - return new Vector3(value.Red / 255.0f, value.Green / 255.0f, value.Blue / 255.0f); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector4(Color value) - { - return new Vector4(value.Red / 255.0f, value.Green / 255.0f, value.Blue / 255.0f, value.Alpha / 255.0f); - } - - /// - /// Convert this instance to a - /// - /// The result of the conversion. - public Color4 ToColor4() - { - return new Color4(Red / 255.0f, Green / 255.0f, Blue / 255.0f, Alpha / 255.0f); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Color4(Color value) - { - return value.ToColor4(); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color(Vector3 value) - { - return new Color(value.X, value.Y, value.Z, 1.0f); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color(Color3 value) - { - return new Color(value.Red, value.Green, value.Blue, 1.0f); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color(Vector4 value) - { - return new Color(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color(Color4 value) - { - return new Color(value.Red, value.Green, value.Blue, value.Alpha); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// - /// The result of the conversion. - /// - public static explicit operator int(Color value) - { - return value.ToRgba(); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// - /// The result of the conversion. - /// - public static explicit operator Color(int value) - { - return new Color(value); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return ColorExtensions.RgbaToString(ToRgba()); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Alpha.GetHashCode() + Red.GetHashCode() + Green.GetHashCode() + Blue.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Color other) - { - return Red == other.Red && Green == other.Green && Blue == other.Blue && Alpha == other.Alpha; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object value) - { - if (value == null) - return false; - - if (!ReferenceEquals(value.GetType(), typeof(Color))) - return false; - - return Equals((Color)value); - } - - private static byte ToByte(float component) - { - var value = (int)(component * 255.0f); - return (byte)(value < 0 ? 0 : value > 255 ? 255 : value); - } - - public string ToString(string format, IFormatProvider formatProvider) - { - throw new NotImplementedException(); - } -} diff --git a/source/OrkEngine3D.Mathematics/Color3.cs b/source/OrkEngine3D.Mathematics/Color3.cs deleted file mode 100644 index 110eafa..0000000 --- a/source/OrkEngine3D.Mathematics/Color3.cs +++ /dev/null @@ -1,935 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a color in the form of rgb. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct Color3 : IEquatable, IFormattable -{ - /// - /// Empty Color3 - /// - public static readonly Color3 Empty; - - /// - /// The red component of the color. - /// - public float Red; - - /// - /// The green component of the color. - /// - public float Green; - - /// - /// The blue component of the color. - /// - public float Blue; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Color3(float value) - { - Red = Green = Blue = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color3(float red, float green, float blue) - { - Red = red; - Green = green; - Blue = blue; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red, green, and blue components of the color. - public Color3(Vector3 value) - { - Red = value.X; - Green = value.Y; - Blue = value.Z; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all three color components. - /// The alpha component is ignored. - public Color3(int rgb) - { - Red = ((rgb >> 16) & 255) / 255.0f; - Green = ((rgb >> 8) & 255) / 255.0f; - Blue = (rgb & 255) / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the red, green, and blue components of the color. This must be an array with three elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Color3(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 3) - throw new ArgumentOutOfRangeException("values", "There must be three and only three input values for Color3."); - - Red = values[0]; - Green = values[1]; - Blue = values[2]; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the red, green, or blue component, depending on the index. - /// The index of the component to access. Use 0 for the red component, 1 for the green component, and 2 for the blue component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 2]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return Red; - case 1: return Green; - case 2: return Blue; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Color3 run from 0 to 2, inclusive."); - } - - set - { - switch (index) - { - case 0: Red = value; break; - case 1: Green = value; break; - case 2: Blue = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Color3 run from 0 to 2, inclusive."); - } - } - } - - /// - /// Negates a color. - /// - public void Negate() - { - this.Red = -Red; - this.Green = -Green; - this.Blue = -Blue; - } - - /// - /// Scales a color. - /// - /// The amount by which to scale. - public void Scale(float scalar) - { - this.Red *= scalar; - this.Green *= scalar; - this.Blue *= scalar; - } - - /// - /// Inverts the color (takes the complement of the color). - /// - public void Invert() - { - this.Red = 1.0f - Red; - this.Green = 1.0f - Green; - this.Blue = 1.0f - Blue; - } - - /// - /// Adjusts the contrast of a color. - /// - /// The amount by which to adjust the contrast. - public void AdjustContrast(float contrast) - { - this.Red = 0.5f + contrast * (Red - 0.5f); - this.Green = 0.5f + contrast * (Green - 0.5f); - this.Blue = 0.5f + contrast * (Blue - 0.5f); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The amount by which to adjust the saturation. - public void AdjustSaturation(float saturation) - { - float grey = Red * 0.2125f + Green * 0.7154f + Blue * 0.0721f; - - this.Red = grey + saturation * (Red - grey); - this.Green = grey + saturation * (Green - grey); - this.Blue = grey + saturation * (Blue - grey); - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all three color components. The alpha channel is set to 255. - public int ToRgb() - { - uint a = 255; - uint r = ((uint)(Red * 255.0f) & 0xFF); - uint g = ((uint)(Green * 255.0f) & 0xFF); - uint b = ((uint)(Blue * 255.0f) & 0xFF); - - uint value = b; - value |= g << 8; - value |= r << 16; - value |= a << 24; - - return (int)value; - } - - /// - /// Converts the color into a three component vector. - /// - /// A three component vector containing the red, green, and blue components of the color. - public Vector3 ToVector3() - { - return new Vector3(Red, Green, Blue); - } - - /// - /// Creates an array containing the elements of the color. - /// - /// A three-element array containing the components of the color. - public float[] ToArray() - { - return new float[] { Red, Green, Blue }; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// When the method completes, completes the sum of the two colors. - public static void Add(ref Color3 left, ref Color3 right, out Color3 result) - { - result.Red = left.Red + right.Red; - result.Green = left.Green + right.Green; - result.Blue = left.Blue + right.Blue; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color3 Add(Color3 left, Color3 right) - { - return new Color3(left.Red + right.Red, left.Green + right.Green, left.Blue + right.Blue); - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// WHen the method completes, contains the difference of the two colors. - public static void Subtract(ref Color3 left, ref Color3 right, out Color3 result) - { - result.Red = left.Red - right.Red; - result.Green = left.Green - right.Green; - result.Blue = left.Blue - right.Blue; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract - /// The difference of the two colors. - public static Color3 Subtract(Color3 left, Color3 right) - { - return new Color3(left.Red - right.Red, left.Green - right.Green, left.Blue - right.Blue); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// When the method completes, contains the modulated color. - public static void Modulate(ref Color3 left, ref Color3 right, out Color3 result) - { - result.Red = left.Red * right.Red; - result.Green = left.Green * right.Green; - result.Blue = left.Blue * right.Blue; - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color3 Modulate(Color3 left, Color3 right) - { - return new Color3(left.Red * right.Red, left.Green * right.Green, left.Blue * right.Blue); - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled color. - public static void Scale(ref Color3 value, float Scalar, out Color3 result) - { - result.Red = value.Red * Scalar; - result.Green = value.Green * Scalar; - result.Blue = value.Blue * Scalar; - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// The scaled color. - public static Color3 Scale(Color3 value, float scalar) - { - return new Color3(value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// When the method completes, contains the negated color. - public static void Negate(ref Color3 value, out Color3 result) - { - result.Red = -value.Red; - result.Green = -value.Green; - result.Blue = -value.Blue; - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// The negated color. - public static Color3 Negate(Color3 value) - { - return new Color3(-value.Red, -value.Green, -value.Blue); - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// When the method completes, contains the inverted color. - public static void Invert(ref Color3 value, out Color3 result) - { - result.Red = 1.0f - value.Red; - result.Green = 1.0f - value.Green; - result.Blue = 1.0f - value.Blue; - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// The inverted color. - public static Color3 Invert(Color3 value) - { - return new Color3(-value.Red, -value.Green, -value.Blue); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Color3 value, ref Color3 min, ref Color3 max, out Color3 result) - { - float red = value.Red; - red = (red > max.Red) ? max.Red : red; - red = (red < min.Red) ? min.Red : red; - - float green = value.Green; - green = (green > max.Green) ? max.Green : green; - green = (green < min.Green) ? min.Green : green; - - float blue = value.Blue; - blue = (blue > max.Blue) ? max.Blue : blue; - blue = (blue < min.Blue) ? min.Blue : blue; - - result = new Color3(red, green, blue); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Color3 Clamp(Color3 value, Color3 min, Color3 max) - { - Color3 result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two colors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Color3 start, ref Color3 end, float amount, out Color3 result) - { - result.Red = start.Red + amount * (end.Red - start.Red); - result.Green = start.Green + amount * (end.Green - start.Green); - result.Blue = start.Blue + amount * (end.Blue - start.Blue); - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two colors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Color3 Lerp(Color3 start, Color3 end, float amount) - { - return new Color3( - start.Red + amount * (end.Red - start.Red), - start.Green + amount * (end.Green - start.Green), - start.Blue + amount * (end.Blue - start.Blue)); - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two colors. - public static void SmoothStep(ref Color3 start, ref Color3 end, float amount, out Color3 result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.Red = start.Red + ((end.Red - start.Red) * amount); - result.Green = start.Green + ((end.Green - start.Green) * amount); - result.Blue = start.Blue + ((end.Blue - start.Blue) * amount); - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two colors. - public static Color3 SmoothStep(Color3 start, Color3 end, float amount) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - return new Color3( - start.Red + ((end.Red - start.Red) * amount), - start.Green + ((end.Green - start.Green) * amount), - start.Blue + ((end.Blue - start.Blue) * amount)); - } - - /// - /// Returns a color containing the smallest components of the specified colorss. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the largest components of the source colorss. - public static void Max(ref Color3 left, ref Color3 right, out Color3 result) - { - result.Red = (left.Red > right.Red) ? left.Red : right.Red; - result.Green = (left.Green > right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue > right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the largest components of the specified colorss. - /// - /// The first source color. - /// The second source color. - /// A color containing the largest components of the source colors. - public static Color3 Max(Color3 left, Color3 right) - { - Color3 result; - Max(ref left, ref right, out result); - return result; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the smallest components of the source colors. - public static void Min(ref Color3 left, ref Color3 right, out Color3 result) - { - result.Red = (left.Red < right.Red) ? left.Red : right.Red; - result.Green = (left.Green < right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue < right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// A color containing the smallest components of the source colors. - public static Color3 Min(Color3 left, Color3 right) - { - Color3 result; - Min(ref left, ref right, out result); - return result; - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// When the method completes, contains the adjusted color. - public static void AdjustContrast(ref Color3 value, float contrast, out Color3 result) - { - result.Red = 0.5f + contrast * (value.Red - 0.5f); - result.Green = 0.5f + contrast * (value.Green - 0.5f); - result.Blue = 0.5f + contrast * (value.Blue - 0.5f); - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// The adjusted color. - public static Color3 AdjustContrast(Color3 value, float contrast) - { - return new Color3( - 0.5f + contrast * (value.Red - 0.5f), - 0.5f + contrast * (value.Green - 0.5f), - 0.5f + contrast * (value.Blue - 0.5f)); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// When the method completes, contains the adjusted color. - public static void AdjustSaturation(ref Color3 value, float saturation, out Color3 result) - { - float grey = value.Red * 0.2125f + value.Green * 0.7154f + value.Blue * 0.0721f; - - result.Red = grey + saturation * (value.Red - grey); - result.Green = grey + saturation * (value.Green - grey); - result.Blue = grey + saturation * (value.Blue - grey); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// The adjusted color. - public static Color3 AdjustSaturation(Color3 value, float saturation) - { - float grey = value.Red * 0.2125f + value.Green * 0.7154f + value.Blue * 0.0721f; - - return new Color3( - grey + saturation * (value.Red - grey), - grey + saturation * (value.Green - grey), - grey + saturation * (value.Blue - grey)); - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// The inverted color. - public static Color3 operator ~(Color3 value) - { - return new Color3(1.0f - value.Red, 1.0f - value.Green, 1.0f - value.Blue); - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color3 operator +(Color3 left, Color3 right) - { - return new Color3(left.Red + right.Red, left.Green + right.Green, left.Blue + right.Blue); - } - - /// - /// Assert a color (return it unchanged). - /// - /// The color to assert (unchange). - /// The asserted (unchanged) color. - public static Color3 operator +(Color3 value) - { - return value; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// The difference of the two colors. - public static Color3 operator -(Color3 left, Color3 right) - { - return new Color3(left.Red - right.Red, left.Green - right.Green, left.Blue - right.Blue); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// A negated color. - public static Color3 operator -(Color3 value) - { - return new Color3(-value.Red, -value.Green, -value.Blue); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color3 operator *(float scalar, Color3 value) - { - return new Color3(value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color3 operator *(Color3 value, float scalar) - { - return new Color3(value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color3 operator *(Color3 left, Color3 right) - { - return new Color3(left.Red * right.Red, left.Green * right.Green, left.Blue * right.Blue); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Color3 left, Color3 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Color3 left, Color3 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(Color3 value) - { - return new Color4(1.0f, value.Red, value.Green, value.Blue); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(Color3 value) - { - return new Vector3(value.Red, value.Green, value.Blue); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(Vector3 value) - { - return new Color3(value.X, value.Y, value.Z); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(int value) - { - return new Color3(value); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Red:{1} Green:{2} Blue:{3}", Red, Green, Blue); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "Red:{1} Green:{2} Blue:{3}", Red.ToString(format, CultureInfo.CurrentCulture), - Green.ToString(format, CultureInfo.CurrentCulture), Blue.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Red:{1} Green:{2} Blue:{3}", Red, Green, Blue); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "Red:{0} Green:{1} Blue:{2}",Red.ToString(format, formatProvider), - Green.ToString(format, formatProvider), Blue.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Red.GetHashCode() + Green.GetHashCode() + Blue.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Color3 other) - { - return (Red == other.Red) && (Green == other.Green) && (Blue == other.Blue); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Color3)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Color3(Color3 value) - { - return new SlimDX.Color3(value.Red, value.Green, value.Blue); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Color3(SlimDX.Color3 value) - { - return new Color3(value.Red, value.Green, value.Blue); - } -#endif - -#if WPFInterop - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator System.Windows.Media.Color(Color3 value) - { - return new System.Windows.Media.Color() - { - A = 255, - R = (byte)(255f * value.Red), - G = (byte)(255f * value.Green), - B = (byte)(255f * value.Blue) - }; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(System.Windows.Media.Color value) - { - return new Color3() - { - Red = (float)value.R / 255f, - Green = (float)value.G / 255f, - Blue = (float)value.B / 255f - }; - } -#endif - -#if WinFormsInterop - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator System.Drawing.Color(Color3 value) - { - return System.Drawing.Color.FromArgb( - (byte)(255f * value.Red), - (byte)(255f * value.Green), - (byte)(255f * value.Blue)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(System.Drawing.Color value) - { - return new Color3() - { - Red = (float)value.R / 255f, - Green = (float)value.G / 255f, - Blue = (float)value.B / 255f - }; - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Color4.cs b/source/OrkEngine3D.Mathematics/Color4.cs deleted file mode 100644 index 9ff772a..0000000 --- a/source/OrkEngine3D.Mathematics/Color4.cs +++ /dev/null @@ -1,1071 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a color in the form of argb. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct Color4 : IEquatable, IFormattable -{ - /// - /// The red component of the color. - /// - public float Red; - - /// - /// The green component of the color. - /// - public float Green; - - /// - /// The blue component of the color. - /// - public float Blue; - - /// - /// The alpha component of the color. - /// - public float Alpha; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Color4(float value) - { - Alpha = Red = Green = Blue = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color4(float red, float green, float blue) - { - Alpha = 1.0f; - Red = red; - Green = green; - Blue = blue; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The alpha component of the color. - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color4(float alpha, float red, float green, float blue) - { - Alpha = alpha; - Red = red; - Green = green; - Blue = blue; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red, green, blue, and alpha components of the color. - public Color4(Vector4 value) - { - Red = value.X; - Green = value.Y; - Blue = value.Z; - Alpha = value.W; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red, green, and blue compoennts of the color. - /// The alpha component of the color. - public Color4(Vector3 value, float alpha) - { - Red = value.X; - Green = value.Y; - Blue = value.Z; - Alpha = alpha; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all four color components. - public Color4(int argb) - { - Alpha = ((argb >> 24) & 255) / 255.0f; - Red = ((argb >> 16) & 255) / 255.0f; - Green = ((argb >> 8) & 255) / 255.0f; - Blue = (argb & 255) / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color4(int red, int green, int blue) - { - Alpha = 1.0f; - Red = red / 255.0f; - Green = green / 255.0f; - Blue = blue / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The alpha component of the color. - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - public Color4(int alpha, int red, int green, int blue) - { - Alpha = alpha / 255.0f; - Red = red / 255.0f; - Green = green / 255.0f; - Blue = blue / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the alpha, red, green, and blue components of the color. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Color4(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 4) - throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Color4."); - - Alpha = values[0]; - Red = values[1]; - Green = values[2]; - Blue = values[3]; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the alpha, red, green, or blue component, depending on the index. - /// The index of the component to access. Use 0 for the alpha component, 1 for the red component, 2 for the green component, and 3 for the blue component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return Alpha; - case 1: return Red; - case 2: return Green; - case 3: return Blue; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Color4 run from 0 to 3, inclusive."); - } - - set - { - switch (index) - { - case 0: Alpha = value; break; - case 1: Red = value; break; - case 2: Green = value; break; - case 3: Blue = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Color4 run from 0 to 3, inclusive."); - } - } - } - - /// - /// Negates a color. - /// - public void Negate() - { - this.Alpha = -Alpha; - this.Red = -Red; - this.Green = -Green; - this.Blue = -Blue; - } - - /// - /// Scales a color. - /// - /// The amount by which to scale. - public void Scale(float scalar) - { - this.Alpha *= scalar; - this.Red *= scalar; - this.Green *= scalar; - this.Blue *= scalar; - } - - /// - /// Inverts the color (takes the complement of the color). - /// - public void Invert() - { - this.Alpha = 1.0f - Alpha; - this.Red = 1.0f - Red; - this.Green = 1.0f - Green; - this.Blue = 1.0f - Blue; - } - - /// - /// Adjusts the contrast of a color. - /// - /// The amount by which to adjust the contrast. - public void AdjustContrast(float contrast) - { - this.Red = 0.5f + contrast * (Red - 0.5f); - this.Green = 0.5f + contrast * (Green - 0.5f); - this.Blue = 0.5f + contrast * (Blue - 0.5f); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The amount by which to adjust the saturation. - public void AdjustSaturation(float saturation) - { - float grey = Red * 0.2125f + Green * 0.7154f + Blue * 0.0721f; - - this.Red = grey + saturation * (Red - grey); - this.Green = grey + saturation * (Green - grey); - this.Blue = grey + saturation * (Blue - grey); - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToArgb() - { - uint a = ((uint)(Alpha * 255.0f) & 0xFF); - uint r = ((uint)(Red * 255.0f) & 0xFF); - uint g = ((uint)(Green * 255.0f) & 0xFF); - uint b = ((uint)(Blue * 255.0f) & 0xFF); - - uint value = b; - value |= g << 8; - value |= r << 16; - value |= a << 24; - - return (int)value; - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public int ToRgba() - { - uint a = ((uint)(Alpha * 255.0f) & 0xFF); - uint r = ((uint)(Red * 255.0f) & 0xFF); - uint g = ((uint)(Green * 255.0f) & 0xFF); - uint b = ((uint)(Blue * 255.0f) & 0xFF); - - uint value = a; - value |= b << 8; - value |= g << 16; - value |= r << 24; - - return (int)value; - } - - /// - /// Converts the color into a three component vector. - /// - /// A three component vector containing the red, green, and blue components of the color. - public Vector3 ToVector3() - { - return new Vector3(Red, Green, Blue); - } - - /// - /// Converts the color into a four component vector. - /// - /// A four component vector containing all four color components. - public Vector4 ToVector4() - { - return new Vector4(Red, Green, Blue, Alpha); - } - - /// - /// Creates an array containing the elements of the color. - /// - /// A four-element array containing the components of the color in ARGB order. - public float[] ToArray() - { - return new float[] { Alpha, Red, Green, Blue }; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// When the method completes, completes the sum of the two colors. - public static void Add(ref Color4 left, ref Color4 right, out Color4 result) - { - result.Alpha = left.Alpha + right.Alpha; - result.Red = left.Red + right.Red; - result.Green = left.Green + right.Green; - result.Blue = left.Blue + right.Blue; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color4 Add(Color4 left, Color4 right) - { - return new Color4(left.Alpha + right.Alpha, left.Red + right.Red, left.Green + right.Green, left.Blue + right.Blue); - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// WHen the method completes, contains the difference of the two colors. - public static void Subtract(ref Color4 left, ref Color4 right, out Color4 result) - { - result.Alpha = left.Alpha - right.Alpha; - result.Red = left.Red - right.Red; - result.Green = left.Green - right.Green; - result.Blue = left.Blue - right.Blue; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract - /// The difference of the two colors. - public static Color4 Subtract(Color4 left, Color4 right) - { - return new Color4(left.Alpha - right.Alpha, left.Red - right.Red, left.Green - right.Green, left.Blue - right.Blue); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// When the method completes, contains the modulated color. - public static void Modulate(ref Color4 left, ref Color4 right, out Color4 result) - { - result.Alpha = left.Alpha * right.Alpha; - result.Red = left.Red * right.Red; - result.Green = left.Green * right.Green; - result.Blue = left.Blue * right.Blue; - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color4 Modulate(Color4 left, Color4 right) - { - return new Color4(left.Alpha * right.Alpha, left.Red * right.Red, left.Green * right.Green, left.Blue * right.Blue); - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled color. - public static void Scale(ref Color4 value, float scalar, out Color4 result) - { - result.Alpha = value.Alpha * scalar; - result.Red = value.Red * scalar; - result.Green = value.Green * scalar; - result.Blue = value.Blue * scalar; - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// The scaled color. - public static Color4 Scale(Color4 value, float scalar) - { - return new Color4(value.Alpha * scalar, value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// When the method completes, contains the negated color. - public static void Negate(ref Color4 value, out Color4 result) - { - result.Alpha = -value.Alpha; - result.Red = -value.Red; - result.Green = -value.Green; - result.Blue = -value.Blue; - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// The negated color. - public static Color4 Negate(Color4 value) - { - return new Color4(-value.Alpha, -value.Red, -value.Green, -value.Blue); - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// When the method completes, contains the inverted color. - public static void Invert(ref Color4 value, out Color4 result) - { - result.Alpha = 1.0f - value.Alpha; - result.Red = 1.0f - value.Red; - result.Green = 1.0f - value.Green; - result.Blue = 1.0f - value.Blue; - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// The inverted color. - public static Color4 Invert(Color4 value) - { - return new Color4(-value.Alpha, -value.Red, -value.Green, -value.Blue); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Color4 value, ref Color4 min, ref Color4 max, out Color4 result) - { - float alpha = value.Alpha; - alpha = (alpha > max.Alpha) ? max.Alpha : alpha; - alpha = (alpha < min.Alpha) ? min.Alpha : alpha; - - float red = value.Red; - red = (red > max.Red) ? max.Red : red; - red = (red < min.Red) ? min.Red : red; - - float green = value.Green; - green = (green > max.Green) ? max.Green : green; - green = (green < min.Green) ? min.Green : green; - - float blue = value.Blue; - blue = (blue > max.Blue) ? max.Blue : blue; - blue = (blue < min.Blue) ? min.Blue : blue; - - result = new Color4(alpha, red, green, blue); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Color4 Clamp(Color4 value, Color4 min, Color4 max) - { - Color4 result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two colors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Color4 start, ref Color4 end, float amount, out Color4 result) - { - result.Alpha = start.Alpha + amount * (end.Alpha - start.Alpha); - result.Red = start.Red + amount * (end.Red - start.Red); - result.Green = start.Green + amount * (end.Green - start.Green); - result.Blue = start.Blue + amount * (end.Blue - start.Blue); - } - - /// - /// Performs a linear interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two colors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Color4 Lerp(Color4 start, Color4 end, float amount) - { - return new Color4( - start.Alpha + amount * (end.Alpha - start.Alpha), - start.Red + amount * (end.Red - start.Red), - start.Green + amount * (end.Green - start.Green), - start.Blue + amount * (end.Blue - start.Blue)); - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two colors. - public static void SmoothStep(ref Color4 start, ref Color4 end, float amount, out Color4 result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.Alpha = start.Alpha + ((end.Alpha - start.Alpha) * amount); - result.Red = start.Red + ((end.Red - start.Red) * amount); - result.Green = start.Green + ((end.Green - start.Green) * amount); - result.Blue = start.Blue + ((end.Blue - start.Blue) * amount); - } - - /// - /// Performs a cubic interpolation between two colors. - /// - /// Start color. - /// End color. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two colors. - public static Color4 SmoothStep(Color4 start, Color4 end, float amount) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - return new Color4( - start.Alpha + ((end.Alpha - start.Alpha) * amount), - start.Red + ((end.Red - start.Red) * amount), - start.Green + ((end.Green - start.Green) * amount), - start.Blue + ((end.Blue - start.Blue) * amount)); - } - - /// - /// Returns a color containing the smallest components of the specified colorss. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the largest components of the source colorss. - public static void Max(ref Color4 left, ref Color4 right, out Color4 result) - { - result.Alpha = (left.Alpha > right.Alpha) ? left.Alpha : right.Alpha; - result.Red = (left.Red > right.Red) ? left.Red : right.Red; - result.Green = (left.Green > right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue > right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the largest components of the specified colorss. - /// - /// The first source color. - /// The second source color. - /// A color containing the largest components of the source colors. - public static Color4 Max(Color4 left, Color4 right) - { - Color4 result; - Max(ref left, ref right, out result); - return result; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// When the method completes, contains an new color composed of the smallest components of the source colors. - public static void Min(ref Color4 left, ref Color4 right, out Color4 result) - { - result.Alpha = (left.Alpha < right.Alpha) ? left.Alpha : right.Alpha; - result.Red = (left.Red < right.Red) ? left.Red : right.Red; - result.Green = (left.Green < right.Green) ? left.Green : right.Green; - result.Blue = (left.Blue < right.Blue) ? left.Blue : right.Blue; - } - - /// - /// Returns a color containing the smallest components of the specified colors. - /// - /// The first source color. - /// The second source color. - /// A color containing the smallest components of the source colors. - public static Color4 Min(Color4 left, Color4 right) - { - Color4 result; - Min(ref left, ref right, out result); - return result; - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// When the method completes, contains the adjusted color. - public static void AdjustContrast(ref Color4 value, float contrast, out Color4 result) - { - result.Alpha = value.Alpha; - result.Red = 0.5f + contrast * (value.Red - 0.5f); - result.Green = 0.5f + contrast * (value.Green - 0.5f); - result.Blue = 0.5f + contrast * (value.Blue - 0.5f); - } - - /// - /// Adjusts the contrast of a color. - /// - /// The color whose contrast is to be adjusted. - /// The amount by which to adjust the contrast. - /// The adjusted color. - public static Color4 AdjustContrast(Color4 value, float contrast) - { - return new Color4( - value.Alpha, - 0.5f + contrast * (value.Red - 0.5f), - 0.5f + contrast * (value.Green - 0.5f), - 0.5f + contrast * (value.Blue - 0.5f)); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// When the method completes, contains the adjusted color. - public static void AdjustSaturation(ref Color4 value, float saturation, out Color4 result) - { - float grey = value.Red * 0.2125f + value.Green * 0.7154f + value.Blue * 0.0721f; - - result.Alpha = value.Alpha; - result.Red = grey + saturation * (value.Red - grey); - result.Green = grey + saturation * (value.Green - grey); - result.Blue = grey + saturation * (value.Blue - grey); - } - - /// - /// Adjusts the saturation of a color. - /// - /// The color whose saturation is to be adjusted. - /// The amount by which to adjust the saturation. - /// The adjusted color. - public static Color4 AdjustSaturation(Color4 value, float saturation) - { - float grey = value.Red * 0.2125f + value.Green * 0.7154f + value.Blue * 0.0721f; - - return new Color4( - value.Alpha, - grey + saturation * (value.Red - grey), - grey + saturation * (value.Green - grey), - grey + saturation * (value.Blue - grey)); - } - - /// - /// Inverts the color (takes the complement of the color). - /// - /// The color to invert. - /// The inverted color. - public static Color4 operator ~(Color4 value) - { - return new Color4(1.0f - value.Alpha, 1.0f - value.Red, 1.0f - value.Green, 1.0f - value.Blue); - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color4 operator +(Color4 left, Color4 right) - { - return new Color4(left.Alpha + right.Alpha, left.Red + right.Red, left.Green + right.Green, left.Blue + right.Blue); - } - - /// - /// Assert a color (return it unchanged). - /// - /// The color to assert (unchange). - /// The asserted (unchanged) color. - public static Color4 operator +(Color4 value) - { - return value; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// The difference of the two colors. - public static Color4 operator -(Color4 left, Color4 right) - { - return new Color4(left.Alpha - right.Alpha, left.Red - right.Red, left.Green - right.Green, left.Blue - right.Blue); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// A negated color. - public static Color4 operator -(Color4 value) - { - return new Color4(-value.Alpha, -value.Red, -value.Green, -value.Blue); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color4 operator *(float scalar, Color4 value) - { - return new Color4(value.Alpha * scalar, value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color4 operator *(Color4 value, float scalar) - { - return new Color4(value.Alpha * scalar, value.Red * scalar, value.Green * scalar, value.Blue * scalar); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color4 operator *(Color4 left, Color4 right) - { - return new Color4(left.Alpha * right.Alpha, left.Red * right.Red, left.Green * right.Green, left.Blue * right.Blue); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Color4 left, Color4 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Color4 left, Color4 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color3(Color4 value) - { - return new Color3(value.Red, value.Green, value.Blue); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(Color4 value) - { - return new Vector3(value.Red, value.Green, value.Blue); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector4(Color4 value) - { - return new Vector4(value.Red, value.Green, value.Blue, value.Alpha); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(Vector3 value) - { - return new Color4(value.X, value.Y, value.Z, 1.0f); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(Vector4 value) - { - return new Color4(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(int value) - { - return new Color4(value); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Alpha:{0} Red:{1} Green:{2} Blue:{3}", Alpha, Red, Green, Blue); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "Alpha:{0} Red:{1} Green:{2} Blue:{3}", Alpha.ToString(format, CultureInfo.CurrentCulture), - Red.ToString(format, CultureInfo.CurrentCulture), Green.ToString(format, CultureInfo.CurrentCulture), Blue.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Alpha:{0} Red:{1} Green:{2} Blue:{3}", Alpha, Red, Green, Blue); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "Alpha:{0} Red:{1} Green:{2} Blue:{3}", Alpha.ToString(format, formatProvider), - Red.ToString(format, formatProvider), Green.ToString(format, formatProvider), Blue.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Alpha.GetHashCode() + Red.GetHashCode() + Green.GetHashCode() + Blue.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Color4 other) - { - return (Alpha == other.Alpha) && (Red == other.Red) && (Green == other.Green) && (Blue == other.Blue); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Color4)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Color4(Color4 value) - { - return new SlimDX.Color4(value.Alpha, value.Red, value.Green, value.Blue); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Color4(SlimDX.Color4 value) - { - return new Color4(value.Alpha, value.Red, value.Green, value.Blue); - } -#endif - -#if WPFInterop - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator System.Windows.Media.Color(Color4 value) - { - return new System.Windows.Media.Color() - { - A = (byte)(255f * value.Alpha), - R = (byte)(255f * value.Red), - G = (byte)(255f * value.Green), - B = (byte)(255f * value.Blue) - }; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(System.Windows.Media.Color value) - { - return new Color4() - { - Alpha = (float)value.A / 255f, - Red = (float)value.R / 255f, - Green = (float)value.G / 255f, - Blue = (float)value.B / 255f - }; - } -#endif - -#if WinFormsInterop - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator System.Drawing.Color(Color4 value) - { - return System.Drawing.Color.FromArgb( - (byte)(255f * value.Alpha), - (byte)(255f * value.Red), - (byte)(255f * value.Green), - (byte)(255f * value.Blue)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Color4(System.Drawing.Color value) - { - return new Color4() - { - Alpha = (float)value.A / 255f, - Red = (float)value.R / 255f, - Green = (float)value.G / 255f, - Blue = (float)value.B / 255f - }; - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/ColorExtensions.cs b/source/OrkEngine3D.Mathematics/ColorExtensions.cs deleted file mode 100644 index 2dc6938..0000000 --- a/source/OrkEngine3D.Mathematics/ColorExtensions.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace OrkEngine3D.Mathematics; - -/// -/// A class containing extension methods for processing colors. -/// -public static class ColorExtensions -{ - /// - /// Indicates if the given string can be converted to an RGBA value using . - /// - /// The string to convert. - /// True if the string can be converted, false otherwise. - public static bool CanConvertStringToRgba(/*[CanBeNull]*/ string stringColor) - { - return stringColor?.StartsWith("#") ?? false; - } - - /// - /// Converts the given string to an RGBA value. - /// - /// The string to convert. - /// The converted RGBA value. - public static uint StringToRgba(/*[CanBeNull]*/ string stringColor) - { - var intValue = 0xFF000000; - if (stringColor != null) - { - if (stringColor.StartsWith("#")) - { - if (stringColor.Length == "#000".Length && uint.TryParse(stringColor.Substring(1, 3), NumberStyles.HexNumber, null, out intValue)) - { - intValue = ((intValue & 0x00F) << 16) - | ((intValue & 0x00F) << 20) - | ((intValue & 0x0F0) << 4) - | ((intValue & 0x0F0) << 8) - | ((intValue & 0xF00) >> 4) - | ((intValue & 0xF00) >> 8) - | (0xFF000000); - } - if (stringColor.Length == "#000000".Length && uint.TryParse(stringColor.Substring(1, 6), NumberStyles.HexNumber, null, out intValue)) - { - intValue = ((intValue & 0x000000FF) << 16) - | (intValue & 0x0000FF00) - | ((intValue & 0x00FF0000) >> 16) - | (0xFF000000); - } - if (stringColor.Length == "#00000000".Length && uint.TryParse(stringColor.Substring(1, 8), NumberStyles.HexNumber, null, out intValue)) - { - intValue = ((intValue & 0x000000FF) << 16) - | (intValue & 0x0000FF00) - | ((intValue & 0x00FF0000) >> 16) - | (intValue & 0xFF000000); - } - } - } - return intValue; - } - - /// - /// Converts the given RGB value to a string. - /// - /// The RGB value to convert. - /// The converted string. - //[System.Diagnostics.CodeAnalysis.NotNull] - public static string RgbToString(int value) - { - var r = (value & 0x000000FF); - var g = (value & 0x0000FF00) >> 8; - var b = (value & 0x00FF0000) >> 16; - return $"#{r:X2}{g:X2}{b:X2}"; - } - - /// - /// Converts the given RGBA value to a string. - /// - /// The RGBA value to convert. - /// The converted string. - //[NotNull] - public static string RgbaToString(int value) - { - var r = (value & 0x000000FF); - var g = (value & 0x0000FF00) >> 8; - var b = (value & 0x00FF0000) >> 16; - var a = (value & 0xFF000000) >> 24; - return $"#{a:X2}{r:X2}{g:X2}{b:X2}"; - } -} \ No newline at end of file diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/all-wcprops b/source/OrkEngine3D.Mathematics/Design/.svn/all-wcprops deleted file mode 100644 index cf8cec5..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/all-wcprops +++ /dev/null @@ -1,71 +0,0 @@ -K 25 -svn:wc:ra_dav:version-url -V 38 -/svn/!svn/ver/43/trunk/SlimMath/Design -END -Half2Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 56 -/svn/!svn/ver/43/trunk/SlimMath/Design/Half2Converter.cs -END -Half3Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 56 -/svn/!svn/ver/43/trunk/SlimMath/Design/Half3Converter.cs -END -Half4Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 56 -/svn/!svn/ver/43/trunk/SlimMath/Design/Half4Converter.cs -END -FieldPropertyDescriptor.cs -K 25 -svn:wc:ra_dav:version-url -V 65 -/svn/!svn/ver/43/trunk/SlimMath/Design/FieldPropertyDescriptor.cs -END -Vector2Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/!svn/ver/43/trunk/SlimMath/Design/Vector2Converter.cs -END -MatrixConverter.cs -K 25 -svn:wc:ra_dav:version-url -V 57 -/svn/!svn/ver/43/trunk/SlimMath/Design/MatrixConverter.cs -END -Vector3Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/!svn/ver/43/trunk/SlimMath/Design/Vector3Converter.cs -END -QuaternionConverter.cs -K 25 -svn:wc:ra_dav:version-url -V 61 -/svn/!svn/ver/43/trunk/SlimMath/Design/QuaternionConverter.cs -END -Vector4Converter.cs -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/!svn/ver/43/trunk/SlimMath/Design/Vector4Converter.cs -END -BaseConverter.cs -K 25 -svn:wc:ra_dav:version-url -V 55 -/svn/!svn/ver/43/trunk/SlimMath/Design/BaseConverter.cs -END -HalfConverter.cs -K 25 -svn:wc:ra_dav:version-url -V 55 -/svn/!svn/ver/43/trunk/SlimMath/Design/HalfConverter.cs -END diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/entries b/source/OrkEngine3D.Mathematics/Design/.svn/entries deleted file mode 100644 index 0569890..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/entries +++ /dev/null @@ -1,402 +0,0 @@ -10 - -dir -47 -http://slimmath.googlecode.com/svn/trunk/SlimMath/Design -http://slimmath.googlecode.com/svn - - - -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - -9684bafa-e604-11de-91d6-89caad0352f8 - -BaseConverter.cs -file - - - - -2016-03-19T02:58:40.968692Z -741469cbd17a86a15c5fe1f5bda7a9c7 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6997 - -HalfConverter.cs -file - - - - -2016-03-19T02:58:40.968692Z -5d8f1536360468e1d1a11bf4f4a3924a -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6837 - -Half2Converter.cs -file - - - - -2016-03-19T02:58:40.968692Z -d901cf059f5befe0e6a1f911e9bfcb10 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6161 - -Half3Converter.cs -file - - - - -2016-03-19T02:58:40.968692Z -4aacf31bedb80dedc724ecc06c4e3df0 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6255 - -Half4Converter.cs -file - - - - -2016-03-19T02:58:40.972692Z -cf92a0d6beabd783bc14d1b664f722c5 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6348 - -FieldPropertyDescriptor.cs -file - - - - -2016-03-19T02:58:40.972692Z -e0dd2859817090dd863849d2d7fa12fb -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -2905 - -Vector2Converter.cs -file - - - - -2016-03-19T02:58:40.968692Z -dc8b63787fc7c4b3cc528079118f469e -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6181 - -MatrixConverter.cs -file - - - - -2016-03-19T02:58:40.968692Z -4718ac84e1446ee934b73801386af1db -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -7997 - -Vector3Converter.cs -file - - - - -2016-03-19T02:58:40.968692Z -0c9fb949a8296d5c868f3c03f999e355 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6275 - -QuaternionConverter.cs -file - - - - -2016-03-19T02:58:40.968692Z -b8d34eed329ee57b383dbce4a598681b -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6410 - -Vector4Converter.cs -file - - - - -2016-03-19T02:58:40.968692Z -4ef2b4fbeeca7bd209fd4d374762b354 -2011-03-06T21:51:40.162858Z -43 -Jorgy343@gmail.com - - - - - - - - - - - - - - - - - - - - - -6368 - diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/BaseConverter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/BaseConverter.cs.svn-base deleted file mode 100644 index 4b362f3..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/BaseConverter.cs.svn-base +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Provides a base class for mathematical type converters. - /// - public abstract class BaseConverter : ExpandableObjectConverter - { - /// - /// Gets or sets the collection of exposed properties. - /// - /// The collection of exposed properties. - protected PropertyDescriptorCollection Properties - { - get; - set; - } - - internal static string ConvertFromValues(ITypeDescriptorContext context, CultureInfo culture, T[] values) - { - if (culture == null) - culture = CultureInfo.CurrentCulture; - - var converter = TypeDescriptor.GetConverter(typeof(T)); - var results = Array.ConvertAll(values, t => converter.ConvertToString(context, culture, t)); - - return string.Join(culture.TextInfo.ListSeparator + " ", results); - } - - internal static T[] ConvertToValues(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var str = value as string; - if (string.IsNullOrEmpty(str)) - return null; - - if (culture == null) - culture = CultureInfo.CurrentCulture; - - var converter = TypeDescriptor.GetConverter(typeof(T)); - var strings = str.Trim().Split(new[] { culture.TextInfo.ListSeparator }, StringSplitOptions.RemoveEmptyEntries); - - return Array.ConvertAll(strings, s => (T)converter.ConvertFromString(context, culture, s)); - } - - /// - /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. - /// - /// An that provides a format context. - /// A that represents the type you want to convert from. - /// - /// true if this converter can perform the conversion; otherwise, false. - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); - } - - /// - /// Returns whether this converter can convert the object to the specified type, using the specified context. - /// - /// An that provides a format context. - /// A that represents the type you want to convert to. - /// - /// true if this converter can perform the conversion; otherwise, false. - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string) || destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType); - } - - /// - /// Returns whether changing a value on this object requires a call to to create a new value, using the specified context. - /// - /// An that provides a format context. - /// - /// true if changing a property on this object requires a call to to create a new value; otherwise, false. - /// - public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) - { - return true; - } - - /// - /// Gets a value indicating whether this object supports properties using the specified context. - /// - /// An that provides a format context. - /// - /// true because should be called to find the properties of this object. This method never returns false. - /// - public override bool GetPropertiesSupported(ITypeDescriptorContext context) - { - return true; - } - - /// - /// Gets a collection of properties for the type of object specified by the value parameter. - /// - /// An that provides a format context. - /// An that specifies the type of object to get the properties for. - /// An array of type that will be used as a filter. - /// - /// A with the properties that are exposed for the component, or null if there are no properties. - /// - public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) - { - return Properties; - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/FieldPropertyDescriptor.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/FieldPropertyDescriptor.cs.svn-base deleted file mode 100644 index 78de67d..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/FieldPropertyDescriptor.cs.svn-base +++ /dev/null @@ -1,92 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.Reflection; - -namespace SlimMath.Design -{ - class FieldPropertyDescriptor : PropertyDescriptor - { - readonly FieldInfo fieldInfo; - - public override Type ComponentType - { - get { return fieldInfo.DeclaringType; } - } - - public override bool IsReadOnly - { - get { return false; } - } - - public override Type PropertyType - { - get { return fieldInfo.FieldType; } - } - - public FieldPropertyDescriptor(FieldInfo fieldInfo) - : base(fieldInfo.Name, (Attribute[])fieldInfo.GetCustomAttributes(true)) - { - this.fieldInfo = fieldInfo; - } - - public override bool CanResetValue(object component) - { - return false; - } - - public override object GetValue(object component) - { - return fieldInfo.GetValue(component); - } - - public override void ResetValue(object component) - { - } - - public override void SetValue(object component, object value) - { - fieldInfo.SetValue(component, value); - OnValueChanged(component, EventArgs.Empty); - } - - public override bool ShouldSerializeValue(object component) - { - return true; - } - - public override int GetHashCode() - { - return fieldInfo.GetHashCode(); - } - - public override bool Equals(object obj) - { - if (obj == null) - return false; - - return GetType() == obj.GetType() && ((FieldPropertyDescriptor)obj).fieldInfo.Equals(fieldInfo); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half2Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half2Converter.cs.svn-base deleted file mode 100644 index ce4cb45..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half2Converter.cs.svn-base +++ /dev/null @@ -1,122 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Half2Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Half2Converter() - { - var type = typeof(Half2); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half2) - { - var vector = (Half2)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half2).GetConstructor(Utilities.Array(typeof(float), 2)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half2(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half2((float)propertyValues["X"], (float)propertyValues["Y"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half3Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half3Converter.cs.svn-base deleted file mode 100644 index 652937a..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half3Converter.cs.svn-base +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Half3Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Half3Converter() - { - var type = typeof(Half3); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half3) - { - var vector = (Half3)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half3).GetConstructor(Utilities.Array(typeof(float), 3)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half3(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half3((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half4Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half4Converter.cs.svn-base deleted file mode 100644 index f396776..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Half4Converter.cs.svn-base +++ /dev/null @@ -1,124 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Half4Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Half4Converter() - { - var type = typeof(Half4); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half4) - { - var vector = (Half4)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half4).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half4(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half4((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/HalfConverter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/HalfConverter.cs.svn-base deleted file mode 100644 index 52637df..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/HalfConverter.cs.svn-base +++ /dev/null @@ -1,128 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Provides a type converter to convert objects to and from various - /// other representations. - /// - public class HalfConverter : ExpandableObjectConverter - { - /// - /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. - /// - /// A that provides a format context. - /// A System::Type that represents the type you want to convert from. - /// - /// true if this converter can perform the conversion; otherwise, false. - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType)); - } - - /// - /// Returns whether this converter can convert the object to the specified type, using the specified context. - /// - /// A that provides a format context. - /// A that represents the type you want to convert to. - /// - /// true if this converter can perform the conversion; otherwise, false. - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if ((destinationType != typeof(string)) && (destinationType != typeof(InstanceDescriptor))) - { - return base.CanConvertTo(context, destinationType); - } - return true; - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// A that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// An that represents the converted value. - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (culture == null) - { - culture = CultureInfo.CurrentCulture; - } - string @string = value as string; - if (@string == null) - { - return base.ConvertFrom(context, culture, value); - } - @string = @string.Trim(); - char[] separator = new char[] { culture.TextInfo.ListSeparator[0] }; - string[] stringArray = @string.Split(separator); - if (stringArray.Length != 1) - { - throw new ArgumentException("Invalid half format."); - } - float H = (float)TypeDescriptor.GetConverter(typeof(float)).ConvertFromString(context, culture, stringArray[0]); - Half type = new Half(H); - return type; - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// A that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// A that represents the type you want to convert to. - /// An that represents the converted value. - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - { - throw new ArgumentNullException("destinationType"); - } - if (culture == null) - { - culture = CultureInfo.CurrentCulture; - } - if ((destinationType == typeof(string)) && value is Half) - { - TypeConverter converter = TypeDescriptor.GetConverter(typeof(float)); - return string.Join(culture.TextInfo.ListSeparator + " ", new string[] { converter.ConvertToString(context, culture, (float)((Half)value)) }); - } - if ((destinationType == typeof(InstanceDescriptor)) && value is Half) - { - var info = typeof(Half).GetConstructor(new Type[] { typeof(float) }); - if (info != null) - { - return new InstanceDescriptor(info, new object[] { (float)((Half)value) }); - } - } - return base.ConvertTo(context, culture, value, destinationType); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/MatrixConverter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/MatrixConverter.cs.svn-base deleted file mode 100644 index 0fc4696..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/MatrixConverter.cs.svn-base +++ /dev/null @@ -1,160 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class MatrixConverter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public MatrixConverter() - { - Type type = typeof(Matrix); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("M11")), - new FieldPropertyDescriptor(type.GetField("M12")), - new FieldPropertyDescriptor(type.GetField("M13")), - new FieldPropertyDescriptor(type.GetField("M14")), - - new FieldPropertyDescriptor(type.GetField("M21")), - new FieldPropertyDescriptor(type.GetField("M22")), - new FieldPropertyDescriptor(type.GetField("M23")), - new FieldPropertyDescriptor(type.GetField("M24")), - - new FieldPropertyDescriptor(type.GetField("M31")), - new FieldPropertyDescriptor(type.GetField("M32")), - new FieldPropertyDescriptor(type.GetField("M33")), - new FieldPropertyDescriptor(type.GetField("M34")), - - new FieldPropertyDescriptor(type.GetField("M41")), - new FieldPropertyDescriptor(type.GetField("M42")), - new FieldPropertyDescriptor(type.GetField("M43")), - new FieldPropertyDescriptor(type.GetField("M44")), - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Matrix) - { - var matrix = (Matrix)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, matrix.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Matrix).GetConstructor(Utilities.Array(typeof(float), 16)); - if (constructor != null) - return new InstanceDescriptor(constructor, matrix.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - - return values != null ? new Matrix(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - var matrix = new Matrix - { - M11 = (float)propertyValues["M11"], - M12 = (float)propertyValues["M12"], - M13 = (float)propertyValues["M13"], - M14 = (float)propertyValues["M14"], - M21 = (float)propertyValues["M21"], - M22 = (float)propertyValues["M22"], - M23 = (float)propertyValues["M23"], - M24 = (float)propertyValues["M24"], - M31 = (float)propertyValues["M31"], - M32 = (float)propertyValues["M32"], - M33 = (float)propertyValues["M33"], - M34 = (float)propertyValues["M34"], - M41 = (float)propertyValues["M41"], - M42 = (float)propertyValues["M42"], - M43 = (float)propertyValues["M43"], - M44 = (float)propertyValues["M44"] - }; - - return matrix; - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/QuaternionConverter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/QuaternionConverter.cs.svn-base deleted file mode 100644 index 4ff77f4..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/QuaternionConverter.cs.svn-base +++ /dev/null @@ -1,124 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class QuaternionConverter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public QuaternionConverter() - { - var type = typeof(Quaternion); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Quaternion) - { - var quaternion = (Quaternion)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, quaternion.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Quaternion).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, quaternion.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Quaternion(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Quaternion((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector2Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector2Converter.cs.svn-base deleted file mode 100644 index 6e9aad3..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector2Converter.cs.svn-base +++ /dev/null @@ -1,122 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Vector2Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Vector2Converter() - { - var type = typeof(Vector2); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector2) - { - var vector = (Vector2)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector2).GetConstructor(Utilities.Array(typeof(float), 2)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector2(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector2((float)propertyValues["X"], (float)propertyValues["Y"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector3Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector3Converter.cs.svn-base deleted file mode 100644 index ea7b7dc..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector3Converter.cs.svn-base +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Vector3Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Vector3Converter() - { - var type = typeof(Vector3); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector3) - { - var vector = (Vector3)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector3).GetConstructor(Utilities.Array(typeof(float), 3)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector3(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector3((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector4Converter.cs.svn-base b/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector4Converter.cs.svn-base deleted file mode 100644 index 5f14b9f..0000000 --- a/source/OrkEngine3D.Mathematics/Design/.svn/text-base/Vector4Converter.cs.svn-base +++ /dev/null @@ -1,124 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace SlimMath.Design -{ - /// - /// Defines a type converter for . - /// - public class Vector4Converter : BaseConverter - { - /// - /// Initializes a new instance of the class. - /// - public Vector4Converter() - { - var type = typeof(Vector4); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector4) - { - var vector = (Vector4)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector4).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector4(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector4((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/BaseConverter.cs b/source/OrkEngine3D.Mathematics/Design/BaseConverter.cs deleted file mode 100644 index 25c9260..0000000 --- a/source/OrkEngine3D.Mathematics/Design/BaseConverter.cs +++ /dev/null @@ -1,134 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Provides a base class for mathematical type converters. -/// -public abstract class BaseConverter : ExpandableObjectConverter -{ - /// - /// Gets or sets the collection of exposed properties. - /// - /// The collection of exposed properties. - protected PropertyDescriptorCollection Properties - { - get; - set; - } - - internal static string ConvertFromValues(ITypeDescriptorContext context, CultureInfo culture, T[] values) - { - if (culture == null) - culture = CultureInfo.CurrentCulture; - - var converter = TypeDescriptor.GetConverter(typeof(T)); - var results = Array.ConvertAll(values, t => converter.ConvertToString(context, culture, t)); - - return string.Join(culture.TextInfo.ListSeparator + " ", results); - } - - internal static T[] ConvertToValues(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var str = value as string; - if (string.IsNullOrEmpty(str)) - return null; - - if (culture == null) - culture = CultureInfo.CurrentCulture; - - var converter = TypeDescriptor.GetConverter(typeof(T)); - var strings = str.Trim().Split(new[] { culture.TextInfo.ListSeparator }, StringSplitOptions.RemoveEmptyEntries); - - return Array.ConvertAll(strings, s => (T)converter.ConvertFromString(context, culture, s)); - } - - /// - /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. - /// - /// An that provides a format context. - /// A that represents the type you want to convert from. - /// - /// true if this converter can perform the conversion; otherwise, false. - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); - } - - /// - /// Returns whether this converter can convert the object to the specified type, using the specified context. - /// - /// An that provides a format context. - /// A that represents the type you want to convert to. - /// - /// true if this converter can perform the conversion; otherwise, false. - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string) || destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType); - } - - /// - /// Returns whether changing a value on this object requires a call to to create a new value, using the specified context. - /// - /// An that provides a format context. - /// - /// true if changing a property on this object requires a call to to create a new value; otherwise, false. - /// - public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) - { - return true; - } - - /// - /// Gets a value indicating whether this object supports properties using the specified context. - /// - /// An that provides a format context. - /// - /// true because should be called to find the properties of this object. This method never returns false. - /// - public override bool GetPropertiesSupported(ITypeDescriptorContext context) - { - return true; - } - - /// - /// Gets a collection of properties for the type of object specified by the value parameter. - /// - /// An that provides a format context. - /// An that specifies the type of object to get the properties for. - /// An array of type that will be used as a filter. - /// - /// A with the properties that are exposed for the component, or null if there are no properties. - /// - public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) - { - return Properties; - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/FieldPropertyDescriptor.cs b/source/OrkEngine3D.Mathematics/Design/FieldPropertyDescriptor.cs deleted file mode 100644 index 5a6a5d6..0000000 --- a/source/OrkEngine3D.Mathematics/Design/FieldPropertyDescriptor.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.Reflection; - -namespace OrkEngine3D.Mathematics.Design; - -class FieldPropertyDescriptor : PropertyDescriptor -{ - readonly FieldInfo fieldInfo; - - public override Type ComponentType - { - get { return fieldInfo.DeclaringType; } - } - - public override bool IsReadOnly - { - get { return false; } - } - - public override Type PropertyType - { - get { return fieldInfo.FieldType; } - } - - public FieldPropertyDescriptor(FieldInfo fieldInfo) - : base(fieldInfo.Name, (Attribute[])fieldInfo.GetCustomAttributes(true)) - { - this.fieldInfo = fieldInfo; - } - - public override bool CanResetValue(object component) - { - return false; - } - - public override object GetValue(object component) - { - return fieldInfo.GetValue(component); - } - - public override void ResetValue(object component) - { - } - - public override void SetValue(object component, object value) - { - fieldInfo.SetValue(component, value); - OnValueChanged(component, EventArgs.Empty); - } - - public override bool ShouldSerializeValue(object component) - { - return true; - } - - public override int GetHashCode() - { - return fieldInfo.GetHashCode(); - } - - public override bool Equals(object obj) - { - if (obj == null) - return false; - - return GetType() == obj.GetType() && ((FieldPropertyDescriptor)obj).fieldInfo.Equals(fieldInfo); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Half2Converter.cs b/source/OrkEngine3D.Mathematics/Design/Half2Converter.cs deleted file mode 100644 index e6f2c7d..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Half2Converter.cs +++ /dev/null @@ -1,121 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Half2Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Half2Converter() - { - var type = typeof(Half2); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half2) - { - var vector = (Half2)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half2).GetConstructor(Utilities.Array(typeof(float), 2)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half2(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half2((float)propertyValues["X"], (float)propertyValues["Y"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Half3Converter.cs b/source/OrkEngine3D.Mathematics/Design/Half3Converter.cs deleted file mode 100644 index d8f8115..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Half3Converter.cs +++ /dev/null @@ -1,122 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Half3Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Half3Converter() - { - var type = typeof(Half3); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half3) - { - var vector = (Half3)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half3).GetConstructor(Utilities.Array(typeof(float), 3)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half3(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half3((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Half4Converter.cs b/source/OrkEngine3D.Mathematics/Design/Half4Converter.cs deleted file mode 100644 index eb81bc6..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Half4Converter.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Half4Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Half4Converter() - { - var type = typeof(Half4); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Half4) - { - var vector = (Half4)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Half4).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Half4(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Half4((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/HalfConverter.cs b/source/OrkEngine3D.Mathematics/Design/HalfConverter.cs deleted file mode 100644 index b1515f4..0000000 --- a/source/OrkEngine3D.Mathematics/Design/HalfConverter.cs +++ /dev/null @@ -1,127 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Provides a type converter to convert objects to and from various -/// other representations. -/// -public class HalfConverter : ExpandableObjectConverter -{ - /// - /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. - /// - /// A that provides a format context. - /// A System::Type that represents the type you want to convert from. - /// - /// true if this converter can perform the conversion; otherwise, false. - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType)); - } - - /// - /// Returns whether this converter can convert the object to the specified type, using the specified context. - /// - /// A that provides a format context. - /// A that represents the type you want to convert to. - /// - /// true if this converter can perform the conversion; otherwise, false. - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if ((destinationType != typeof(string)) && (destinationType != typeof(InstanceDescriptor))) - { - return base.CanConvertTo(context, destinationType); - } - return true; - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// A that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// An that represents the converted value. - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (culture == null) - { - culture = CultureInfo.CurrentCulture; - } - string @string = value as string; - if (@string == null) - { - return base.ConvertFrom(context, culture, value); - } - @string = @string.Trim(); - char[] separator = new char[] { culture.TextInfo.ListSeparator[0] }; - string[] stringArray = @string.Split(separator); - if (stringArray.Length != 1) - { - throw new ArgumentException("Invalid half format."); - } - float H = (float)TypeDescriptor.GetConverter(typeof(float)).ConvertFromString(context, culture, stringArray[0]); - Half type = new Half(H); - return type; - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// A that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// A that represents the type you want to convert to. - /// An that represents the converted value. - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - { - throw new ArgumentNullException("destinationType"); - } - if (culture == null) - { - culture = CultureInfo.CurrentCulture; - } - if ((destinationType == typeof(string)) && value is Half) - { - TypeConverter converter = TypeDescriptor.GetConverter(typeof(float)); - return string.Join(culture.TextInfo.ListSeparator + " ", new string[] { converter.ConvertToString(context, culture, (float)((Half)value)) }); - } - if ((destinationType == typeof(InstanceDescriptor)) && value is Half) - { - var info = typeof(Half).GetConstructor(new Type[] { typeof(float) }); - if (info != null) - { - return new InstanceDescriptor(info, new object[] { (float)((Half)value) }); - } - } - return base.ConvertTo(context, culture, value, destinationType); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/MatrixConverter.cs b/source/OrkEngine3D.Mathematics/Design/MatrixConverter.cs deleted file mode 100644 index 0993e11..0000000 --- a/source/OrkEngine3D.Mathematics/Design/MatrixConverter.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class MatrixConverter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public MatrixConverter() - { - Type type = typeof(Matrix); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("M11")), - new FieldPropertyDescriptor(type.GetField("M12")), - new FieldPropertyDescriptor(type.GetField("M13")), - new FieldPropertyDescriptor(type.GetField("M14")), - - new FieldPropertyDescriptor(type.GetField("M21")), - new FieldPropertyDescriptor(type.GetField("M22")), - new FieldPropertyDescriptor(type.GetField("M23")), - new FieldPropertyDescriptor(type.GetField("M24")), - - new FieldPropertyDescriptor(type.GetField("M31")), - new FieldPropertyDescriptor(type.GetField("M32")), - new FieldPropertyDescriptor(type.GetField("M33")), - new FieldPropertyDescriptor(type.GetField("M34")), - - new FieldPropertyDescriptor(type.GetField("M41")), - new FieldPropertyDescriptor(type.GetField("M42")), - new FieldPropertyDescriptor(type.GetField("M43")), - new FieldPropertyDescriptor(type.GetField("M44")), - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Matrix) - { - var matrix = (Matrix)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, matrix.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Matrix).GetConstructor(Utilities.Array(typeof(float), 16)); - if (constructor != null) - return new InstanceDescriptor(constructor, matrix.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - - return values != null ? new Matrix(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - var matrix = new Matrix - { - M11 = (float)propertyValues["M11"], - M12 = (float)propertyValues["M12"], - M13 = (float)propertyValues["M13"], - M14 = (float)propertyValues["M14"], - M21 = (float)propertyValues["M21"], - M22 = (float)propertyValues["M22"], - M23 = (float)propertyValues["M23"], - M24 = (float)propertyValues["M24"], - M31 = (float)propertyValues["M31"], - M32 = (float)propertyValues["M32"], - M33 = (float)propertyValues["M33"], - M34 = (float)propertyValues["M34"], - M41 = (float)propertyValues["M41"], - M42 = (float)propertyValues["M42"], - M43 = (float)propertyValues["M43"], - M44 = (float)propertyValues["M44"] - }; - - return matrix; - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/QuaternionConverter.cs b/source/OrkEngine3D.Mathematics/Design/QuaternionConverter.cs deleted file mode 100644 index 50ce6f7..0000000 --- a/source/OrkEngine3D.Mathematics/Design/QuaternionConverter.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class QuaternionConverter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public QuaternionConverter() - { - var type = typeof(Quaternion); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Quaternion) - { - var quaternion = (Quaternion)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, quaternion.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Quaternion).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, quaternion.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Quaternion(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Quaternion((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Vector2Converter.cs b/source/OrkEngine3D.Mathematics/Design/Vector2Converter.cs deleted file mode 100644 index a7517ee..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Vector2Converter.cs +++ /dev/null @@ -1,121 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Vector2Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Vector2Converter() - { - var type = typeof(Vector2); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector2) - { - var vector = (Vector2)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector2).GetConstructor(Utilities.Array(typeof(float), 2)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector2(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector2((float)propertyValues["X"], (float)propertyValues["Y"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Vector3Converter.cs b/source/OrkEngine3D.Mathematics/Design/Vector3Converter.cs deleted file mode 100644 index f8a604b..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Vector3Converter.cs +++ /dev/null @@ -1,122 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Vector3Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Vector3Converter() - { - var type = typeof(Vector3); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector3) - { - var vector = (Vector3)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector3).GetConstructor(Utilities.Array(typeof(float), 3)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector3(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector3((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Design/Vector4Converter.cs b/source/OrkEngine3D.Mathematics/Design/Vector4Converter.cs deleted file mode 100644 index c38ad17..0000000 --- a/source/OrkEngine3D.Mathematics/Design/Vector4Converter.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design.Serialization; -using System.Globalization; - -namespace OrkEngine3D.Mathematics.Design; - -/// -/// Defines a type converter for . -/// -public class Vector4Converter : BaseConverter -{ - /// - /// Initializes a new instance of the class. - /// - public Vector4Converter() - { - var type = typeof(Vector4); - Properties = new PropertyDescriptorCollection(new[] - { - new FieldPropertyDescriptor(type.GetField("X")), - new FieldPropertyDescriptor(type.GetField("Y")), - new FieldPropertyDescriptor(type.GetField("Z")), - new FieldPropertyDescriptor(type.GetField("W")) - }); - } - - /// - /// Converts the given value object to the specified type, using the specified context and culture information. - /// - /// An that provides a format context. - /// A . If null is passed, the current culture is assumed. - /// The to convert. - /// The to convert the parameter to. - /// - /// An that represents the converted value. - /// - /// - /// The parameter is null. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType == null) - throw new ArgumentNullException("destinationType"); - - if (value is Vector4) - { - var vector = (Vector4)value; - - if (destinationType == typeof(string)) - return ConvertFromValues(context, culture, vector.ToArray()); - - if (destinationType == typeof(InstanceDescriptor)) - { - var constructor = typeof(Vector4).GetConstructor(Utilities.Array(typeof(float), 4)); - if (constructor != null) - return new InstanceDescriptor(constructor, vector.ToArray()); - } - } - - return base.ConvertTo(context, culture, value, destinationType); - } - - /// - /// Converts the given object to the type of this converter, using the specified context and culture information. - /// - /// An that provides a format context. - /// The to use as the current culture. - /// The to convert. - /// - /// An that represents the converted value. - /// - /// - /// The conversion cannot be performed. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - var values = ConvertToValues(context, culture, value); - return values != null ? new Vector4(values) : base.ConvertFrom(context, culture, value); - } - - /// - /// Creates an instance of the type that this is associated with, using the specified context, given a set of property values for the object. - /// - /// An that provides a format context. - /// An of new property values. - /// - /// An representing the given , or null if the object cannot be created. This method always returns null. - /// - public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) - { - if (propertyValues == null) - throw new ArgumentNullException("propertyValues"); - - return new Vector4((float)propertyValues["X"], (float)propertyValues["Y"], (float)propertyValues["Z"], (float)propertyValues["W"]); - } -} diff --git a/source/OrkEngine3D.Mathematics/Enums.cs b/source/OrkEngine3D.Mathematics/Enums.cs deleted file mode 100644 index 95ece8e..0000000 --- a/source/OrkEngine3D.Mathematics/Enums.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OrkEngine3D.Mathematics; - - /* - * The enumerations defined in this file are in alphabetical order. When - * adding new enumerations or renaming existing ones, please make sure - * the ordering is maintained. - */ - -/// -/// Describes how one bounding volume contains another. -/// -public enum ContainmentType -{ - /// - /// The two bounding volumes don't intersect at all. - /// - Disjoint, - - /// - /// One bounding volume completely contains another. - /// - Contains, - - /// - /// The two bounding volumes overlap. - /// - Intersects -}; - -/// -/// Describes the result of an intersection with a plane in three dimensions. -/// -public enum PlaneIntersectionType -{ - /// - /// The object is behind the plane. - /// - Back, - - /// - /// The object is in front of the plane. - /// - Front, - - /// - /// The object is intersecting the plane. - /// - Intersecting -}; diff --git a/source/OrkEngine3D.Mathematics/Gjk.cs b/source/OrkEngine3D.Mathematics/Gjk.cs deleted file mode 100644 index d5b0ea3..0000000 --- a/source/OrkEngine3D.Mathematics/Gjk.cs +++ /dev/null @@ -1,603 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Collections.Generic; - -namespace OrkEngine3D.Mathematics; - -/// -/// Implements the Gilbert-Johnson-Keerthi algorithm for convex polyhedra collision detection. -/// -public sealed class Gjk -{ - Vector3[] simplex = new Vector3[4]; - int count = 0; - Vector3 direction = Vector3.UnitX; - - /// - /// Gets or sets the direction for which to search for a support point. - /// - public Vector3 Direction - { - get { return direction; } - set { direction = value; } - } - - /// - /// Resets the state of this instance. - /// - public void Reset() - { - count = 0; - Direction = Vector3.UnitX; - } - - /// - /// Prepares the simplex to an empty state. - /// - public void Initialize() - { - count = 0; - } - - /// - /// Prepares the simplex with one initial point. - /// - /// The point to initialize the simplex with. - public void Initialize(Vector3 point1) - { - simplex[0] = point1; - - count = 1; - } - - /// - /// Prepares the simplex with two initial points. - /// - /// The first point to initialize the simplex with. - /// The second point to initialize the simplex with. - public void Initialize(Vector3 point1, Vector3 point2) - { - simplex[0] = point1; - simplex[1] = point2; - - count = 2; - } - - /// - /// Prepares the simplex with three initial points. - /// - /// The first point to initialize the simplex with. - /// The second point to initialize the simplex with. - /// The third point to initialize the simplex with. - public void Initialize(Vector3 point1, Vector3 point2, Vector3 point3) - { - simplex[0] = point1; - simplex[1] = point2; - simplex[2] = point3; - - count = 3; - } - /* - /// - /// Prepares the simplex with four initial points. - /// - /// The first point to initialize the simplex with. - /// The second point to initialize the simplex with. - /// The third point to initialize the simplex with. - /// The fourth point to initialize the simplex with. - public void Initialize(Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4) - { - simplex[0] = point1; - simplex[1] = point2; - simplex[2] = point3; - simplex[3] = point4; - - count = 4; - } - */ - /// - /// Checks for a collision between two convex polyhedra. - /// - /// The function delegate responsible for returning support points. - /// The maximum amount of iterations allowed. - /// true if there was an intersection between the two convex polyhedra; otherwise, falce. - public bool Intersects(Func supportFunction, int maxIterations = 20) - { - /* - * This method uses the following psuedo code from the paper: - * http://www.win.tue.nl/~gino/solid/jgt98convex.pdf - * - * You will notice that this method does not follow the psuedo code exactly. Some - * changes were made based on the fact that we do not use −v to get the new support - * point. This is becuase in our simplex handling code, the new direction is already - * pointing in the appropriate direction (pointing somewhere toward the origin). This - * also means that we have to flip the > sign to a < sign in the if statement. - * - * - * v := "arbitrary vector"; - * W := ∅; - * - * repeat - * w := Sᴀ-ʙ(−v); - * if v⋅w > 0 then return false; - * v := υ(conv(W ∪ {w})); - * W := "smallest X ⊆ W ∪ {w} such that v ∈ conv(X)"; - * until v = 0; - * - * return true - */ - - var currentiteration = 0; - count = 0; - - do - { - currentiteration++; - - var w = supportFunction(Direction); - simplex[count++] = w; - - if (Vector3.Dot(Direction, w) < 0f) - return false; - - switch (count) - { - case 2: - DoLine(simplex[1], simplex[0]); - break; - - case 3: - DoTriangle(simplex[2], simplex[1], simplex[0]); - break; - - case 4: - if (DoTetrahedron(simplex[3], simplex[2], simplex[1], simplex[0])) - return true; - break; - } - } while (!Direction.Equals(Vector3.Zero, Utilities.ZeroTolerance) && currentiteration < maxIterations); - - return false; - } - - /// - /// Gets the minimum distance between two convex polyhedra. - /// - /// The function delegate responsible for returning support points. - /// The amount of allotted error in the result. - /// true if there was an intersection between the two convex polyhedra; otherwise, falce. - /// The minimum distance between the two convex polyhedra. - public float GetMinimumDistance(Func supportFunction, int maxIterations = 20, float epsilon = 0.1f) - { - /* - * This method uses the following psuedo code from the paper: - * http://www.win.tue.nl/~gino/solid/jgt98convex.pdf - * - * - * v := "arbitrary point in A − B"; - * W := ∅; - * μ := 0; - * close_enough := false; - * - * while not close_enough and v ≠ 0 do begin - * w := Sᴀ-ʙ(−v); - * δ := v⋅w/‖v‖; - * μ := max{μ,δ}; - * close_enough := ‖v‖ − μ ≤ ε; - * - * if not close_enough then begin - * v := υ(conv(W ∪ {w})); - * W := "smallest X ⊆ W ∪ {w} such that v ∈ conv(X)"; - * end - * end; - * - * return ‖v‖ - */ - - var currentiteration = 0; - var u = 0f; - var closeenough = false; - - Direction = supportFunction(Direction); - count = 0; - - while (!closeenough && !Direction.Equals(Vector3.Zero, Utilities.ZeroTolerance) && currentiteration < maxIterations) - { - currentiteration++; - float directionlength = Direction.Length(); - - var w = supportFunction(-Direction); - var d = Vector3.Dot(Direction, w) / directionlength; - u = Math.Max(u, d); - - closeenough = directionlength - u <= epsilon; - - simplex[count++] = w; - - if (!closeenough) - { - switch (count) - { - case 2: - DoLineNoDirection(simplex[1], simplex[0]); - break; - - case 3: - DoTriangleNoDirection(simplex[2], simplex[1], simplex[0]); - break; - - case 4: - if (DoTetrahedronNoDirection(simplex[3], simplex[2], simplex[1], simplex[0])) - { - //Objects intersect, distance makes no sense - return Direction.Length(); - } - break; - } - - Vector3 origin = Vector3.Zero; - - switch (count) - { - case 1: - Direction = simplex[0]; - break; - - case 2: - Collision.ClosestPointOnSegmentToPoint(ref simplex[0], ref simplex[1], ref origin, out direction); - break; - - case 3: - Collision.ClosestPointOnTriangleToPoint(ref simplex[0], ref simplex[1], ref simplex[2], ref origin, out direction); - break; - } - } - } - - return Direction.Length(); - } - - /// - /// Simplifies a line simplex. - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - private void DoLineNoDirection(Vector3 a, Vector3 b) - { - Vector3 ab = b - a; - - if (Vector3.Dot(ab, -a) > 0.0f) - { - //Do not simplify this code out, it is needed for the - //DoTriangle and DoTetrahedron methods - simplex[0] = b; - simplex[1] = a; - count = 2; - } - else - { - simplex[0] = a; - count = 1; - } - } - - /// - /// Simplifies a triangle simplex; - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - /// The oldest point in the simplex. - private void DoTriangleNoDirection(Vector3 a, Vector3 b, Vector3 c) - { - Vector3 ab = b - a; - Vector3 ac = c - a; - - Vector3 abc = Vector3.Cross(ab, ac); - Vector3 ababc = Vector3.Cross(ab, abc); - Vector3 abcac = Vector3.Cross(abc, ac); - - if (Vector3.Dot(abcac, -a) > 0.0f) - { - if (Vector3.Dot(ac, -a) > 0.0f) - { - simplex[0] = c; - simplex[1] = a; - count = 2; - } - else - { - DoLine(a, b); - } - } - else - { - if (Vector3.Dot(ababc, -a) > 0.0f) - { - DoLine(a, b); - } - else - { - if (Vector3.Dot(abc, -a) > 0.0f) - { - //Do not simplify this code out, it is needed for the - //DoTetrahedron methods - simplex[0] = c; - simplex[1] = b; - simplex[2] = a; - count = 3; - } - else - { - simplex[0] = b; - simplex[1] = c; - simplex[2] = a; - count = 3; - } - } - } - } - - /// - /// Simplifies a tetrahedron simplex. - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - /// The older point in the simplex. - /// The oldest point in the simplex. - /// true if the origin is contained by this simplex; otherwise, false. - private bool DoTetrahedronNoDirection(Vector3 a, Vector3 b, Vector3 c, Vector3 d) - { - Vector3 ab = b - a; - Vector3 ac = c - a; - Vector3 ad = d - a; - Vector3 abc = Vector3.Cross(ab, ac); - Vector3 acd = Vector3.Cross(ac, ad); - Vector3 adb = Vector3.Cross(ad, ab); - - if (Vector3.Dot(abc, -a) > 0.0f) - { - if (Vector3.Dot(acd, -a) > 0.0f) - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - simplex[0] = a; - count = 1; - return false; - } - else - { - DoLine(a, c); - return false; - } - } - else - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoLine(a, b); - return false; - } - else - { - DoTriangle(a, b, c); - return false; - } - } - } - else - { - if (Vector3.Dot(acd, -a) > 0.0f) - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoLine(a, d); - return false; - } - else - { - DoTriangle(a, c, d); - return false; - } - } - else - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoTriangle(a, d, b); - return false; - } - else - { - return true; - } - } - } - } - - /// - /// Simplifies a line simplex and finds the new direction. - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - private void DoLine(Vector3 a, Vector3 b) - { - Vector3 ab = b - a; - - if (Vector3.Dot(ab, -a) > 0.0f) - { - //Do not simplify this code out, it is needed for the - //DoTriangle and DoTetrahedron methods - simplex[0] = b; - simplex[1] = a; - count = 2; - Direction = Vector3.Cross(ab, Vector3.Cross(-a, ab)); - } - else - { - simplex[0] = a; - count = 1; - Direction = -a; - } - } - - /// - /// Simplifies a triangle simplex and finds the new direction. - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - /// The oldest point in the simplex. - private void DoTriangle(Vector3 a, Vector3 b, Vector3 c) - { - Vector3 ab = b - a; - Vector3 ac = c - a; - - Vector3 abc = Vector3.Cross(ab, ac); - Vector3 ababc = Vector3.Cross(ab, abc); - Vector3 abcac = Vector3.Cross(abc, ac); - - if (Vector3.Dot(abcac, -a) > 0.0f) - { - if (Vector3.Dot(ac, -a) > 0.0f) - { - simplex[0] = c; - simplex[1] = a; - count = 2; - Direction = Vector3.Cross(ac, Vector3.Cross(-a, ac)); - } - else - { - DoLine(a, b); - } - } - else - { - if (Vector3.Dot(ababc, -a) > 0.0f) - { - DoLine(a, b); - } - else - { - if (Vector3.Dot(abc, -a) > 0.0f) - { - //Do not simplify this code out, it is needed for the - //DoTetrahedron methods - simplex[0] = c; - simplex[1] = b; - simplex[2] = a; - count = 3; - Direction = abc; - } - else - { - simplex[0] = b; - simplex[1] = c; - simplex[2] = a; - count = 3; - Direction = -abc; - } - } - } - } - - /// - /// Simplifies a tetrahedron simplex and finds the new direction. - /// - /// The newly added point in the simplex. - /// The old point in the simplex. - /// The older point in the simplex. - /// The oldest point in the simplex. - /// true if the origin is contained by this simplex; otherwise, false. - private bool DoTetrahedron(Vector3 a, Vector3 b, Vector3 c, Vector3 d) - { - Vector3 ab = b - a; - Vector3 ac = c - a; - Vector3 ad = d - a; - Vector3 abc = Vector3.Cross(ab, ac); - Vector3 acd = Vector3.Cross(ac, ad); - Vector3 adb = Vector3.Cross(ad, ab); - - if (Vector3.Dot(abc, -a) > 0.0f) - { - if (Vector3.Dot(acd, -a) > 0.0f) - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - simplex[0] = a; - count = 1; - Direction = -a; - return false; - } - else - { - DoLine(a, c); - return false; - } - } - else - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoLine(a, b); - return false; - } - else - { - DoTriangle(a, b, c); - return false; - } - } - } - else - { - if (Vector3.Dot(acd, -a) > 0.0f) - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoLine(a, d); - return false; - } - else - { - DoTriangle(a, c, d); - return false; - } - } - else - { - if (Vector3.Dot(adb, -a) > 0.0f) - { - DoTriangle(a, d, b); - return false; - } - else - { - return true; - } - } - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Half.cs b/source/OrkEngine3D.Mathematics/Half.cs deleted file mode 100644 index 9f5c5ff..0000000 --- a/source/OrkEngine3D.Mathematics/Half.cs +++ /dev/null @@ -1,551 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// A half precision (16 bit) floating point value. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential)] -public struct Half : IConvertible, IComparable, IComparable, IEquatable, IFormattable -{ - private ushort value; - - /// - /// Number of decimal digits of precision. - /// - public const int PrecisionDigits = 3; - - /// - /// Number of bits in the mantissa. - /// - public const int MantissaBits = 11; - - /// - /// Maximum decimal exponent. - /// - public const int MaximumDecimalExponent = 4; - - /// - /// Maximum binary exponent. - /// - public const int MaximumBinaryExponent = 15; - - /// - /// Minimum decimal exponent. - /// - public const int MinimumDecimalExponent = -4; - - /// - /// Minimum binary exponent. - /// - public const int MinimumBinaryExponent = -14; - - /// - /// Exponent radix. - /// - public const int ExponentRadix = 2; - - /// - /// Additional rounding. - /// - public const int AdditionRounding = 1; - - /// - /// Smallest value such that 1.0 + epsilon != 1.0 - /// - public static readonly Half Epsilon = new Half(0.0004887581f); - - /// - /// Maximum value of the number. - /// - public static readonly Half MaxValue = new Half(65504f); - - /// - /// Minimum value of the number. - /// - public static readonly Half MinValue = new Half(6.103516E-05f); - - /// - /// Represents not a number (NaN). - /// - public static readonly Half NaN = new Half(0.0f / 0.0f); - - /// - /// Represents negative infinity. - /// - public static readonly Half NegativeInfinity = new Half(-1.0f / 0.0f); - - /// - /// Represents positive infinity. - /// - public static readonly Half PositiveInfinity = new Half(1.0f / 0.0f); - - /// - /// Initializes a new instance of the structure. - /// - /// The floating point value that should be stored in 16 bit format. - public Half(float value) - { - this.value = HalfUtilities.Pack(value); - } - - /// - /// Gets the raw 16 bit value used to back this half-float. - /// - // I also removed one line here(that bugged me) - public ushort RawValue - { - get { return value; } - } - - /// - /// Converts an array of half precision values into full precision values. - /// - /// The values to be converted. - /// An array of converted values. - public static float[] ConvertToFloat(Half[] values) - { - float[] results = new float[values.Length]; - - for(int i = 0; i < results.Length; i++) - results[i] = HalfUtilities.Unpack(values[i].RawValue); - - return results; - } - - /// - /// Converts an array of full precision values into half precision values. - /// - /// The values to be converted. - /// An array of converted values. - public static Half[] ConvertToHalf(float[] values) - { - Half[] results = new Half[values.Length]; - - for(int i = 0; i < results.Length; i++) - results[i] = new Half(values[i]); - - return results; - } - - /// - /// Returns a value indicating whether the specified number evaluates to negative or positive infinity. - /// - /// The to check. - /// true if evaluates to positive or negative infinity; otherwise, false. - public static bool IsInfinity(Half half) - { - return (half == PositiveInfinity) || (half == NegativeInfinity); - } - - /// - /// Returns a value indicating whether the specified number evaluates to NaN. - /// - /// The to check. - /// true if evaluates to NaN; otherwise, false. - public static bool IsNaN(Half half) - { - return half == NaN; - } - - /// - /// Returns a value indicating whether the specified number evaluates to negative infinity. - /// - /// The to check. - /// true if evaluates to negative infinity; otherwise, false. - public static bool IsNegativeInfinity(Half half) - { - return half == NegativeInfinity; - } - - /// - /// Returns a value indicating whether the specified number evaluates to positive infinity. - /// - /// The to check. - /// true if evaluates to positive infinity; otherwise, false. - public static bool IsPositiveInfinity(Half half) - { - return half == PositiveInfinity; - } - - /// - /// Returns a value that indicates whether a specified value is - /// less than another specified value. - /// - /// The first value to compare. - /// The second value to compare. - /// true if is less than ; otherwise, false. - public static bool operator <(Half left, Half right) - { - return (float)left < (float)right; - } - - /// - /// Returns a value that indicates whether a specified value is - /// greater than another specified value. - /// - /// The first value to compare. - /// The second value to compare. - /// true if is greater than ; otherwise, false. - public static bool operator >(Half left, Half right) - { - return (float)left > (float)right; - } - - /// - /// Returns a value that indicates whether a specified value is - /// less than or equal to another specified value. - /// - /// The first value to compare. - /// The second value to compare. - /// true if is less than or equal to ; otherwise, false. - public static bool operator <=(Half left, Half right) - { - return (float)left <= (float)right; - } - - /// - /// Returns a value that indicates whether a specified value is - /// greater than or equal to another specified value. - /// - /// The first value to compare. - /// The second value to compare. - /// true if is greater than or equal to right; otherwise, false. - public static bool operator >=(Half left, Half right) - { - return (float)left >= (float)right; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Half left, Half right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Half left, Half right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static explicit operator Half(float value) - { - return new Half(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static implicit operator float(Half value) - { - return HalfUtilities.Unpack(value.value); - } - - /// - /// Converts the value of the object to its equivalent string representation. - /// - /// The string representation of the value of this instance. - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, ((float)this).ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, ((float)this).ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, ((float)this).ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - ToString(formatProvider); - - return string.Format(formatProvider, ((float)this).ToString(format, formatProvider)); - } - - /// - /// Returns the hash code for this instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return (((value * 3) / 2) ^ value); - } - - /// - /// Compares this instance to another instance of the same type. - /// - /// The other value to compare to this instance. - /// A value that specifies if this instance is greater than, less than, or equal to . - public int CompareTo(Half value) - { - if (this < value) - { - return -1; - } - - if (this > value) - { - return 1; - } - - if (this != value) - { - if (!IsNaN(this)) - { - return 1; - } - - if (!IsNaN(value)) - { - return -1; - } - } - - return 0; - } - - /// - /// Compares this instance to another instance of another type. - /// - /// The other value to compare to this instance. - /// A value that specifies if this instance is greater than, less than, or equal to . - public int CompareTo(object value) - { - if (value == null) - { - return 1; - } - - if (!(value is Half)) - { - throw new ArgumentException("The argument value must be a SlimMath.Half."); - } - - Half f = (Half)value; - if (this < f) - { - return -1; - } - - if (this > f) - { - return 1; - } - - if (this != f) - { - if (!IsNaN(this)) - { - return 1; - } - - if (!IsNaN(f)) - { - return -1; - } - } - - return 0; - } - - /// - /// Determines whether the specified object instances are considered equal. - /// - /// - /// - /// - /// true if is the same instance as or - /// if both are null references or if value1.Equals(value2) returns true; otherwise, false. - public static bool Equals(ref Half value1, ref Half value2) - { - return value1.value == value2.value; - } - - /// - /// Returns a value that indicates whether the current instance is equal to the specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public bool Equals(Half other) - { - return other.value == value; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Half)obj); - } - - /// - /// Returns the for value type . - /// - /// The type code. - public TypeCode GetTypeCode() - { - return Type.GetTypeCode(typeof(Half)); - } - - bool IConvertible.ToBoolean(IFormatProvider provider) - { - return Convert.ToBoolean(this); - } - - byte IConvertible.ToByte(IFormatProvider provider) - { - return Convert.ToByte(this); - } - - char IConvertible.ToChar(IFormatProvider provider) - { - throw new InvalidCastException("Invalid cast from SlimMath.Half to System.Char."); - } - - DateTime IConvertible.ToDateTime(IFormatProvider provider) - { - throw new InvalidCastException("Invalid cast from SlimMath.Half to System.DateTime."); - } - - decimal IConvertible.ToDecimal(IFormatProvider provider) - { - return Convert.ToDecimal(this); - } - - double IConvertible.ToDouble(IFormatProvider provider) - { - return Convert.ToDouble(this); - } - - short IConvertible.ToInt16(IFormatProvider provider) - { - return Convert.ToInt16(this); - } - - int IConvertible.ToInt32(IFormatProvider provider) - { - return Convert.ToInt32(this); - } - - long IConvertible.ToInt64(IFormatProvider provider) - { - return Convert.ToInt64(this); - } - - sbyte IConvertible.ToSByte(IFormatProvider provider) - { - return Convert.ToSByte(this); - } - - float IConvertible.ToSingle(IFormatProvider provider) - { - return this; - } - - object IConvertible.ToType(Type type, IFormatProvider provider) - { - return ((IConvertible)((float)this)).ToType(type, provider); - } - - ushort IConvertible.ToUInt16(IFormatProvider provider) - { - return Convert.ToUInt16(this); - } - - uint IConvertible.ToUInt32(IFormatProvider provider) - { - return Convert.ToUInt32(this); - } - - ulong IConvertible.ToUInt64(IFormatProvider provider) - { - return Convert.ToUInt64(this); - } -} diff --git a/source/OrkEngine3D.Mathematics/Half2.cs b/source/OrkEngine3D.Mathematics/Half2.cs deleted file mode 100644 index 3c95e42..0000000 --- a/source/OrkEngine3D.Mathematics/Half2.cs +++ /dev/null @@ -1,263 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Defines a two component vector, using half precision floating point coordinates. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential)] -public struct Half2 : IEquatable, IFormattable -{ - /// - /// Gets or sets the X component of the vector. - /// - /// The X component of the vector. - public Half X; - - /// - /// Gets or sets the Y component of the vector. - /// - /// The Y component of the vector. - public Half Y; - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - public Half2(Half x, Half y) - { - this.X = x; - this.Y = y; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for both the X and Y components. - public Half2(Half value) - { - this.X = value; - this.Y = value; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - public Half2(float x, float y) - { - this.X = (Half)x; - this.Y = (Half)y; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for both the X and Y components. - public Half2(float value) - { - this.X = this.Y = (Half)value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X and Y components of the vector. This must be an array with two elements. - /// Thrown when is null. - /// Thrown when contains more or less than two elements. - public Half2(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 2) - throw new ArgumentOutOfRangeException("values", "There must be two and only two input values for Half2."); - - X = (Half)values[0]; - Y = (Half)values[1]; - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A two-element array containing the components of the vector. - public Half[] ToArray() - { - return new Half[] { X, Y }; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Half2 left, Half2 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Half2 left, Half2 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static explicit operator Half2(Vector2 value) - { - return new Half2(value.X, value.Y); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static implicit operator Vector2(Half2 value) - { - return new Vector2(value.X, value.Y); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X, Y); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X.ToString(format, CultureInfo.CurrentCulture), Y.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1}", X, Y); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1}", X.ToString(format, formatProvider), Y.ToString(format, formatProvider)); - } - - /// - /// Returns the hash code for this instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode(); - } - - /// - /// Determines whether the specified object instances are considered equal. - /// - /// - /// - /// - /// true if is the same instance as or - /// if both are null references or if value1.Equals(value2) returns true; otherwise, false. - public static bool Equals(ref Half2 value1, ref Half2 value2) - { - return (value1.X == value2.X) && (value1.Y == value2.Y); - } - - /// - /// Returns a value that indicates whether the current instance is equal to the specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public bool Equals(Half2 other) - { - return (this.X == other.X) && (this.Y == other.Y); - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Half2)obj); - } -} diff --git a/source/OrkEngine3D.Mathematics/Half3.cs b/source/OrkEngine3D.Mathematics/Half3.cs deleted file mode 100644 index 6af9bdd..0000000 --- a/source/OrkEngine3D.Mathematics/Half3.cs +++ /dev/null @@ -1,277 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Defines a three component vector, using half precision floating point coordinates. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential)] -public struct Half3 : IEquatable, IFormattable -{ - /// - /// Gets or sets the X component of the vector. - /// - /// The X component of the vector. - public Half X; - - /// - /// Gets or sets the Y component of the vector. - /// - /// The Y component of the vector. - public Half Y; - - /// - /// Gets or sets the Z component of the vector. - /// - /// The Z component of the vector. - public Half Z; - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - /// The Z component. - public Half3(Half x, Half y, Half z) - { - this.X = x; - this.Y = y; - this.Z = z; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for the X, Y, and Z components. - public Half3(Half value) - { - this.X = value; - this.Y = value; - this.Z = value; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - /// The Z component. - public Half3(float x, float y, float z) - { - this.X = (Half)x; - this.Y = (Half)y; - this.Z = (Half)z; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for the X, Y, and Z components. - public Half3(float value) - { - this.X = this.Y = this.Z = (Half)value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X, Y, and Z components of the vector. This must be an array with three elements. - /// Thrown when is null. - /// Thrown when contains more or less than three elements. - public Half3(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 3) - throw new ArgumentOutOfRangeException("values", "There must be three and only three input values for Half3."); - - X = (Half)values[0]; - Y = (Half)values[1]; - Z = (Half)values[2]; - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A two-element array containing the components of the vector. - public Half[] ToArray() - { - return new Half[] { X, Y, Z }; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Half3 left, Half3 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Half3 left, Half3 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static explicit operator Half3(Vector3 value) - { - return new Half3(value.X, value.Y, value.Z); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static implicit operator Vector3(Half3 value) - { - return new Vector3(value.X, value.Y, value.Z); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} Q:{3}", X, Y, Z); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2}", X.ToString(format, CultureInfo.CurrentCulture), - Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X, Y, Z); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X.ToString(format, formatProvider), - Y.ToString(format, formatProvider), Z.ToString(format, formatProvider)); - } - - /// - /// Returns the hash code for this instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode(); - } - - /// - /// Determines whether the specified object instances are considered equal. - /// - /// - /// - /// - /// true if is the same instance as or - /// if both are null references or if value1.Equals(value2) returns true; otherwise, false. - public static bool Equals(ref Half3 value1, ref Half3 value2) - { - return (value1.X == value2.X) && (value1.Y == value2.Y) && (value1.Z == value2.Z); - } - - /// - /// Returns a value that indicates whether the current instance is equal to the specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public bool Equals(Half3 other) - { - return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z); - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Half3)obj); - } -} diff --git a/source/OrkEngine3D.Mathematics/Half4.cs b/source/OrkEngine3D.Mathematics/Half4.cs deleted file mode 100644 index ae0a802..0000000 --- a/source/OrkEngine3D.Mathematics/Half4.cs +++ /dev/null @@ -1,289 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimMath Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Defines a four component vector, using half precision floating point coordinates. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential)] -public struct Half4 : IEquatable, IFormattable -{ - /// - /// Gets or sets the X component of the vector. - /// - /// The X component of the vector. - public Half X; - - /// - /// Gets or sets the Y component of the vector. - /// - /// The Y component of the vector. - public Half Y; - - /// - /// Gets or sets the Z component of the vector. - /// - /// The Z component of the vector. - public Half Z; - - /// - /// Gets or sets the W component of the vector. - /// - /// The W component of the vector. - public Half W; - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - /// The Z component. - /// The W component. - public Half4(Half x, Half y, Half z, Half w) - { - this.X = x; - this.Y = y; - this.Z = z; - this.W = w; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for the X, Y, Z, and W components. - public Half4(Half value) - { - this.X = value; - this.Y = value; - this.Z = value; - this.W = value; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The X component. - /// The Y component. - /// The Z component. - /// The W component. - public Half4(float x, float y, float z, float w) - { - this.X = (Half)x; - this.Y = (Half)y; - this.Z = (Half)z; - this.W = (Half)w; - } - - /// - /// Initializes a new instance of the structure. - /// - /// The value to set for the X, Y, Z, and W components. - public Half4(float value) - { - this.X = this.Y = this.Z = this.W = (Half)value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X, Y, Z, and W components of the vector. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Half4(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 4) - throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Half4."); - - X = (Half)values[0]; - Y = (Half)values[1]; - Z = (Half)values[2]; - W = (Half)values[3]; - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A two-element array containing the components of the vector. - public Half[] ToArray() - { - return new Half[] { X, Y, Z, W }; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Half4 left, Half4 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Half4 left, Half4 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static explicit operator Half4(Vector4 value) - { - return new Half4(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to be converted. - /// The converted value. - public static implicit operator Vector4(Half4 value) - { - return new Vector4(value.X, value.Y, value.Z, value.W); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} Q:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, CultureInfo.CurrentCulture), - Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture), W.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, formatProvider), - Y.ToString(format, formatProvider), Z.ToString(format, formatProvider), W.ToString(format, formatProvider)); - } - - /// - /// Returns the hash code for this instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode(); - } - - /// - /// Determines whether the specified object instances are considered equal. - /// - /// - /// - /// - /// true if is the same instance as or - /// if both are null references or if value1.Equals(value2) returns true; otherwise, false. - public static bool Equals(ref Half4 value1, ref Half4 value2) - { - return (value1.X == value2.X) && (value1.Y == value2.Y) && (value1.Z == value2.Z) && (value1.W == value2.W); - } - - /// - /// Returns a value that indicates whether the current instance is equal to the specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public bool Equals(Half4 other) - { - return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z) && (this.W == other.W); - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// Object to make the comparison with. - /// - /// true if the current instance is equal to the specified object; false otherwise. - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Half4)obj); - } -} diff --git a/source/OrkEngine3D.Mathematics/HalfUtilities.cs b/source/OrkEngine3D.Mathematics/HalfUtilities.cs deleted file mode 100644 index a5d0e6b..0000000 --- a/source/OrkEngine3D.Mathematics/HalfUtilities.cs +++ /dev/null @@ -1,180 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Helper class to perform Half/Float conversion. -/// -internal static class HalfUtilities -{ - //Source: www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf by Jeroen van der Zijp - static readonly uint[] HalfToFloatMantissaTable = new uint[2048]; - static readonly uint[] HalfToFloatExponentTable = new uint[64]; - static readonly uint[] HalfToFloatOffsetTable = new uint[64]; - static readonly ushort[] FloatToHalfBaseTable = new ushort[512]; - static readonly byte[] FloatToHalfShiftTable = new byte[512]; - - [StructLayout(LayoutKind.Explicit)] - private struct FloatToUint - { - [FieldOffset(0)] - public uint uintValue; - - [FieldOffset(0)] - public float floatValue; - } - - static HalfUtilities() - { - int i; - - //Mantissa table - - //0 => 0 - HalfToFloatMantissaTable[0] = 0; - - //Transform subnormal to normalized - for (i = 1; i < 1024; i++) - { - uint m = ((uint)i) << 13; - uint e = 0; - - while ((m & 0x00800000) == 0) - { - e -= 0x00800000; - m <<= 1; - } - - m &= ~0x00800000U; - e += 0x38800000; - HalfToFloatMantissaTable[i] = m | e; - } - - //Normal case - for (i = 1024; i < 2048; i++) - HalfToFloatMantissaTable[i] = 0x38000000 + (((uint)(i - 1024)) << 13); - - //Exponent table - - //0 => 0 - HalfToFloatExponentTable[0] = 0; - - for (i = 1; i < 63; i++) - { - if (i < 31) - { - //Positive Numbers - HalfToFloatExponentTable[i] = ((uint)i) << 23; - } - else - { - //Negative Numbers - HalfToFloatExponentTable[i] = 0x80000000 + (((uint)(i - 32)) << 23); - } - } - HalfToFloatExponentTable[31] = 0x47800000; - HalfToFloatExponentTable[32] = 0x80000000; - HalfToFloatExponentTable[63] = 0xC7800000; - - //Offset table - HalfToFloatOffsetTable[0] = 0; - for (i = 1; i < 64; i++) - HalfToFloatOffsetTable[i] = 1024; - HalfToFloatOffsetTable[32] = 0; - - //Float to Half tables - for (i = 0; i < 256; i++) - { - int e = i - 127; - if (e < -24) - { - //Very small numbers map to zero - FloatToHalfBaseTable[i | 0x000] = 0x0000; - FloatToHalfBaseTable[i | 0x100] = 0x8000; - FloatToHalfShiftTable[i | 0x000] = 24; - FloatToHalfShiftTable[i | 0x100] = 24; - } - else if (e < -14) - { - //Small numbers map to denorms - FloatToHalfBaseTable[i | 0x000] = (ushort)((0x0400 >> (-e - 14))); - FloatToHalfBaseTable[i | 0x100] = (ushort)((0x0400 >> (-e - 14)) | 0x8000); - FloatToHalfShiftTable[i | 0x000] = (byte)(-e - 1); - FloatToHalfShiftTable[i | 0x100] = (byte)(-e - 1); - } - else if (e <= 15) - { - //Normal numbers just lose precision - FloatToHalfBaseTable[i | 0x000] = (ushort)(((e + 15) << 10)); - FloatToHalfBaseTable[i | 0x100] = (ushort)(((e + 15) << 10) | 0x8000); - FloatToHalfShiftTable[i | 0x000] = 13; - FloatToHalfShiftTable[i | 0x100] = 13; - } - else if (e < 128) - { - //Large numbers map to Infinity - FloatToHalfBaseTable[i | 0x000] = 0x7C00; - FloatToHalfBaseTable[i | 0x100] = 0xFC00; - FloatToHalfShiftTable[i | 0x000] = 24; - FloatToHalfShiftTable[i | 0x100] = 24; - } - else - { - //Infinity and NaN's stay Infinity and NaN's - FloatToHalfBaseTable[i | 0x000] = 0x7C00; - FloatToHalfBaseTable[i | 0x100] = 0xFC00; - FloatToHalfShiftTable[i | 0x000] = 13; - FloatToHalfShiftTable[i | 0x100] = 13; - } - } - } - - /// - /// Unpacks the specified half. - /// - /// The half to unpack. - /// The floating point representation of the half. - public static float Unpack(ushort value) - { - var conv = new FloatToUint(); - conv.uintValue = HalfToFloatMantissaTable[HalfToFloatOffsetTable[value >> 10] + (((uint)value) & 0x3ff)] + HalfToFloatExponentTable[value >> 10]; - return conv.floatValue; - } - - /// - /// Packs the specified float. - /// - /// The float to pack. - /// The half represntation of the float. - public static ushort Pack(float value) - { - FloatToUint conv = new FloatToUint(); - conv.floatValue = value; - return (ushort)(FloatToHalfBaseTable[(conv.uintValue >> 23) & 0x1ff] + ((conv.uintValue & 0x007fffff) >> FloatToHalfShiftTable[(conv.uintValue >> 23) & 0x1ff])); - } -} diff --git a/source/OrkEngine3D.Mathematics/MathF.cs b/source/OrkEngine3D.Mathematics/MathF.cs deleted file mode 100644 index 1d78859..0000000 --- a/source/OrkEngine3D.Mathematics/MathF.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using sMathf = System.MathF; - -namespace OrkEngine3D.Mathematics; - -public static class MathF -{ - public const float E = 2.71828175F; - - public const float PI = 3.14159274F; - - public const float Tau = 6.28318548F; - - public static float Abs(float x) => sMathf.Abs(x); - - public static float Acos(float x) => sMathf.Acos(x); - - public static float Acosh(float x) => sMathf.Acosh(x); - - public static float Asin(float x) => sMathf.Asin(x); - - public static float Asinh(float x) => sMathf.Asinh(x); - - public static float Atan(float x) => sMathf.Atan(x); - - public static float Atan2(float y, float x) => sMathf.Atan2(x, y); - - public static float Atanh(float x) => sMathf.Atanh(x); - - public static float BitDecrement(float x) => sMathf.BitDecrement(x); - - public static float BitIcrement(float x) => sMathf.BitIncrement(x); - - public static float Cbrt(float x) => sMathf.Cbrt(x); - - public static float Ceiling(float x) => sMathf.Ceiling(x); - - public static float CopySign(float x, float y) => sMathf.CopySign(x, y); - - public static float Cos(float x) => sMathf.Cos(x); - - public static float Cosh(float x) => sMathf.Cosh(x); - - public static float Exp(float x) => sMathf.Exp(x); - - public static float Floor(float x) => sMathf.Floor(x); - - public static float FusedMultipleAdd(float x, float y, float z) => sMathf.FusedMultiplyAdd(x, y, z); - - public static float IEEERemainder(float x, float y) => sMathf.IEEERemainder(x, y); - - public static int ILogB(float x) => sMathf.ILogB(x); - - public static float Log(float x) => sMathf.Log(x); - - public static float Log(float x, float y) => sMathf.Log(x, y); - - public static float Log10(float x) => sMathf.Log10(x); - - public static float Log2(float x) => sMathf.Log2(x); - - public static float Max(float x, float y) => sMathf.Max(x, y); - - public static float MaxMagnitude(float x, float y) => sMathf.MaxMagnitude(x, y); - - public static float Min(float x, float y) => sMathf.Min(x, y); - - public static float MinMagnitude(float x, float y) => sMathf.MinMagnitude(x, y); - - public static float Pow(float x, float y) => sMathf.Pow(x, y); - - public static float Round(float x, MidpointRounding mode) => sMathf.Round(x, mode); - - public static float Round(float x, int digits, MidpointRounding mode) => sMathf.Round(x, digits, mode); - - public static float Round(float x) => sMathf.Round(x); - - public static float Round(float x, int digits) => sMathf.Round(x, digits); - - public static float ScaleB(float x, int n) => sMathf.ScaleB(x, n); - - public static int Sign(float x) => sMathf.Sign(x); - - public static float Sin(float x) => sMathf.Sin(x); - - public static float Sinh(float x) => sMathf.Sinh(x); - - public static float Sqrt(float x) => sMathf.Sqrt(x); - - public static float Tan(float x) => sMathf.Tan(x); - - public static float Tanh(float x) => sMathf.Tanh(x); - - public static float Truncate(float x) => sMathf.Truncate(x); -} diff --git a/source/OrkEngine3D.Mathematics/MathHelper.cs b/source/OrkEngine3D.Mathematics/MathHelper.cs deleted file mode 100644 index f59bb04..0000000 --- a/source/OrkEngine3D.Mathematics/MathHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - - -namespace OrkEngine3D.Mathematics; - -/// -/// Contains mathmeatical methods and constants that extend the System.Math class. -/// -public static class MathHelper -{ - /// - /// A value specifying the approximation of π which is 180 degrees. - /// - public const float Pi = 3.141592653589793239f; - - /// - /// A value specifying the approximation of 2π which is 360 degrees. - /// - public const float TwoPi = 6.283185307179586477f; - - /// - /// A value specifying the approximation of π/2 which is 90 degrees. - /// - public const float PiOverTwo = 1.570796326794896619f; - - /// - /// A value specifying the approximation of π/4 which is 45 degrees. - /// - public const float PiOverFour = 0.785398163397448310f; - - /// - /// Converts degrees to radians. - /// - /// The value to convert. - /// The converted value. - public static float DegreesToRadians(float degree) - { - return degree * (Pi / 180.0f); - } - - /// - /// Converts radians to degrees. - /// - /// The value to convert. - /// The converted value. - public static float RadiansToDegrees(float radian) - { - return radian * (180.0f / Pi); - } -} diff --git a/source/OrkEngine3D.Mathematics/MathUtils.cs b/source/OrkEngine3D.Mathematics/MathUtils.cs deleted file mode 100644 index 3b47491..0000000 --- a/source/OrkEngine3D.Mathematics/MathUtils.cs +++ /dev/null @@ -1,703 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ----------------------------------------------------------------------------- -// Original code from SlimMath project. http://code.google.com/p/slimmath/ -// Greetings to SlimDX Group. Original code published with the following license: -// ----------------------------------------------------------------------------- -/* -* Copyright (c) 2007-2011 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Drawing; -using System.Runtime.CompilerServices; - -namespace OrkEngine3D.Mathematics; - -/// -/// Common utility methods for math operations. -/// -public static class MathUtil -{ - /// - /// The value for which all absolute numbers smaller than are considered equal to zero. - /// - public const float ZeroTolerance = 1e-6f; // Value a 8x higher than 1.19209290E-07F - - /// - /// The value for which all absolute numbers smaller than are considered equal to zero. - /// - public const double ZeroToleranceDouble = double.Epsilon * 8; - - /// - /// A value specifying the approximation of π which is 180 degrees. - /// - public const float Pi = (float)Math.PI; - - /// - /// A value specifying the approximation of 2π which is 360 degrees. - /// - public const float TwoPi = (float)(2 * Math.PI); - - /// - /// A value specifying the approximation of π/2 which is 90 degrees. - /// - public const float PiOverTwo = (float)(Math.PI / 2); - - /// - /// A value specifying the approximation of π/4 which is 45 degrees. - /// - public const float PiOverFour = (float)(Math.PI / 4); - /* Unsafe and i dont feel like adding it to my build actions yet. - /// - /// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers (unlike method). See Remarks. - /// See remarks. - /// - /// The left value to compare. - /// The right value to compare. - /// true if a almost equal to b, false otherwise - /// - /// The code is using the technique described by Bruce Dawson in - /// Comparing Floating point numbers 2012 edition. - /// - public static unsafe bool NearEqual(float a, float b) - { - // Check if the numbers are really close -- needed - // when comparing numbers near zero. - if (IsZero(a - b)) - return true; - - // Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - int aInt = *(int*)&a; - int bInt = *(int*)&b; - - // Different signs means they do not match. - if ((aInt < 0) != (bInt < 0)) - return false; - - // Find the difference in ULPs. - int ulp = Math.Abs(aInt - bInt); - - // Choose of maxUlp = 4 - // according to http://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h - const int maxUlp = 4; - return (ulp <= maxUlp); - } - */ - /// - /// Determines whether the specified value is close to zero (0.0f). - /// - /// The floating value. - /// true if the specified value is close to zero (0.0f); otherwise, false. - public static bool IsZero(float a) - { - return Math.Abs(a) < ZeroTolerance; - } - - /// - /// Determines whether the specified value is close to zero (0.0f). - /// - /// The floating value. - /// true if the specified value is close to zero (0.0f); otherwise, false. - public static bool IsZero(double a) - { - return Math.Abs(a) < ZeroToleranceDouble; - } - - /// - /// Determines whether the specified value is close to one (1.0f). - /// - /// The floating value. - /// true if the specified value is close to one (1.0f); otherwise, false. - public static bool IsOne(float a) - { - return IsZero(a - 1.0f); - } - - /// - /// Checks if a - b are almost equals within a float epsilon. - /// - /// The left value to compare. - /// The right value to compare. - /// Epsilon value - /// true if a almost equal to b within a float epsilon, false otherwise - public static bool WithinEpsilon(float a, float b, float epsilon) - { - float num = a - b; - return ((-epsilon <= num) && (num <= epsilon)); - } - - /// - /// Creates a one-dimensional array of the specified and filled with the specified . - /// - /// The Type of the array to create. - /// The value to fill the array with. - /// The size of the array to create. - /// A new one-dimensional array of the specified type with the specified length and filled with the specified value. - public static T[] Array(T value, int length) - { - var result = new T[length]; - for (var i = 0; i < length; i++) - result[i] = value; - - return result; - } - - /// - /// Converts revolutions to degrees. - /// - /// The value to convert. - /// The converted value. - public static float RevolutionsToDegrees(float revolution) - { - return revolution * 360.0f; - } - - /// - /// Converts revolutions to radians. - /// - /// The value to convert. - /// The converted value. - public static float RevolutionsToRadians(float revolution) - { - return revolution * TwoPi; - } - - /// - /// Converts revolutions to gradians. - /// - /// The value to convert. - /// The converted value. - public static float RevolutionsToGradians(float revolution) - { - return revolution * 400.0f; - } - - /// - /// Converts degrees to revolutions. - /// - /// The value to convert. - /// The converted value. - public static float DegreesToRevolutions(float degree) - { - return degree / 360.0f; - } - - /// - /// Converts degrees to radians. - /// - /// The value to convert. - /// The converted value. - public static float DegreesToRadians(float degree) - { - return degree * (Pi / 180.0f); - } - - public static Vector3 DegreesToRadians(Vector3 degrees) - { - return new Vector3( - (float)(degrees.X * Math.PI / 180), - (float)(degrees.Y * Math.PI / 180), - (float)(degrees.Z * Math.PI / 180) - ); - } - - /// - /// Converts radians to revolutions. - /// - /// The value to convert. - /// The converted value. - public static float RadiansToRevolutions(float radian) - { - return radian / TwoPi; - } - - /// - /// Converts radians to gradians. - /// - /// The value to convert. - /// The converted value. - public static float RadiansToGradians(float radian) - { - return radian * (200.0f / Pi); - } - - /// - /// Converts gradians to revolutions. - /// - /// The value to convert. - /// The converted value. - public static float GradiansToRevolutions(float gradian) - { - return gradian / 400.0f; - } - - /// - /// Converts gradians to degrees. - /// - /// The value to convert. - /// The converted value. - public static float GradiansToDegrees(float gradian) - { - return gradian * (9.0f / 10.0f); - } - - /// - /// Converts gradians to radians. - /// - /// The value to convert. - /// The converted value. - public static float GradiansToRadians(float gradian) - { - return gradian * (Pi / 200.0f); - } - - /// - /// Converts radians to degrees. - /// - /// The value to convert. - /// The converted value. - public static float RadiansToDegrees(float radian) - { - return radian * (180.0f / Pi); - } - - public static Vector3 RadiansToDegrees(Vector3 radians) - { - return new Vector3( - (float)(radians.X * 180 / Math.PI), - (float)(radians.Y * 180 / Math.PI), - (float)(radians.Z * 180 / Math.PI) - ); - } - - public static Vector3 SumAll(IEnumerable vectors) - { - Vector3 sum = Vector3.Zero; - foreach (var vector in vectors) - { - sum += vector; - } - - return sum; - } - - /// - /// Clamps the specified value. - /// - /// The value. - /// The min. - /// The max. - /// The result of clamping a value between min and max - public static float Clamp(float value, float min, float max) - { - return value < min ? min : value > max ? max : value; - } - - /// - /// Clamps the specified value. - /// - /// The value. - /// The min. - /// The max. - /// The result of clamping a value between min and max - public static double Clamp(double value, double min, double max) - { - return value < min ? min : value > max ? max : value; - } - - /// - /// Clamps the specified value. - /// - /// The value. - /// The min. - /// The max. - /// The result of clamping a value between min and max - public static int Clamp(int value, int min, int max) - { - return value < min ? min : value > max ? max : value; - } - - /// - /// Inverse-interpolates a value linearly. - /// - /// Minimum value that takes place in inverse-interpolation. - /// Maximum value that takes place in inverse-interpolation. - /// Value to get inverse interpolation. - /// Returns an inverse-linearly interpolated coeficient. - public static float InverseLerp(float min, float max, float value) - { - if (IsZero(Math.Abs(max - min))) - return float.NaN; - return (value - min) / (max - min); - } - - /// - /// Inverse-interpolates a value linearly. - /// - /// Minimum value that takes place in inverse-interpolation. - /// Maximum value that takes place in inverse-interpolation. - /// Value to get inverse interpolation. - /// Returns an inverse-linearly interpolated coeficient. - public static double InverseLerp(double min, double max, double value) - { - if (IsZero(Math.Abs(max - min))) - return double.NaN; - return (value - min) / (max - min); - } - - /// - /// Interpolates between two values using a linear function by a given amount. - /// - /// - /// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and - /// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ - /// - /// Value to interpolate from. - /// Value to interpolate to. - /// Interpolation amount. - /// The result of linear interpolation of values based on the amount. - public static double Lerp(double from, double to, double amount) - { - return (1 - amount) * from + amount * to; - } - - /// - /// Interpolates between two values using a linear function by a given amount. - /// - /// - /// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and - /// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ - /// - /// Value to interpolate from. - /// Value to interpolate to. - /// Interpolation amount. - /// The result of linear interpolation of values based on the amount. - public static float Lerp(float from, float to, float amount) - { - return (1 - amount) * from + amount * to; - } - - /// - /// Interpolates between two values using a linear function by a given amount. - /// - /// - /// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and - /// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ - /// - /// Value to interpolate from. - /// Value to interpolate to. - /// Interpolation amount. - /// The result of linear interpolation of values based on the amount. - public static byte Lerp(byte from, byte to, float amount) - { - return (byte)Lerp((float)from, (float)to, amount); - } - - /// - /// Performs smooth (cubic Hermite) interpolation between 0 and 1. - /// - /// - /// See https://en.wikipedia.org/wiki/Smoothstep - /// - /// Value between 0 and 1 indicating interpolation amount. - public static float SmoothStep(float amount) - { - return (amount <= 0) ? 0 - : (amount >= 1) ? 1 - : amount * amount * (3 - (2 * amount)); - } - - /// - /// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints. - /// - /// - /// See https://en.wikipedia.org/wiki/Smoothstep - /// - /// Value between 0 and 1 indicating interpolation amount. - public static float SmootherStep(float amount) - { - return (amount <= 0) ? 0 - : (amount >= 1) ? 1 - : amount * amount * amount * (amount * ((amount * 6) - 15) + 10); - } - - /// - /// Determines whether the value is inside the given range (inclusively). - /// - /// The value. - /// The minimum value of the range. - /// The maximum value of the range. - /// true if value is inside the specified range; otherwise, false. - public static bool IsInRange(float value, float min, float max) - { - return min <= value && value <= max; - } - - /// - /// Determines whether the value is inside the given range (inclusively). - /// - /// The value. - /// The minimum value of the range. - /// The maximum value of the range. - /// true if value is inside the specified range; otherwise, false. - public static bool IsInRange(int value, int min, int max) - { - return min <= value && value <= max; - } - - /// - /// Determines whether the specified x is pow2. - /// - /// The x. - /// true if the specified x is pow2; otherwise, false. - public static bool IsPow2(int x) - { - return ((x != 0) && (x & (x - 1)) == 0); - } - - /// - /// Converts a float value from sRGB to linear. - /// - /// The sRGB value. - /// A linear value. - public static float SRgbToLinear(float sRgbValue) - { - if (sRgbValue < 0.04045f) return sRgbValue / 12.92f; - return (float)Math.Pow((sRgbValue + 0.055) / 1.055, 2.4); - } - - /// - /// Converts a float value from linear to sRGB. - /// - /// The linear value. - /// The encoded sRGB value. - public static float LinearToSRgb(float linearValue) - { - if (linearValue < 0.0031308f) return linearValue * 12.92f; - return (float)(1.055 * Math.Pow(linearValue, 1 / 2.4) - 0.055); - } - - /// - /// Calculate the logarithm 2 of a floating point. - /// - /// The input float - /// Log2(x) - public static float Log2(float x) - { - return MathF.Log(x) / 0.6931471805599453f; - } - - /// - /// Calculate the logarithm 2 of an integer. - /// - /// The input integer - /// the log2(i) rounded to lower integer - public static int Log2(int i) - { - var r = 0; - - while ((i >>= 1) != 0) - ++r; - - return r; - } - - /// - /// Get the next power of two of an integer. - /// - /// The size. - /// System.Int32. - /// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 - public static int NextPowerOfTwo(int x) - { - if (x < 0) - return 0; - - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return x + 1; - } - - /// - /// Get the next power of two for a size. - /// - /// The size. - /// System.Int32. - public static float NextPowerOfTwo(float size) - { - return (float)Math.Pow(2, Math.Ceiling(Math.Log(size, 2))); - } - - /// - /// Get the previous power of two of the provided integer. - /// - /// The value - public static int PreviousPowerOfTwo(int size) - { - return 1 << (int)Math.Floor(Math.Log(size, 2)); - } - - /// - /// Get the previous power of two of the provided float. - /// - /// The value - public static float PreviousPowerOfTwo(float size) - { - return (float)Math.Pow(2, Math.Floor(Math.Log(size, 2))); - } - - /// - /// Alignes value up to match desire alignment. - /// - /// The value. - /// The alignment. - /// Aligned value (multiple of alignment). - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int AlignUp(int value, int alignment) - { - int mask = alignment - 1; - return (value + mask) & ~mask; - } - - /// - /// Alignes value down to match desire alignment. - /// - /// The value. - /// The alignment. - /// Aligned value (multiple of alignment). - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int AlignDown(int value, int alignment) - { - int mask = alignment - 1; - return value & ~mask; - } - - /// - /// Determines whether the specified value is aligned. - /// - /// The value. - /// The alignment. - /// true if the specified value is aligned; otherwise, false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsAligned(int value, int alignment) - { - return (value & (alignment - 1)) == 0; - } - - /// - /// Snaps a value to the nearest interval. - /// - /// The value to snap. - /// The interval gap. - /// The nearest interval to the provided value. - public static float Snap(float value, float gap) - { - if (gap == 0) - return value; - return MathF.Round((value / gap), MidpointRounding.AwayFromZero) * gap; - } - - /// - /// Snaps a value to the nearest interval. - /// - /// The value to snap. - /// The interval gap. - /// The nearest interval to the provided value. - public static double Snap(double value, double gap) - { - if (gap == 0) - return value; - return Math.Round((value / gap), MidpointRounding.AwayFromZero) * gap; - } - - /// - /// Snaps all vector components to the nearest interval. - /// - /// The vector to snap. - /// The interval gap. - /// A vector which components are snapped to the nearest interval. - public static Vector2 Snap(Vector2 value, float gap) - { - if (gap == 0) - return value; - return new Vector2( - MathF.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap); - } - - /// - /// Snaps all vector components to the nearest interval. - /// - /// The vector to snap. - /// The interval gap. - /// A vector which components are snapped to the nearest interval. - public static Vector3 Snap(Vector3 value, float gap) - { - if (gap == 0) - return value; - return new Vector3( - MathF.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.Z / gap), MidpointRounding.AwayFromZero) * gap); - } - - /// - /// Snaps all vector components to the nearest interval. - /// - /// The vector to snap. - /// The interval gap. - /// A vector which components are snapped to the nearest interval. - public static Vector4 Snap(Vector4 value, float gap) - { - if (gap == 0) - return value; - return new Vector4( - MathF.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.Z / gap), MidpointRounding.AwayFromZero) * gap, - MathF.Round((value.W / gap), MidpointRounding.AwayFromZero) * gap); - } - - /// - /// Computes standard mathematical modulo (as opposed to remainder). - /// - /// The value. - /// The divisor. - /// A value between 0 and divisor. The result will have the same sign as divisor. - public static float Mod(float value, float divisor) - { - return ((value % divisor) + divisor) % divisor; - } - - public static Vector3 Projection(Vector3 source, Vector3 direction) - { - return (Vector3.Dot(source, direction) / Vector3.Dot(direction, direction)) * direction; - } -} diff --git a/source/OrkEngine3D.Mathematics/Matrix.cs b/source/OrkEngine3D.Mathematics/Matrix.cs deleted file mode 100644 index faa45fb..0000000 --- a/source/OrkEngine3D.Mathematics/Matrix.cs +++ /dev/null @@ -1,3189 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Globalization; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a 4x4 mathematical matrix. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -[TypeConverter(typeof(Design.MatrixConverter))] -public struct Matrix : IEquatable, IFormattable -{ - /// - /// The size of the type, in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Matrix)); - - /// - /// A with all of its components set to zero. - /// - public static readonly Matrix Zero = new Matrix(); - - /// - /// The identity . - /// - public static readonly Matrix Identity = new Matrix() { M11 = 1.0f, M22 = 1.0f, M33 = 1.0f, M44 = 1.0f }; - - /// - /// Value at row 1 column 1 of the matrix. - /// - public float M11; - - /// - /// Value at row 1 column 2 of the matrix. - /// - public float M12; - - /// - /// Value at row 1 column 3 of the matrix. - /// - public float M13; - - /// - /// Value at row 1 column 4 of the matrix. - /// - public float M14; - - /// - /// Value at row 2 column 1 of the matrix. - /// - public float M21; - - /// - /// Value at row 2 column 2 of the matrix. - /// - public float M22; - - /// - /// Value at row 2 column 3 of the matrix. - /// - public float M23; - - /// - /// Value at row 2 column 4 of the matrix. - /// - public float M24; - - /// - /// Value at row 3 column 1 of the matrix. - /// - public float M31; - - /// - /// Value at row 3 column 2 of the matrix. - /// - public float M32; - - /// - /// Value at row 3 column 3 of the matrix. - /// - public float M33; - - /// - /// Value at row 3 column 4 of the matrix. - /// - public float M34; - - /// - /// Value at row 4 column 1 of the matrix. - /// - public float M41; - - /// - /// Value at row 4 column 2 of the matrix. - /// - public float M42; - - /// - /// Value at row 4 column 3 of the matrix. - /// - public float M43; - - /// - /// Value at row 4 column 4 of the matrix. - /// - public float M44; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Matrix(float value) - { - M11 = M12 = M13 = M14 = - M21 = M22 = M23 = M24 = - M31 = M32 = M33 = M34 = - M41 = M42 = M43 = M44 = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The value to assign at row 1 column 1 of the matrix. - /// The value to assign at row 1 column 2 of the matrix. - /// The value to assign at row 1 column 3 of the matrix. - /// The value to assign at row 1 column 4 of the matrix. - /// The value to assign at row 2 column 1 of the matrix. - /// The value to assign at row 2 column 2 of the matrix. - /// The value to assign at row 2 column 3 of the matrix. - /// The value to assign at row 2 column 4 of the matrix. - /// The value to assign at row 3 column 1 of the matrix. - /// The value to assign at row 3 column 2 of the matrix. - /// The value to assign at row 3 column 3 of the matrix. - /// The value to assign at row 3 column 4 of the matrix. - /// The value to assign at row 4 column 1 of the matrix. - /// The value to assign at row 4 column 2 of the matrix. - /// The value to assign at row 4 column 3 of the matrix. - /// The value to assign at row 4 column 4 of the matrix. - public Matrix(float M11, float M12, float M13, float M14, - float M21, float M22, float M23, float M24, - float M31, float M32, float M33, float M34, - float M41, float M42, float M43, float M44) - { - this.M11 = M11; this.M12 = M12; this.M13 = M13; this.M14 = M14; - this.M21 = M21; this.M22 = M22; this.M23 = M23; this.M24 = M24; - this.M31 = M31; this.M32 = M32; this.M33 = M33; this.M34 = M34; - this.M41 = M41; this.M42 = M42; this.M43 = M43; this.M44 = M44; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the components of the matrix. This must be an array with sixteen elements. - /// Thrown when is null. - /// Thrown when contains more or less than sixteen elements. - public Matrix(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 16) - throw new ArgumentOutOfRangeException("values", "There must be sixteen and only sixteen input values for Matrix."); - - M11 = values[0]; - M12 = values[1]; - M13 = values[2]; - M14 = values[3]; - - M21 = values[4]; - M22 = values[5]; - M23 = values[6]; - M24 = values[7]; - - M31 = values[8]; - M32 = values[9]; - M33 = values[10]; - M34 = values[11]; - - M41 = values[12]; - M42 = values[13]; - M43 = values[14]; - M44 = values[15]; - } - - /// - /// Gets or sets the first row in the matrix; that is M11, M12, M13, and M14. - /// - public Vector4 Row1 - { - get { return new Vector4(M11, M12, M13, M14); } - set { M11 = value.X; M12 = value.Y; M13 = value.Z; M14 = value.W; } - } - - /// - /// Gets or sets the second row in the matrix; that is M21, M22, M23, and M24. - /// - public Vector4 Row2 - { - get { return new Vector4(M21, M22, M23, M24); } - set { M21 = value.X; M22 = value.Y; M23 = value.Z; M24 = value.W; } - } - - /// - /// Gets or sets the third row in the matrix; that is M31, M32, M33, and M34. - /// - public Vector4 Row3 - { - get { return new Vector4(M31, M32, M33, M34); } - set { M31 = value.X; M32 = value.Y; M33 = value.Z; M34 = value.W; } - } - - /// - /// Gets or sets the fourth row in the matrix; that is M41, M42, M43, and M44. - /// - public Vector4 Row4 - { - get { return new Vector4(M41, M42, M43, M44); } - set { M41 = value.X; M42 = value.Y; M43 = value.Z; M44 = value.W; } - } - - /// - /// Gets or sets the first column in the matrix; that is M11, M21, M31, and M41. - /// - public Vector4 Column1 - { - get { return new Vector4(M11, M21, M31, M41); } - set { M11 = value.X; M21 = value.Y; M31 = value.Z; M41 = value.W; } - } - - /// - /// Gets or sets the second column in the matrix; that is M12, M22, M32, and M42. - /// - public Vector4 Column2 - { - get { return new Vector4(M12, M22, M32, M42); } - set { M12 = value.X; M22 = value.Y; M32 = value.Z; M42 = value.W; } - } - - /// - /// Gets or sets the third column in the matrix; that is M13, M23, M33, and M43. - /// - public Vector4 Column3 - { - get { return new Vector4(M13, M23, M33, M43); } - set { M13 = value.X; M23 = value.Y; M33 = value.Z; M43 = value.W; } - } - - /// - /// Gets or sets the fourth column in the matrix; that is M14, M24, M34, and M44. - /// - public Vector4 Column4 - { - get { return new Vector4(M14, M24, M34, M44); } - set { M14 = value.X; M24 = value.Y; M34 = value.Z; M44 = value.W; } - } - - /// - /// Gets or sets the translation of the matrix; that is M41, M42, and M43. - /// - public Vector3 TranslationVector - { - get { return new Vector3(M41, M42, M43); } - set { M41 = value.X; M42 = value.Y; M43 = value.Z; } - } - - /// - /// Gets or sets the scale of the matrix; that is M11, M22, and M33. - /// - public Vector3 ScaleVector - { - get { return new Vector3(M11, M22, M33); } - set { M11 = value.X; M22 = value.Y; M33 = value.Z; } - } - - /// - /// Gets a value indicating whether this instance is an identity matrix. - /// - /// - /// true if this instance is an identity matrix; otherwise, false. - /// - public bool IsIdentity - { - get { return this.Equals(Identity); } - } - - /// - /// Calculates the determinant of the matrix. - /// - /// The determinant of the matrix. - public float Determinant - { - get - { - float temp1 = (M33 * M44) - (M34 * M43); - float temp2 = (M32 * M44) - (M34 * M42); - float temp3 = (M32 * M43) - (M33 * M42); - float temp4 = (M31 * M44) - (M34 * M41); - float temp5 = (M31 * M43) - (M33 * M41); - float temp6 = (M31 * M42) - (M32 * M41); - - return ((((M11 * (((M22 * temp1) - (M23 * temp2)) + (M24 * temp3))) - (M12 * (((M21 * temp1) - - (M23 * temp4)) + (M24 * temp5)))) + (M13 * (((M21 * temp2) - (M22 * temp4)) + (M24 * temp6)))) - - (M14 * (((M21 * temp3) - (M22 * temp5)) + (M23 * temp6)))); - } - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the matrix component, depending on the index. - /// The zero-based index of the component to access. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 15]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return M11; - case 1: return M12; - case 2: return M13; - case 3: return M14; - case 4: return M21; - case 5: return M22; - case 6: return M23; - case 7: return M24; - case 8: return M31; - case 9: return M32; - case 10: return M33; - case 11: return M34; - case 12: return M41; - case 13: return M42; - case 14: return M43; - case 15: return M44; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Matrix run from 0 to 15, inclusive."); - } - - set - { - switch (index) - { - case 0: M11 = value; break; - case 1: M12 = value; break; - case 2: M13 = value; break; - case 3: M14 = value; break; - case 4: M21 = value; break; - case 5: M22 = value; break; - case 6: M23 = value; break; - case 7: M24 = value; break; - case 8: M31 = value; break; - case 9: M32 = value; break; - case 10: M33 = value; break; - case 11: M34 = value; break; - case 12: M41 = value; break; - case 13: M42 = value; break; - case 14: M43 = value; break; - case 15: M44 = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Matrix run from 0 to 15, inclusive."); - } - } - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the matrix component, depending on the index. - /// The row of the matrix to access. - /// The column of the matrix to access. - /// The value of the component at the specified index. - /// Thrown when the or is out of the range [0, 3]. - public float this[int row, int column] - { - get - { - if (row < 0 || row > 3) - throw new ArgumentOutOfRangeException("row", "Rows and columns for matrices run from 0 to 3, inclusive."); - if (column < 0 || column > 3) - throw new ArgumentOutOfRangeException("column", "Rows and columns for matrices run from 0 to 3, inclusive."); - - return this[(row * 4) + column]; - } - - set - { - if (row < 0 || row > 3) - throw new ArgumentOutOfRangeException("row", "Rows and columns for matrices run from 0 to 3, inclusive."); - if (column < 0 || column > 3) - throw new ArgumentOutOfRangeException("column", "Rows and columns for matrices run from 0 to 3, inclusive."); - - this[(row * 4) + column] = value; - } - } - - /// - /// Negates a matrix. - /// - public void Negate() - { - Negate(ref this, out this); - } - - /// - /// Inverts the matrix. - /// - public void Invert() - { - Invert(ref this, out this); - } - - /// - /// Transposes the matrix. - /// - public void Transpose() - { - Transpose(ref this, out this); - } - - /// - /// Performs the exponential operation on a matrix. - /// - /// The exponent to raise the matrix to. - /// Thrown when the is negative. - public void Exponent(int exponent) - { - Exponent(ref this, exponent, out this); - } - - /// - /// Orthogonalizes the specified matrix. - /// - /// - /// Orthogonalization is the process of making all rows orthogonal to each other. This - /// means that any given row in the matrix will be orthogonal to any other given row in the - /// matrix. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public void Orthogonalize() - { - Orthogonalize(ref this, out this); - } - - /// - /// Orthonormalizes the specified matrix. - /// - /// - /// Orthonormalization is the process of making all rows and columns orthogonal to each - /// other and making all rows and columns of unit length. This means that any given row will - /// be orthogonal to any other given row and any given column will be orthogonal to any other - /// given column. Any given row will not be orthogonal to any given column. Every row and every - /// column will be of unit length. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public void Orthonormalize() - { - Orthonormalize(ref this, out this); - } - - /// - /// Decomposes a matrix into an orthonormalized matrix Q and a right traingular matrix R. - /// - /// When the method completes, contains the orthonormalized matrix of the decomposition. - /// When the method completes, contains the right triangular matrix of the decomposition. - public void DecomposeQR(out Matrix Q, out Matrix R) - { - Matrix temp = this; - temp.Transpose(); - Orthonormalize(ref temp, out Q); - Q.Transpose(); - - R = new Matrix(); - R.M11 = Vector4.Dot(Q.Column1, Column1); - R.M12 = Vector4.Dot(Q.Column1, Column2); - R.M13 = Vector4.Dot(Q.Column1, Column3); - R.M14 = Vector4.Dot(Q.Column1, Column4); - - R.M22 = Vector4.Dot(Q.Column2, Column2); - R.M23 = Vector4.Dot(Q.Column2, Column3); - R.M24 = Vector4.Dot(Q.Column2, Column4); - - R.M33 = Vector4.Dot(Q.Column3, Column3); - R.M34 = Vector4.Dot(Q.Column3, Column4); - - R.M44 = Vector4.Dot(Q.Column4, Column4); - } - - /// - /// Decomposes a matrix into a lower triangular matrix L and an orthonormalized matrix Q. - /// - /// When the method completes, contains the lower triangular matrix of the decomposition. - /// When the method completes, contains the orthonormalized matrix of the decomposition. - public void DecomposeLQ(out Matrix L, out Matrix Q) - { - Orthonormalize(ref this, out Q); - - L = new Matrix(); - L.M11 = Vector4.Dot(Q.Row1, Row1); - - L.M21 = Vector4.Dot(Q.Row1, Row2); - L.M22 = Vector4.Dot(Q.Row2, Row2); - - L.M31 = Vector4.Dot(Q.Row1, Row3); - L.M32 = Vector4.Dot(Q.Row2, Row3); - L.M33 = Vector4.Dot(Q.Row3, Row3); - - L.M41 = Vector4.Dot(Q.Row1, Row4); - L.M42 = Vector4.Dot(Q.Row2, Row4); - L.M43 = Vector4.Dot(Q.Row3, Row4); - L.M44 = Vector4.Dot(Q.Row4, Row4); - } - - /// - /// Decomposes a matrix into a scale, rotation, and translation. - /// - /// When the method completes, contains the scaling component of the decomposed matrix. - /// When the method completes, contains the rtoation component of the decomposed matrix. - /// When the method completes, contains the translation component of the decomposed matrix. - /// - /// This method is designed to decompose an SRT transformation matrix only. - /// - public bool Decompose(out Vector3 scale, out Quaternion rotation, out Vector3 translation) - { - //Source: Unknown - //References: http://www.gamedev.net/community/forums/topic.asp?topic_id=441695 - - //Get the translation. - translation.X = this.M41; - translation.Y = this.M42; - translation.Z = this.M43; - - //Scaling is the length of the rows. - scale.X = (float)Math.Sqrt((M11 * M11) + (M12 * M12) + (M13 * M13)); - scale.Y = (float)Math.Sqrt((M21 * M21) + (M22 * M22) + (M23 * M23)); - scale.Z = (float)Math.Sqrt((M31 * M31) + (M32 * M32) + (M33 * M33)); - - //If any of the scaling factors are zero, than the rotation matrix can not exist. - if (Math.Abs(scale.X) < Utilities.ZeroTolerance || - Math.Abs(scale.Y) < Utilities.ZeroTolerance || - Math.Abs(scale.Z) < Utilities.ZeroTolerance) - { - rotation = Quaternion.Identity; - return false; - } - - //The rotation is the left over matrix after dividing out the scaling. - Matrix rotationmatrix = new Matrix(); - rotationmatrix.M11 = M11 / scale.X; - rotationmatrix.M12 = M12 / scale.X; - rotationmatrix.M13 = M13 / scale.X; - - rotationmatrix.M21 = M21 / scale.Y; - rotationmatrix.M22 = M22 / scale.Y; - rotationmatrix.M23 = M23 / scale.Y; - - rotationmatrix.M31 = M31 / scale.Z; - rotationmatrix.M32 = M32 / scale.Z; - rotationmatrix.M33 = M33 / scale.Z; - - rotationmatrix.M44 = 1f; - - Quaternion.RotationMatrix(ref rotationmatrix, out rotation); - return true; - } - - /// - /// Exchanges two rows in the matrix. - /// - /// The first row to exchange. This is an index of the row starting at zero. - /// The second row to exchange. This is an index of the row starting at zero. - public void ExchangeRows(int firstRow, int secondRow) - { - if (firstRow < 0) - throw new ArgumentOutOfRangeException("firstRow", "The parameter firstRow must be greater than or equal to zero."); - if (firstRow > 3) - throw new ArgumentOutOfRangeException("firstRow", "The parameter firstRow must be less than or equal to three."); - if (secondRow < 0) - throw new ArgumentOutOfRangeException("secondRow", "The parameter secondRow must be greater than or equal to zero."); - if (secondRow > 3) - throw new ArgumentOutOfRangeException("secondRow", "The parameter secondRow must be less than or equal to three."); - - if (firstRow == secondRow) - return; - - float temp0 = this[secondRow, 0]; - float temp1 = this[secondRow, 1]; - float temp2 = this[secondRow, 2]; - float temp3 = this[secondRow, 3]; - - this[secondRow, 0] = this[firstRow, 0]; - this[secondRow, 1] = this[firstRow, 1]; - this[secondRow, 2] = this[firstRow, 2]; - this[secondRow, 3] = this[firstRow, 3]; - - this[firstRow, 0] = temp0; - this[firstRow, 1] = temp1; - this[firstRow, 2] = temp2; - this[firstRow, 3] = temp3; - } - - /// - /// - /// - /// - /// - public void ExchangeColumns(int firstColumn, int secondColumn) - { - if (firstColumn < 0) - throw new ArgumentOutOfRangeException("firstColumn", "The parameter firstColumn must be greater than or equal to zero."); - if (firstColumn > 3) - throw new ArgumentOutOfRangeException("firstColumn", "The parameter firstColumn must be less than or equal to three."); - if (secondColumn < 0) - throw new ArgumentOutOfRangeException("secondColumn", "The parameter secondColumn must be greater than or equal to zero."); - if (secondColumn > 3) - throw new ArgumentOutOfRangeException("secondColumn", "The parameter secondColumn must be less than or equal to three."); - - if (firstColumn == secondColumn) - return; - - float temp0 = this[0, secondColumn]; - float temp1 = this[1, secondColumn]; - float temp2 = this[2, secondColumn]; - float temp3 = this[3, secondColumn]; - - this[0, secondColumn] = this[0, firstColumn]; - this[1, secondColumn] = this[1, firstColumn]; - this[2, secondColumn] = this[2, firstColumn]; - this[3, secondColumn] = this[3, firstColumn]; - - this[0, firstColumn] = temp0; - this[1, firstColumn] = temp1; - this[2, firstColumn] = temp2; - this[3, firstColumn] = temp3; - } - - /// - /// Creates an array containing the elements of the matrix. - /// - /// A sixteen-element array containing the components of the matrix. - public float[] ToArray() - { - return new[] { M11, M12, M13, M14, M21, M22, M23, M24, M31, M32, M33, M34, M41, M42, M43, M44 }; - } - - /// - /// Determines the sum of two matrices. - /// - /// The first matrix to add. - /// The second matrix to add. - /// When the method completes, contains the sum of the two matrices. - public static void Add(ref Matrix left, ref Matrix right, out Matrix result) - { - result.M11 = left.M11 + right.M11; - result.M12 = left.M12 + right.M12; - result.M13 = left.M13 + right.M13; - result.M14 = left.M14 + right.M14; - result.M21 = left.M21 + right.M21; - result.M22 = left.M22 + right.M22; - result.M23 = left.M23 + right.M23; - result.M24 = left.M24 + right.M24; - result.M31 = left.M31 + right.M31; - result.M32 = left.M32 + right.M32; - result.M33 = left.M33 + right.M33; - result.M34 = left.M34 + right.M34; - result.M41 = left.M41 + right.M41; - result.M42 = left.M42 + right.M42; - result.M43 = left.M43 + right.M43; - result.M44 = left.M44 + right.M44; - } - - /// - /// Determines the sum of two matrices. - /// - /// The first matrix to add. - /// The second matrix to add. - /// The sum of the two matrices. - public static Matrix Add(Matrix left, Matrix right) - { - Matrix result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Determines the difference between two matrices. - /// - /// The first matrix to subtract. - /// The second matrix to subtract. - /// When the method completes, contains the difference between the two matrices. - public static void Subtract(ref Matrix left, ref Matrix right, out Matrix result) - { - result.M11 = left.M11 - right.M11; - result.M12 = left.M12 - right.M12; - result.M13 = left.M13 - right.M13; - result.M14 = left.M14 - right.M14; - result.M21 = left.M21 - right.M21; - result.M22 = left.M22 - right.M22; - result.M23 = left.M23 - right.M23; - result.M24 = left.M24 - right.M24; - result.M31 = left.M31 - right.M31; - result.M32 = left.M32 - right.M32; - result.M33 = left.M33 - right.M33; - result.M34 = left.M34 - right.M34; - result.M41 = left.M41 - right.M41; - result.M42 = left.M42 - right.M42; - result.M43 = left.M43 - right.M43; - result.M44 = left.M44 - right.M44; - } - - /// - /// Determines the difference between two matrices. - /// - /// The first matrix to subtract. - /// The second matrix to subtract. - /// The difference between the two matrices. - public static Matrix Subtract(Matrix left, Matrix right) - { - Matrix result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Scales a matrix by the given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled matrix. - public static void Multiply(ref Matrix left, float scalar, out Matrix result) - { - result.M11 = left.M11 * scalar; - result.M12 = left.M12 * scalar; - result.M13 = left.M13 * scalar; - result.M14 = left.M14 * scalar; - result.M21 = left.M21 * scalar; - result.M22 = left.M22 * scalar; - result.M23 = left.M23 * scalar; - result.M24 = left.M24 * scalar; - result.M31 = left.M31 * scalar; - result.M32 = left.M32 * scalar; - result.M33 = left.M33 * scalar; - result.M34 = left.M34 * scalar; - result.M41 = left.M41 * scalar; - result.M42 = left.M42 * scalar; - result.M43 = left.M43 * scalar; - result.M44 = left.M44 * scalar; - } - - /// - /// Scales a matrix by the given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// The scaled matrix. - public static Matrix Multiply(Matrix left, float scalar) - { - Matrix result; - Multiply(ref left, scalar, out result); - return result; - } - - /// - /// Determines the product of two matrices. - /// - /// The first matrix to multiply. - /// The second matrix to multiply. - /// The product of the two matrices. - public static void Multiply(ref Matrix left, ref Matrix right, out Matrix result) - { - result = new Matrix(); - 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); - } - - /// - /// Determines the product of two matrices. - /// - /// The first matrix to multiply. - /// The second matrix to multiply. - /// The product of the two matrices. - public static Matrix Multiply(Matrix left, Matrix right) - { - Matrix result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Scales a matrix by the given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled matrix. - public static void Divide(ref Matrix left, float scalar, out Matrix result) - { - float inv = 1.0f / scalar; - - result.M11 = left.M11 * inv; - result.M12 = left.M12 * inv; - result.M13 = left.M13 * inv; - result.M14 = left.M14 * inv; - result.M21 = left.M21 * inv; - result.M22 = left.M22 * inv; - result.M23 = left.M23 * inv; - result.M24 = left.M24 * inv; - result.M31 = left.M31 * inv; - result.M32 = left.M32 * inv; - result.M33 = left.M33 * inv; - result.M34 = left.M34 * inv; - result.M41 = left.M41 * inv; - result.M42 = left.M42 * inv; - result.M43 = left.M43 * inv; - result.M44 = left.M44 * inv; - } - - /// - /// Scales a matrix by the given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// The scaled matrix. - public static Matrix Divide(Matrix left, float scalar) - { - Matrix result; - Divide(ref left, scalar, out result); - return result; - } - - /// - /// Determines the quotient of two matrices. - /// - /// The first matrix to divide. - /// The second matrix to divide. - /// When the method completes, contains the quotient of the two matrices. - public static void Divide(ref Matrix left, ref Matrix right, out Matrix result) - { - result.M11 = left.M11 / right.M11; - result.M12 = left.M12 / right.M12; - result.M13 = left.M13 / right.M13; - result.M14 = left.M14 / right.M14; - result.M21 = left.M21 / right.M21; - result.M22 = left.M22 / right.M22; - result.M23 = left.M23 / right.M23; - result.M24 = left.M24 / right.M24; - result.M31 = left.M31 / right.M31; - result.M32 = left.M32 / right.M32; - result.M33 = left.M33 / right.M33; - result.M34 = left.M34 / right.M34; - result.M41 = left.M41 / right.M41; - result.M42 = left.M42 / right.M42; - result.M43 = left.M43 / right.M43; - result.M44 = left.M44 / right.M44; - } - - /// - /// Determines the quotient of two matrices. - /// - /// The first matrix to divide. - /// The second matrix to divide. - /// The quotient of the two matrices. - public static Matrix Divide(Matrix left, Matrix right) - { - Matrix result; - Divide(ref left, ref right, out result); - return result; - } - - /// - /// Performs the exponential operation on a matrix. - /// - /// The matrix to perform the operation on. - /// The exponent to raise the matrix to. - /// When the method completes, contains the exponential matrix. - /// Thrown when the is negative. - public static void Exponent(ref Matrix value, int exponent, out Matrix result) - { - //Source: http://rosettacode.org - //Refrence: http://rosettacode.org/wiki/Matrix-exponentiation_operator - - if (exponent < 0) - throw new ArgumentOutOfRangeException("exponent", "The exponent can not be negative."); - - if (exponent == 0) - { - result = Matrix.Identity; - return; - } - - if (exponent == 1) - { - result = value; - return; - } - - Matrix identity = Matrix.Identity; - Matrix temp = value; - - while (true) - { - if ((exponent & 1) != 0) - identity = identity * temp; - - exponent /= 2; - - if (exponent > 0) - temp *= temp; - else - break; - } - - result = identity; - } - - /// - /// Performs the exponential operation on a matrix. - /// - /// The matrix to perform the operation on. - /// The exponent to raise the matrix to. - /// The exponential matrix. - /// Thrown when the is negative. - public static Matrix Exponent(Matrix value, int exponent) - { - Matrix result; - Exponent(ref value, exponent, out result); - return result; - } - - /// - /// Negates a matrix. - /// - /// The matrix to be negated. - /// When the method completes, contains the negated matrix. - public static void Negate(ref Matrix value, out Matrix result) - { - result.M11 = -value.M11; - result.M12 = -value.M12; - result.M13 = -value.M13; - result.M14 = -value.M14; - result.M21 = -value.M21; - result.M22 = -value.M22; - result.M23 = -value.M23; - result.M24 = -value.M24; - result.M31 = -value.M31; - result.M32 = -value.M32; - result.M33 = -value.M33; - result.M34 = -value.M34; - result.M41 = -value.M41; - result.M42 = -value.M42; - result.M43 = -value.M43; - result.M44 = -value.M44; - } - - /// - /// Negates a matrix. - /// - /// The matrix to be negated. - /// The negated matrix. - public static Matrix Negate(Matrix value) - { - Matrix result; - Negate(ref value, out result); - return result; - } - - /// - /// Performs a linear interpolation between two matricies. - /// - /// Start matrix. - /// End matrix. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two matricies. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Matrix start, ref Matrix end, float amount, out Matrix result) - { - result.M11 = start.M11 + ((end.M11 - start.M11) * amount); - result.M12 = start.M12 + ((end.M12 - start.M12) * amount); - result.M13 = start.M13 + ((end.M13 - start.M13) * amount); - result.M14 = start.M14 + ((end.M14 - start.M14) * amount); - result.M21 = start.M21 + ((end.M21 - start.M21) * amount); - result.M22 = start.M22 + ((end.M22 - start.M22) * amount); - result.M23 = start.M23 + ((end.M23 - start.M23) * amount); - result.M24 = start.M24 + ((end.M24 - start.M24) * amount); - result.M31 = start.M31 + ((end.M31 - start.M31) * amount); - result.M32 = start.M32 + ((end.M32 - start.M32) * amount); - result.M33 = start.M33 + ((end.M33 - start.M33) * amount); - result.M34 = start.M34 + ((end.M34 - start.M34) * amount); - result.M41 = start.M41 + ((end.M41 - start.M41) * amount); - result.M42 = start.M42 + ((end.M42 - start.M42) * amount); - result.M43 = start.M43 + ((end.M43 - start.M43) * amount); - result.M44 = start.M44 + ((end.M44 - start.M44) * amount); - } - - /// - /// Performs a linear interpolation between two matricies. - /// - /// Start matrix. - /// End matrix. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two matrices. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Matrix Lerp(Matrix start, Matrix end, float amount) - { - Matrix result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Performs a cubic interpolation between two matricies. - /// - /// Start matrix. - /// End matrix. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two matrices. - public static void SmoothStep(ref Matrix start, ref Matrix end, float amount, out Matrix result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.M11 = start.M11 + ((end.M11 - start.M11) * amount); - result.M12 = start.M12 + ((end.M12 - start.M12) * amount); - result.M13 = start.M13 + ((end.M13 - start.M13) * amount); - result.M14 = start.M14 + ((end.M14 - start.M14) * amount); - result.M21 = start.M21 + ((end.M21 - start.M21) * amount); - result.M22 = start.M22 + ((end.M22 - start.M22) * amount); - result.M23 = start.M23 + ((end.M23 - start.M23) * amount); - result.M24 = start.M24 + ((end.M24 - start.M24) * amount); - result.M31 = start.M31 + ((end.M31 - start.M31) * amount); - result.M32 = start.M32 + ((end.M32 - start.M32) * amount); - result.M33 = start.M33 + ((end.M33 - start.M33) * amount); - result.M34 = start.M34 + ((end.M34 - start.M34) * amount); - result.M41 = start.M41 + ((end.M41 - start.M41) * amount); - result.M42 = start.M42 + ((end.M42 - start.M42) * amount); - result.M43 = start.M43 + ((end.M43 - start.M43) * amount); - result.M44 = start.M44 + ((end.M44 - start.M44) * amount); - } - - /// - /// Performs a cubic interpolation between two matrices. - /// - /// Start matrix. - /// End matrix. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two matrices. - public static Matrix SmoothStep(Matrix start, Matrix end, float amount) - { - Matrix result; - SmoothStep(ref start, ref end, amount, out result); - return result; - } - - /// - /// Calculates the transpose of the specified matrix. - /// - /// The matrix whose transpose is to be calculated. - /// When the method completes, contains the transpose of the specified matrix. - public static void Transpose(ref Matrix value, out Matrix result) - { - Matrix temp = new Matrix(); - temp.M11 = value.M11; - temp.M12 = value.M21; - temp.M13 = value.M31; - temp.M14 = value.M41; - temp.M21 = value.M12; - temp.M22 = value.M22; - temp.M23 = value.M32; - temp.M24 = value.M42; - temp.M31 = value.M13; - temp.M32 = value.M23; - temp.M33 = value.M33; - temp.M34 = value.M43; - temp.M41 = value.M14; - temp.M42 = value.M24; - temp.M43 = value.M34; - temp.M44 = value.M44; - - result = temp; - } - - /// - /// Calculates the transpose of the specified matrix. - /// - /// The matrix whose transpose is to be calculated. - /// The transpose of the specified matrix. - public static Matrix Transpose(Matrix value) - { - Matrix result; - Transpose(ref value, out result); - return result; - } - - /// - /// Calculates the inverse of the specified matrix. - /// - /// The matrix whose inverse is to be calculated. - /// When the method completes, contains the inverse of the specified matrix. - public static void Invert(ref Matrix value, out Matrix result) - { - float b0 = (value.M31 * value.M42) - (value.M32 * value.M41); - float b1 = (value.M31 * value.M43) - (value.M33 * value.M41); - float b2 = (value.M34 * value.M41) - (value.M31 * value.M44); - float b3 = (value.M32 * value.M43) - (value.M33 * value.M42); - float b4 = (value.M34 * value.M42) - (value.M32 * value.M44); - float b5 = (value.M33 * value.M44) - (value.M34 * value.M43); - - float d11 = value.M22 * b5 + value.M23 * b4 + value.M24 * b3; - float d12 = value.M21 * b5 + value.M23 * b2 + value.M24 * b1; - float d13 = value.M21 * -b4 + value.M22 * b2 + value.M24 * b0; - float d14 = value.M21 * b3 + value.M22 * -b1 + value.M23 * b0; - - float det = value.M11 * d11 - value.M12 * d12 + value.M13 * d13 - value.M14 * d14; - if (Math.Abs(det) <= Utilities.ZeroTolerance) - { - result = Matrix.Zero; - return; - } - - det = 1f / det; - - float a0 = (value.M11 * value.M22) - (value.M12 * value.M21); - float a1 = (value.M11 * value.M23) - (value.M13 * value.M21); - float a2 = (value.M14 * value.M21) - (value.M11 * value.M24); - float a3 = (value.M12 * value.M23) - (value.M13 * value.M22); - float a4 = (value.M14 * value.M22) - (value.M12 * value.M24); - float a5 = (value.M13 * value.M24) - (value.M14 * value.M23); - - float d21 = value.M12 * b5 + value.M13 * b4 + value.M14 * b3; - float d22 = value.M11 * b5 + value.M13 * b2 + value.M14 * b1; - float d23 = value.M11 * -b4 + value.M12 * b2 + value.M14 * b0; - float d24 = value.M11 * b3 + value.M12 * -b1 + value.M13 * b0; - - float d31 = value.M42 * a5 + value.M43 * a4 + value.M44 * a3; - float d32 = value.M41 * a5 + value.M43 * a2 + value.M44 * a1; - float d33 = value.M41 * -a4 + value.M42 * a2 + value.M44 * a0; - float d34 = value.M41 * a3 + value.M42 * -a1 + value.M43 * a0; - - float d41 = value.M32 * a5 + value.M33 * a4 + value.M34 * a3; - float d42 = value.M31 * a5 + value.M33 * a2 + value.M34 * a1; - float d43 = value.M31 * -a4 + value.M32 * a2 + value.M34 * a0; - float d44 = value.M31 * a3 + value.M32 * -a1 + value.M33 * a0; - - result.M11 = +d11 * det; result.M12 = -d21 * det; result.M13 = +d31 * det; result.M14 = -d41 * det; - result.M21 = -d12 * det; result.M22 = +d22 * det; result.M23 = -d32 * det; result.M24 = +d42 * det; - result.M31 = +d13 * det; result.M32 = -d23 * det; result.M33 = +d33 * det; result.M34 = -d43 * det; - result.M41 = -d14 * det; result.M42 = +d24 * det; result.M43 = -d34 * det; result.M44 = +d44 * det; - } - - /// - /// Calculates the inverse of the specified matrix. - /// - /// The matrix whose inverse is to be calculated. - /// The inverse of the specified matrix. - public static Matrix Invert(Matrix value) - { - value.Invert(); - return value; - } - - /// - /// Orthogonalizes the specified matrix. - /// - /// The matrix to orthogonalize. - /// When the method completes, contains the orthogonalized matrix. - /// - /// Orthogonalization is the process of making all rows orthogonal to each other. This - /// means that any given row in the matrix will be orthogonal to any other given row in the - /// matrix. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public static void Orthogonalize(ref Matrix value, out Matrix result) - { - //Uses the modified Gram-Schmidt process. - //q1 = m1 - //q2 = m2 - ((q1 ⋅ m2) / (q1 ⋅ q1)) * q1 - //q3 = m3 - ((q1 ⋅ m3) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m3) / (q2 ⋅ q2)) * q2 - //q4 = m4 - ((q1 ⋅ m4) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m4) / (q2 ⋅ q2)) * q2 - ((q3 ⋅ m4) / (q3 ⋅ q3)) * q3 - - //By separating the above algorithm into multiple lines, we actually increase accuracy. - result = value; - - result.Row2 = result.Row2 - (Vector4.Dot(result.Row1, result.Row2) / Vector4.Dot(result.Row1, result.Row1)) * result.Row1; - - result.Row3 = result.Row3 - (Vector4.Dot(result.Row1, result.Row3) / Vector4.Dot(result.Row1, result.Row1)) * result.Row1; - result.Row3 = result.Row3 - (Vector4.Dot(result.Row2, result.Row3) / Vector4.Dot(result.Row2, result.Row2)) * result.Row2; - - result.Row4 = result.Row4 - (Vector4.Dot(result.Row1, result.Row4) / Vector4.Dot(result.Row1, result.Row1)) * result.Row1; - result.Row4 = result.Row4 - (Vector4.Dot(result.Row2, result.Row4) / Vector4.Dot(result.Row2, result.Row2)) * result.Row2; - result.Row4 = result.Row4 - (Vector4.Dot(result.Row3, result.Row4) / Vector4.Dot(result.Row3, result.Row3)) * result.Row3; - } - - /// - /// Orthogonalizes the specified matrix. - /// - /// The matrix to orthogonalize. - /// The orthogonalized matrix. - /// - /// Orthogonalization is the process of making all rows orthogonal to each other. This - /// means that any given row in the matrix will be orthogonal to any other given row in the - /// matrix. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public static Matrix Orthogonalize(Matrix value) - { - Matrix result; - Orthogonalize(ref value, out result); - return result; - } - - /// - /// Orthonormalizes the specified matrix. - /// - /// The matrix to orthonormalize. - /// When the method completes, contains the orthonormalized matrix. - /// - /// Orthonormalization is the process of making all rows and columns orthogonal to each - /// other and making all rows and columns of unit length. This means that any given row will - /// be orthogonal to any other given row and any given column will be orthogonal to any other - /// given column. Any given row will not be orthogonal to any given column. Every row and every - /// column will be of unit length. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public static void Orthonormalize(ref Matrix value, out Matrix result) - { - //Uses the modified Gram-Schmidt process. - //Because we are making unit vectors, we can optimize the math for orthogonalization - //and simplify the projection operation to remove the division. - //q1 = m1 / |m1| - //q2 = (m2 - (q1 ⋅ m2) * q1) / |m2 - (q1 ⋅ m2) * q1| - //q3 = (m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2) / |m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2| - //q4 = (m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3) / |m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3| - - //By separating the above algorithm into multiple lines, we actually increase accuracy. - result = value; - - result.Row1 = Vector4.Normalize(result.Row1); - - result.Row2 = result.Row2 - Vector4.Dot(result.Row1, result.Row2) * result.Row1; - result.Row2 = Vector4.Normalize(result.Row2); - - result.Row3 = result.Row3 - Vector4.Dot(result.Row1, result.Row3) * result.Row1; - result.Row3 = result.Row3 - Vector4.Dot(result.Row2, result.Row3) * result.Row2; - result.Row3 = Vector4.Normalize(result.Row3); - - result.Row4 = result.Row4 - Vector4.Dot(result.Row1, result.Row4) * result.Row1; - result.Row4 = result.Row4 - Vector4.Dot(result.Row2, result.Row4) * result.Row2; - result.Row4 = result.Row4 - Vector4.Dot(result.Row3, result.Row4) * result.Row3; - result.Row4 = Vector4.Normalize(result.Row4); - } - - /// - /// Orthonormalizes the specified matrix. - /// - /// The matrix to orthonormalize. - /// The orthonormalized matrix. - /// - /// Orthonormalization is the process of making all rows and columns orthogonal to each - /// other and making all rows and columns of unit length. This means that any given row will - /// be orthogonal to any other given row and any given column will be orthogonal to any other - /// given column. Any given row will not be orthogonal to any given column. Every row and every - /// column will be of unit length. - /// Because this method uses the modified Gram-Schmidt process, the resulting matrix - /// tends to be numerically unstable. The numeric stability decreases according to the rows - /// so that the first row is the most stable and the last row is the least stable. - /// This operation is performed on the rows of the matrix rather than the columns. - /// If you wish for this operation to be performed on the columns, first transpose the - /// input and than transpose the output. - /// - public static Matrix Orthonormalize(Matrix value) - { - Matrix result; - Orthonormalize(ref value, out result); - return result; - } - - /// - /// Brings the matrix into upper triangular form using elementry row operations. - /// - /// The matrix to put into upper triangular form. - /// When the method completes, contains the upper triangular matrix. - /// - /// If the matrix is not invertable (i.e. its determinant is zero) than the result of this - /// method may produce Single.Nan and Single.Inf values. When the matrix represents a system - /// of linear equations, than this often means that either no solution exists or an infinite - /// number of solutions exist. - /// - public static void UpperTriangularForm(ref Matrix value, out Matrix result) - { - //Adapted from the row echelon code - result = value; - int lead = 0; - int rowcount = 4; - int columncount = 4; - - for (int r = 0; r < rowcount; ++r) - { - if (columncount <= lead) - return; - - int i = r; - - while (Math.Abs(result[i, lead]) < Utilities.ZeroTolerance) - { - i++; - - if (i == rowcount) - { - i = r; - lead++; - - if (lead == columncount) - return; - } - } - - if (i != r) - { - result.ExchangeRows(i, r); - } - - float multiplier = 1f / result[r, lead]; - - for (; i < rowcount; ++i) - { - if (i != r) - { - result[i, 0] -= result[r, 0] * multiplier * result[i, lead]; - result[i, 1] -= result[r, 1] * multiplier * result[i, lead]; - result[i, 2] -= result[r, 2] * multiplier * result[i, lead]; - result[i, 3] -= result[r, 3] * multiplier * result[i, lead]; - } - } - - lead++; - } - } - - /// - /// Brings the matrix into upper triangular form using elementry row operations. - /// - /// The matrix to put into upper triangular form. - /// The upper triangular matrix. - /// - /// If the matrix is not invertable (i.e. its determinant is zero) than the result of this - /// method may produce Single.Nan and Single.Inf values. When the matrix represents a system - /// of linear equations, than this often means that either no solution exists or an infinite - /// number of solutions exist. - /// - public static Matrix UpperTriangularForm(Matrix value) - { - Matrix result; - UpperTriangularForm(ref value, out result); - return result; - } - - /// - /// Brings the matrix into lower triangular form using elementry row operations. - /// - /// The matrix to put into lower triangular form. - /// When the method completes, contains the lower triangular matrix. - /// - /// If the matrix is not invertable (i.e. its determinant is zero) than the result of this - /// method may produce Single.Nan and Single.Inf values. When the matrix represents a system - /// of linear equations, than this often means that either no solution exists or an infinite - /// number of solutions exist. - /// - public static void LowerTriangularForm(ref Matrix value, out Matrix result) - { - //Adapted from the row echelon code - Matrix temp = value; - Matrix.Transpose(ref temp, out result); - - int lead = 0; - int rowcount = 4; - int columncount = 4; - - for (int r = 0; r < rowcount; ++r) - { - if (columncount <= lead) - return; - - int i = r; - - while (Math.Abs(result[i, lead]) < Utilities.ZeroTolerance) - { - i++; - - if (i == rowcount) - { - i = r; - lead++; - - if (lead == columncount) - return; - } - } - - if (i != r) - { - result.ExchangeRows(i, r); - } - - float multiplier = 1f / result[r, lead]; - - for (; i < rowcount; ++i) - { - if (i != r) - { - result[i, 0] -= result[r, 0] * multiplier * result[i, lead]; - result[i, 1] -= result[r, 1] * multiplier * result[i, lead]; - result[i, 2] -= result[r, 2] * multiplier * result[i, lead]; - result[i, 3] -= result[r, 3] * multiplier * result[i, lead]; - } - } - - lead++; - } - - Matrix.Transpose(ref result, out result); - } - - /// - /// Brings the matrix into lower triangular form using elementry row operations. - /// - /// The matrix to put into lower triangular form. - /// The lower triangular matrix. - /// - /// If the matrix is not invertable (i.e. its determinant is zero) than the result of this - /// method may produce Single.Nan and Single.Inf values. When the matrix represents a system - /// of linear equations, than this often means that either no solution exists or an infinite - /// number of solutions exist. - /// - public static Matrix LowerTriangularForm(Matrix value) - { - Matrix result; - LowerTriangularForm(ref value, out result); - return result; - } - - /// - /// Brings the matrix into row echelon form using elementry row operations; - /// - /// The matrix to put into row echelon form. - /// When the method completes, contains the row echelon form of the matrix. - public static void RowEchelonForm(ref Matrix value, out Matrix result) - { - //Source: Wikipedia psuedo code - //Reference: http://en.wikipedia.org/wiki/Row_echelon_form#Pseudocode - - result = value; - int lead = 0; - int rowcount = 4; - int columncount = 4; - - for (int r = 0; r < rowcount; ++r) - { - if (columncount <= lead) - return; - - int i = r; - - while (Math.Abs(result[i, lead]) < Utilities.ZeroTolerance) - { - i++; - - if (i == rowcount) - { - i = r; - lead++; - - if (lead == columncount) - return; - } - } - - if (i != r) - { - result.ExchangeRows(i, r); - } - - float multiplier = 1f / result[r, lead]; - result[r, 0] *= multiplier; - result[r, 1] *= multiplier; - result[r, 2] *= multiplier; - result[r, 3] *= multiplier; - - for (; i < rowcount; ++i) - { - if (i != r) - { - result[i, 0] -= result[r, 0] * result[i, lead]; - result[i, 1] -= result[r, 1] * result[i, lead]; - result[i, 2] -= result[r, 2] * result[i, lead]; - result[i, 3] -= result[r, 3] * result[i, lead]; - } - } - - lead++; - } - } - - /// - /// Brings the matrix into row echelon form using elementry row operations; - /// - /// The matrix to put into row echelon form. - /// When the method completes, contains the row echelon form of the matrix. - public static Matrix RowEchelonForm(Matrix value) - { - Matrix result; - RowEchelonForm(ref value, out result); - return result; - } - - /// - /// Brings the matrix into reduced row echelon form using elementry row operations. - /// - /// The matrix to put into reduced row echelon form. - /// The fifth column of the matrix. - /// When the method completes, contains the resultant matrix after the operation. - /// When the method completes, contains the resultant fifth column of the matrix. - /// - /// The fifth column is often called the agumented part of the matrix. This is because the fifth - /// column is really just an extension of the matrix so that there is a place to put all of the - /// non-zero components after the operation is complete. - /// Often times the resultant matrix will the identity matrix or a matrix similar to the identity - /// matrix. Sometimes, however, that is not possible and numbers other than zero and one may appear. - /// This method can be used to solve systems of linear equations. Upon completion of this method, - /// the will contain the solution for the system. It is up to the user - /// to analyze both the input and the result to determine if a solution really exists. - /// - public static void ReducedRowEchelonForm(ref Matrix value, ref Vector4 augment, out Matrix result, out Vector4 augmentResult) - { - //Source: http://rosettacode.org - //Reference: http://rosettacode.org/wiki/Reduced_row_echelon_form - - float[,] matrix = new float[4, 5]; - - matrix[0, 0] = value[0, 0]; - matrix[0, 1] = value[0, 1]; - matrix[0, 2] = value[0, 2]; - matrix[0, 3] = value[0, 3]; - matrix[0, 4] = augment[0]; - - matrix[1, 0] = value[1, 0]; - matrix[1, 1] = value[1, 1]; - matrix[1, 2] = value[1, 2]; - matrix[1, 3] = value[1, 3]; - matrix[1, 4] = augment[1]; - - matrix[2, 0] = value[2, 0]; - matrix[2, 1] = value[2, 1]; - matrix[2, 2] = value[2, 2]; - matrix[2, 3] = value[2, 3]; - matrix[2, 4] = augment[2]; - - matrix[3, 0] = value[3, 0]; - matrix[3, 1] = value[3, 1]; - matrix[3, 2] = value[3, 2]; - matrix[3, 3] = value[3, 3]; - matrix[3, 4] = augment[3]; - - int lead = 0; - int rowcount = 4; - int columncount = 5; - - for (int r = 0; r < rowcount; r++) - { - if (columncount <= lead) - break; - - int i = r; - - while (matrix[i, lead] == 0) - { - i++; - - if (i == rowcount) - { - i = r; - lead++; - - if (columncount == lead) - break; - } - } - - for (int j = 0; j < columncount; j++) - { - float temp = matrix[r, j]; - matrix[r, j] = matrix[i, j]; - matrix[i, j] = temp; - } - - float div = matrix[r, lead]; - - for (int j = 0; j < columncount; j++) - { - matrix[r, j] /= div; - } - - for (int j = 0; j < rowcount; j++) - { - if (j != r) - { - float sub = matrix[j, lead]; - for (int k = 0; k < columncount; k++) matrix[j, k] -= (sub * matrix[r, k]); - } - } - - lead++; - } - - result.M11 = matrix[0, 0]; - result.M12 = matrix[0, 1]; - result.M13 = matrix[0, 2]; - result.M14 = matrix[0, 3]; - - result.M21 = matrix[1, 0]; - result.M22 = matrix[1, 1]; - result.M23 = matrix[1, 2]; - result.M24 = matrix[1, 3]; - - result.M31 = matrix[2, 0]; - result.M32 = matrix[2, 1]; - result.M33 = matrix[2, 2]; - result.M34 = matrix[2, 3]; - - result.M41 = matrix[3, 0]; - result.M42 = matrix[3, 1]; - result.M43 = matrix[3, 2]; - result.M44 = matrix[3, 3]; - - augmentResult.X = matrix[0, 4]; - augmentResult.Y = matrix[1, 4]; - augmentResult.Z = matrix[2, 4]; - augmentResult.W = matrix[3, 4]; - } - - /// - /// Creates a spherical billboard that rotates around a specified object position. - /// - /// The position of the object around which the billboard will rotate. - /// The position of the camera. - /// The up vector of the camera. - /// The forward vector of the camera. - /// When the method completes, contains the created billboard matrix. - public static void Billboard(ref Vector3 objectPosition, ref Vector3 cameraPosition, ref Vector3 cameraUpVector, ref Vector3 cameraForwardVector, out Matrix result) - { - Vector3 crossed; - Vector3 final; - Vector3 difference = objectPosition - cameraPosition; - - float lengthsq = difference.LengthSquared(); - if (lengthsq < Utilities.ZeroTolerance) - difference = -cameraForwardVector; - else - difference *= (float)(1.0 / Math.Sqrt(lengthsq)); - - Vector3.Cross(ref cameraUpVector, ref difference, out crossed); - crossed.Normalize(); - Vector3.Cross(ref difference, ref crossed, out final); - - result.M11 = crossed.X; - result.M12 = crossed.Y; - result.M13 = crossed.Z; - result.M14 = 0.0f; - result.M21 = final.X; - result.M22 = final.Y; - result.M23 = final.Z; - result.M24 = 0.0f; - result.M31 = difference.X; - result.M32 = difference.Y; - result.M33 = difference.Z; - result.M34 = 0.0f; - result.M41 = objectPosition.X; - result.M42 = objectPosition.Y; - result.M43 = objectPosition.Z; - result.M44 = 1.0f; - } - - /// - /// Creates a spherical billboard that rotates around a specified object position. - /// - /// The position of the object around which the billboard will rotate. - /// The position of the camera. - /// The up vector of the camera. - /// The forward vector of the camera. - /// The created billboard matrix. - public static Matrix Billboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) - { - Matrix result; - Billboard(ref objectPosition, ref cameraPosition, ref cameraUpVector, ref cameraForwardVector, out result); - return result; - } - - /// - /// Creates a left-handed, look-at matrix. - /// - /// The position of the viewer's eye. - /// The camera look-at target. - /// The camera's up vector. - /// When the method completes, contains the created look-at matrix. - public static void LookAtLH(ref Vector3 eye, ref Vector3 target, ref Vector3 up, out Matrix result) - { - Vector3 xaxis, yaxis, zaxis; - Vector3.Subtract(ref target, ref eye, out zaxis); zaxis.Normalize(); - Vector3.Cross(ref up, ref zaxis, out xaxis); xaxis.Normalize(); - Vector3.Cross(ref zaxis, ref xaxis, out yaxis); - - result = Matrix.Identity; - result.M11 = xaxis.X; result.M21 = xaxis.Y; result.M31 = xaxis.Z; - result.M12 = yaxis.X; result.M22 = yaxis.Y; result.M32 = yaxis.Z; - result.M13 = zaxis.X; result.M23 = zaxis.Y; result.M33 = zaxis.Z; - - Vector3.Dot(ref xaxis, ref eye, out result.M41); - Vector3.Dot(ref yaxis, ref eye, out result.M42); - Vector3.Dot(ref zaxis, ref eye, out result.M43); - - result.M41 = -result.M41; - result.M42 = -result.M42; - result.M43 = -result.M43; - } - - /// - /// Creates a left-handed, look-at matrix. - /// - /// The position of the viewer's eye. - /// The camera look-at target. - /// The camera's up vector. - /// The created look-at matrix. - public static Matrix LookAtLH(Vector3 eye, Vector3 target, Vector3 up) - { - Matrix result; - LookAtLH(ref eye, ref target, ref up, out result); - return result; - } - - /// - /// Creates a right-handed, look-at matrix. - /// - /// The position of the viewer's eye. - /// The camera look-at target. - /// The camera's up vector. - /// When the method completes, contains the created look-at matrix. - public static void LookAtRH(ref Vector3 eye, ref Vector3 target, ref Vector3 up, out Matrix result) - { - Vector3 xaxis, yaxis, zaxis; - Vector3.Subtract(ref eye, ref target, out zaxis); zaxis.Normalize(); - Vector3.Cross(ref up, ref zaxis, out xaxis); xaxis.Normalize(); - Vector3.Cross(ref zaxis, ref xaxis, out yaxis); - - result = Matrix.Identity; - result.M11 = xaxis.X; result.M21 = xaxis.Y; result.M31 = xaxis.Z; - result.M12 = yaxis.X; result.M22 = yaxis.Y; result.M32 = yaxis.Z; - result.M13 = zaxis.X; result.M23 = zaxis.Y; result.M33 = zaxis.Z; - - Vector3.Dot(ref xaxis, ref eye, out result.M41); - Vector3.Dot(ref yaxis, ref eye, out result.M42); - Vector3.Dot(ref zaxis, ref eye, out result.M43); - - result.M41 = -result.M41; - result.M42 = -result.M42; - result.M43 = -result.M43; - } - - /// - /// Creates a right-handed, look-at matrix. - /// - /// The position of the viewer's eye. - /// The camera look-at target. - /// The camera's up vector. - /// The created look-at matrix. - public static Matrix LookAtRH(Vector3 eye, Vector3 target, Vector3 up) - { - Matrix result; - LookAtRH(ref eye, ref target, ref up, out result); - return result; - } - - /// - /// Creates a left-handed, orthographic projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void OrthoLH(float width, float height, float znear, float zfar, out Matrix result) - { - float halfWidth = width * 0.5f; - float halfHeight = height * 0.5f; - - OrthoOffCenterLH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a left-handed, orthographic projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix OrthoLH(float width, float height, float znear, float zfar) - { - Matrix result; - OrthoLH(width, height, znear, zfar, out result); - return result; - } - - /// - /// Creates a right-handed, orthographic projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void OrthoRH(float width, float height, float znear, float zfar, out Matrix result) - { - float halfWidth = width * 0.5f; - float halfHeight = height * 0.5f; - - OrthoOffCenterRH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a right-handed, orthographic projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix OrthoRH(float width, float height, float znear, float zfar) - { - Matrix result; - OrthoRH(width, height, znear, zfar, out result); - return result; - } - - /// - /// Creates a left-handed, customized orthographic projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void OrthoOffCenterLH(float left, float right, float bottom, float top, float znear, float zfar, out Matrix result) - { - float zRange = 1.0f / (zfar - znear); - - result = Matrix.Identity; - result.M11 = 2.0f / (right - left); - result.M22 = 2.0f / (top - bottom); - result.M33 = zRange; - result.M41 = (left + right) / (left - right); - result.M42 = (top + bottom) / (bottom - top); - result.M43 = -znear * zRange; - } - - /// - /// Creates a left-handed, customized orthographic projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix OrthoOffCenterLH(float left, float right, float bottom, float top, float znear, float zfar) - { - Matrix result; - OrthoOffCenterLH(left, right, bottom, top, znear, zfar, out result); - return result; - } - - /// - /// Creates a right-handed, customized orthographic projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void OrthoOffCenterRH(float left, float right, float bottom, float top, float znear, float zfar, out Matrix result) - { - OrthoOffCenterLH(left, right, bottom, top, znear, zfar, out result); - result.M33 *= -1.0f; - } - - /// - /// Creates a right-handed, customized orthographic projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix OrthoOffCenterRH(float left, float right, float bottom, float top, float znear, float zfar) - { - Matrix result; - OrthoOffCenterRH(left, right, bottom, top, znear, zfar, out result); - return result; - } - - /// - /// Creates a left-handed, perspective projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveLH(float width, float height, float znear, float zfar, out Matrix result) - { - float halfWidth = width * 0.5f; - float halfHeight = height * 0.5f; - - PerspectiveOffCenterLH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a left-handed, perspective projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveLH(float width, float height, float znear, float zfar) - { - Matrix result; - PerspectiveLH(width, height, znear, zfar, out result); - return result; - } - - /// - /// Creates a right-handed, perspective projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveRH(float width, float height, float znear, float zfar, out Matrix result) - { - float halfWidth = width * 0.5f; - float halfHeight = height * 0.5f; - - PerspectiveOffCenterRH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a right-handed, perspective projection matrix. - /// - /// Width of the viewing volume. - /// Height of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveRH(float width, float height, float znear, float zfar) - { - Matrix result; - PerspectiveRH(width, height, znear, zfar, out result); - return result; - } - - /// - /// Creates a left-handed, perspective projection matrix based on a field of view. - /// - /// Field of view in the y direction, in radians. - /// Aspect ratio, defined as view space width divided by height. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveFovLH(float fov, float aspect, float znear, float zfar, out Matrix result) - { - float yScale = (float)(1.0 / Math.Tan(fov * 0.5f)); - float xScale = yScale / aspect; - - float halfWidth = znear / xScale; - float halfHeight = znear / yScale; - - PerspectiveOffCenterLH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a left-handed, perspective projection matrix based on a field of view. - /// - /// Field of view in the y direction, in radians. - /// Aspect ratio, defined as view space width divided by height. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveFovLH(float fov, float aspect, float znear, float zfar) - { - Matrix result; - PerspectiveFovLH(fov, aspect, znear, zfar, out result); - return result; - } - - /// - /// Creates a right-handed, perspective projection matrix based on a field of view. - /// - /// Field of view in the y direction, in radians. - /// Aspect ratio, defined as view space width divided by height. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveFovRH(float fov, float aspect, float znear, float zfar, out Matrix result) - { - float yScale = (float)(1.0 / Math.Tan(fov * 0.5f)); - float xScale = yScale / aspect; - - float halfWidth = znear / xScale; - float halfHeight = znear / yScale; - - PerspectiveOffCenterRH(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out result); - } - - /// - /// Creates a right-handed, perspective projection matrix based on a field of view. - /// - /// Field of view in the y direction, in radians. - /// Aspect ratio, defined as view space width divided by height. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveFovRH(float fov, float aspect, float znear, float zfar) - { - Matrix result; - PerspectiveFovRH(fov, aspect, znear, zfar, out result); - return result; - } - - /// - /// Creates a left-handed, customized perspective projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveOffCenterLH(float left, float right, float bottom, float top, float znear, float zfar, out Matrix result) - { - float zRange = zfar / (zfar - znear); - - result = new Matrix(); - result.M11 = 2.0f * znear / (right - left); - result.M22 = 2.0f * znear / (top - bottom); - result.M31 = (left + right) / (left - right); - result.M32 = (top + bottom) / (bottom - top); - result.M33 = zRange; - result.M34 = 1.0f; - result.M43 = -znear * zRange; - } - - /// - /// Creates a left-handed, customized perspective projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveOffCenterLH(float left, float right, float bottom, float top, float znear, float zfar) - { - Matrix result; - PerspectiveOffCenterLH(left, right, bottom, top, znear, zfar, out result); - return result; - } - - /// - /// Creates a right-handed, customized perspective projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// When the method completes, contains the created projection matrix. - public static void PerspectiveOffCenterRH(float left, float right, float bottom, float top, float znear, float zfar, out Matrix result) - { - PerspectiveOffCenterLH(left, right, bottom, top, znear, zfar, out result); - result.M31 *= -1.0f; - result.M32 *= -1.0f; - result.M33 *= -1.0f; - result.M34 *= -1.0f; - } - - /// - /// Creates a right-handed, customized perspective projection matrix. - /// - /// Minimum x-value of the viewing volume. - /// Maximum x-value of the viewing volume. - /// Minimum y-value of the viewing volume. - /// Maximum y-value of the viewing volume. - /// Minimum z-value of the viewing volume. - /// Maximum z-value of the viewing volume. - /// The created projection matrix. - public static Matrix PerspectiveOffCenterRH(float left, float right, float bottom, float top, float znear, float zfar) - { - Matrix result; - PerspectiveOffCenterRH(left, right, bottom, top, znear, zfar, out result); - return result; - } - - /// - /// Builds a matrix that can be used to reflect vectors about a plane. - /// - /// The plane for which the reflection occurs. This parameter is assumed to be normalized. - /// When the method completes, contains the reflection matrix. - public static void Reflection(ref Plane plane, out Matrix result) - { - float x = plane.Normal.X; - float y = plane.Normal.Y; - float z = plane.Normal.Z; - float x2 = -2.0f * x; - float y2 = -2.0f * y; - float z2 = -2.0f * z; - - result.M11 = (x2 * x) + 1.0f; - result.M12 = y2 * x; - result.M13 = z2 * x; - result.M14 = 0.0f; - result.M21 = x2 * y; - result.M22 = (y2 * y) + 1.0f; - result.M23 = z2 * y; - result.M24 = 0.0f; - result.M31 = x2 * z; - result.M32 = y2 * z; - result.M33 = (z2 * z) + 1.0f; - result.M34 = 0.0f; - result.M41 = x2 * plane.D; - result.M42 = y2 * plane.D; - result.M43 = z2 * plane.D; - result.M44 = 1.0f; - } - - /// - /// Builds a matrix that can be used to reflect vectors about a plane. - /// - /// The plane for which the reflection occurs. This parameter is assumed to be normalized. - /// The reflection matrix. - public static Matrix Reflection(Plane plane) - { - Matrix result; - Reflection(ref plane, out result); - return result; - } - - /// - /// Creates a matrix that flattens geometry into a shadow. - /// - /// The light direction. If the W component is 0, the light is directional light; if the - /// W component is 1, the light is a point light. - /// The plane onto which to project the geometry as a shadow. This parameter is assumed to be normalized. - /// When the method completes, contains the shadow matrix. - public static void Shadow(ref Vector4 light, ref Plane plane, out Matrix result) - { - float dot = (plane.Normal.X * light.X) + (plane.Normal.Y * light.Y) + (plane.Normal.Z * light.Z) + (plane.D * light.W); - float x = -plane.Normal.X; - float y = -plane.Normal.Y; - float z = -plane.Normal.Z; - float d = -plane.D; - - result.M11 = (x * light.X) + dot; - result.M21 = y * light.X; - result.M31 = z * light.X; - result.M41 = d * light.X; - result.M12 = x * light.Y; - result.M22 = (y * light.Y) + dot; - result.M32 = z * light.Y; - result.M42 = d * light.Y; - result.M13 = x * light.Z; - result.M23 = y * light.Z; - result.M33 = (z * light.Z) + dot; - result.M43 = d * light.Z; - result.M14 = x * light.W; - result.M24 = y * light.W; - result.M34 = z * light.W; - result.M44 = (d * light.W) + dot; - } - - /// - /// Creates a matrix that flattens geometry into a shadow. - /// - /// The light direction. If the W component is 0, the light is directional light; if the - /// W component is 1, the light is a point light. - /// The plane onto which to project the geometry as a shadow. This parameter is assumed to be normalized. - /// The shadow matrix. - public static Matrix Shadow(Vector4 light, Plane plane) - { - Matrix result; - Shadow(ref light, ref plane, out result); - return result; - } - - /// - /// Creates a matrix that scales along the x-axis, y-axis, and y-axis. - /// - /// Scaling factor for all three axes. - /// When the method completes, contains the created scaling matrix. - public static void Scaling(ref Vector3 scale, out Matrix result) - { - Scaling(scale.X, scale.Y, scale.Z, out result); - } - - /// - /// Creates a matrix that scales along the x-axis, y-axis, and y-axis. - /// - /// Scaling factor for all three axes. - /// The created scaling matrix. - public static Matrix Scaling(Vector3 scale) - { - Matrix result; - Scaling(ref scale, out result); - return result; - } - - /// - /// Creates a matrix that uniformally scales along all three axis. - /// - /// The uniform scale that is applied along all axis. - /// When the method completes, contains the created scaling matrix. - public static void Scaling(float scale, out Matrix result) - { - result = Matrix.Identity; - result.M11 = result.M22 = result.M33 = scale; - } - - /// - /// Creates a matrix that uniformally scales along all three axis. - /// - /// The uniform scale that is applied along all axis. - /// The created scaling matrix. - public static Matrix Scaling(float scale) - { - Matrix result; - Scaling(scale, out result); - return result; - } - - /// - /// Creates a matrix that scales along the x-axis, y-axis, and y-axis. - /// - /// Scaling factor that is applied along the x-axis. - /// Scaling factor that is applied along the y-axis. - /// Scaling factor that is applied along the z-axis. - /// When the method completes, contains the created scaling matrix. - public static void Scaling(float x, float y, float z, out Matrix result) - { - result = Matrix.Identity; - result.M11 = x; - result.M22 = y; - result.M33 = z; - } - - /// - /// Creates a matrix that scales along the x-axis, y-axis, and y-axis. - /// - /// Scaling factor that is applied along the x-axis. - /// Scaling factor that is applied along the y-axis. - /// Scaling factor that is applied along the z-axis. - /// The created scaling matrix. - public static Matrix Scaling(float x, float y, float z) - { - Matrix result; - Scaling(x, y, z, out result); - return result; - } - - /// - /// Creates a matrix that rotates around the x-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// When the method completes, contains the created rotation matrix. - public static void RotationX(float angle, out Matrix result) - { - float cos = (float)Math.Cos(angle); - float sin = (float)Math.Sin(angle); - - result = Matrix.Identity; - result.M22 = cos; - result.M23 = sin; - result.M32 = -sin; - result.M33 = cos; - } - - /// - /// Creates a matrix that rotates around the x-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// The created rotation matrix. - public static Matrix RotationX(float angle) - { - Matrix result; - RotationX(angle, out result); - return result; - } - - /// - /// Creates a matrix that rotates around the y-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// When the method completes, contains the created rotation matrix. - public static void RotationY(float angle, out Matrix result) - { - float cos = (float)Math.Cos(angle); - float sin = (float)Math.Sin(angle); - - result = Matrix.Identity; - result.M11 = cos; - result.M13 = -sin; - result.M31 = sin; - result.M33 = cos; - } - - /// - /// Creates a matrix that rotates around the y-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// The created rotation matrix. - public static Matrix RotationY(float angle) - { - Matrix result; - RotationY(angle, out result); - return result; - } - - /// - /// Creates a matrix that rotates around the z-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// When the method completes, contains the created rotation matrix. - public static void RotationZ(float angle, out Matrix result) - { - float cos = (float)Math.Cos(angle); - float sin = (float)Math.Sin(angle); - - result = Matrix.Identity; - result.M11 = cos; - result.M12 = sin; - result.M21 = -sin; - result.M22 = cos; - } - - /// - /// Creates a matrix that rotates around the z-axis. - /// - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// The created rotation matrix. - public static Matrix RotationZ(float angle) - { - Matrix result; - RotationZ(angle, out result); - return result; - } - - /// - /// Creates a matrix that rotates around an arbitary axis. - /// - /// The axis around which to rotate. This parameter is assumed to be normalized. - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// When the method completes, contains the created rotation matrix. - public static void RotationAxis(ref Vector3 axis, float angle, out Matrix result) - { - float x = axis.X; - float y = axis.Y; - float z = axis.Z; - float cos = (float)Math.Cos(angle); - float sin = (float)Math.Sin(angle); - float xx = x * x; - float yy = y * y; - float zz = z * z; - float xy = x * y; - float xz = x * z; - float yz = y * z; - - result = Matrix.Identity; - result.M11 = xx + (cos * (1.0f - xx)); - result.M12 = (xy - (cos * xy)) + (sin * z); - result.M13 = (xz - (cos * xz)) - (sin * y); - result.M21 = (xy - (cos * xy)) - (sin * z); - result.M22 = yy + (cos * (1.0f - yy)); - result.M23 = (yz - (cos * yz)) + (sin * x); - result.M31 = (xz - (cos * xz)) + (sin * y); - result.M32 = (yz - (cos * yz)) - (sin * x); - result.M33 = zz + (cos * (1.0f - zz)); - } - - /// - /// Creates a matrix that rotates around an arbitary axis. - /// - /// The axis around which to rotate. This parameter is assumed to be normalized. - /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin. - /// The created rotation matrix. - public static Matrix RotationAxis(Vector3 axis, float angle) - { - Matrix result; - RotationAxis(ref axis, angle, out result); - return result; - } - - /// - /// Creates a rotation matrix from a quaternion. - /// - /// The quaternion to use to build the matrix. - /// The created rotation matrix. - public static void RotationQuaternion(ref Quaternion rotation, out Matrix result) - { - float xx = rotation.X * rotation.X; - float yy = rotation.Y * rotation.Y; - float zz = rotation.Z * rotation.Z; - float xy = rotation.X * rotation.Y; - float zw = rotation.Z * rotation.W; - float zx = rotation.Z * rotation.X; - float yw = rotation.Y * rotation.W; - float yz = rotation.Y * rotation.Z; - float xw = rotation.X * rotation.W; - - result = Matrix.Identity; - result.M11 = 1.0f - (2.0f * (yy + zz)); - result.M12 = 2.0f * (xy + zw); - result.M13 = 2.0f * (zx - yw); - result.M21 = 2.0f * (xy - zw); - result.M22 = 1.0f - (2.0f * (zz + xx)); - result.M23 = 2.0f * (yz + xw); - result.M31 = 2.0f * (zx + yw); - result.M32 = 2.0f * (yz - xw); - result.M33 = 1.0f - (2.0f * (yy + xx)); - } - - /// - /// Creates a rotation matrix from a quaternion. - /// - /// The quaternion to use to build the matrix. - /// The created rotation matrix. - public static Matrix RotationQuaternion(Quaternion rotation) - { - Matrix result; - RotationQuaternion(ref rotation, out result); - return result; - } - - /// - /// Creates a rotation matrix with a specified yaw, pitch, and roll. - /// - /// Yaw around the y-axis, in radians. - /// Pitch around the x-axis, in radians. - /// Roll around the z-axis, in radians. - /// When the method completes, contains the created rotation matrix. - public static void RotationYawPitchRoll(float yaw, float pitch, float roll, out Matrix result) - { - Quaternion quaternion = new Quaternion(); - Quaternion.RotationYawPitchRoll(yaw, pitch, roll, out quaternion); - RotationQuaternion(ref quaternion, out result); - } - - /// - /// Creates a rotation matrix with a specified yaw, pitch, and roll. - /// - /// Yaw around the y-axis, in radians. - /// Pitch around the x-axis, in radians. - /// Roll around the z-axis, in radians. - /// The created rotation matrix. - public static Matrix RotationYawPitchRoll(float yaw, float pitch, float roll) - { - Matrix result; - RotationYawPitchRoll(yaw, pitch, roll, out result); - return result; - } - - /// - /// Creates a translation matrix using the specified offsets. - /// - /// The offset for all three coordinate planes. - /// When the method completes, contains the created translation matrix. - public static void Translation(ref Vector3 value, out Matrix result) - { - Translation(value.X, value.Y, value.Z, out result); - } - - /// - /// Creates a translation matrix using the specified offsets. - /// - /// The offset for all three coordinate planes. - /// The created translation matrix. - public static Matrix Translation(Vector3 value) - { - Matrix result; - Translation(ref value, out result); - return result; - } - - /// - /// Creates a translation matrix using the specified offsets. - /// - /// X-coordinate offset. - /// Y-coordinate offset. - /// Z-coordinate offset. - /// When the method completes, contains the created translation matrix. - public static void Translation(float x, float y, float z, out Matrix result) - { - result = Matrix.Identity; - result.M41 = x; - result.M42 = y; - result.M43 = z; - } - - /// - /// Creates a translation matrix using the specified offsets. - /// - /// X-coordinate offset. - /// Y-coordinate offset. - /// Z-coordinate offset. - /// The created translation matrix. - public static Matrix Translation(float x, float y, float z) - { - Matrix result; - Translation(x, y, z, out result); - return result; - } - - /// - /// Creates a 3D affine transformation matrix. - /// - /// Scaling factor. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created affine transformation matrix. - public static void AffineTransformation(float scaling, ref Quaternion rotation, ref Vector3 translation, out Matrix result) - { - result = Scaling(scaling) * RotationQuaternion(rotation) * Translation(translation); - } - - /// - /// Creates a 3D affine transformation matrix. - /// - /// Scaling factor. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created affine transformation matrix. - public static Matrix AffineTransformation(float scaling, Quaternion rotation, Vector3 translation) - { - Matrix result; - AffineTransformation(scaling, ref rotation, ref translation, out result); - return result; - } - - /// - /// Creates a 3D affine transformation matrix. - /// - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created affine transformation matrix. - public static void AffineTransformation(float scaling, ref Vector3 rotationCenter, ref Quaternion rotation, ref Vector3 translation, out Matrix result) - { - result = Scaling(scaling) * Translation(-rotationCenter) * RotationQuaternion(rotation) * - Translation(rotationCenter) * Translation(translation); - } - - /// - /// Creates a 3D affine transformation matrix. - /// - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created affine transformation matrix. - public static Matrix AffineTransformation(float scaling, Vector3 rotationCenter, Quaternion rotation, Vector3 translation) - { - Matrix result; - AffineTransformation(scaling, ref rotationCenter, ref rotation, ref translation, out result); - return result; - } - - /// - /// Creates a 2D affine transformation matrix. - /// - /// Scaling factor. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created affine transformation matrix. - public static void AffineTransformation2D(float scaling, float rotation, ref Vector2 translation, out Matrix result) - { - result = Scaling(scaling, scaling, 1.0f) * RotationZ(rotation) * Translation((Vector3)translation); - } - - /// - /// Creates a 2D affine transformation matrix. - /// - /// Scaling factor. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created affine transformation matrix. - public static Matrix AffineTransformation2D(float scaling, float rotation, Vector2 translation) - { - Matrix result; - AffineTransformation2D(scaling, rotation, ref translation, out result); - return result; - } - - /// - /// Creates a 2D affine transformation matrix. - /// - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created affine transformation matrix. - public static void AffineTransformation2D(float scaling, ref Vector2 rotationCenter, float rotation, ref Vector2 translation, out Matrix result) - { - result = Scaling(scaling, scaling, 1.0f) * Translation((Vector3)(-rotationCenter)) * RotationZ(rotation) * - Translation((Vector3)rotationCenter) * Translation((Vector3)translation); - } - - /// - /// Creates a 2D affine transformation matrix. - /// - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created affine transformation matrix. - public static Matrix AffineTransformation2D(float scaling, Vector2 rotationCenter, float rotation, Vector2 translation) - { - Matrix result; - AffineTransformation2D(scaling, ref rotationCenter, rotation, ref translation, out result); - return result; - } - - /// - /// Creates a transformation matrix. - /// - /// Center point of the scaling operation. - /// Scaling rotation amount. - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created transformation matrix. - public static void Transformation(ref Vector3 scalingCenter, ref Quaternion scalingRotation, ref Vector3 scaling, ref Vector3 rotationCenter, ref Quaternion rotation, ref Vector3 translation, out Matrix result) - { - Matrix sr = RotationQuaternion(scalingRotation); - - result = Translation(-scalingCenter) * Transpose(sr) * Scaling(scaling) * sr * Translation(scalingCenter) * Translation(-rotationCenter) * - RotationQuaternion(rotation) * Translation(rotationCenter) * Translation(translation); - } - - /// - /// Creates a transformation matrix. - /// - /// Center point of the scaling operation. - /// Scaling rotation amount. - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created transformation matrix. - public static Matrix Transformation(Vector3 scalingCenter, Quaternion scalingRotation, Vector3 scaling, Vector3 rotationCenter, Quaternion rotation, Vector3 translation) - { - Matrix result; - Transformation(ref scalingCenter, ref scalingRotation, ref scaling, ref rotationCenter, ref rotation, ref translation, out result); - return result; - } - - /// - /// Creates a 2D transformation matrix. - /// - /// Center point of the scaling operation. - /// Scaling rotation amount. - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// When the method completes, contains the created transformation matrix. - public static void Transformation2D(ref Vector2 scalingCenter, float scalingRotation, ref Vector2 scaling, ref Vector2 rotationCenter, float rotation, ref Vector2 translation, out Matrix result) - { - result = Translation((Vector3)(-scalingCenter)) * RotationZ(-scalingRotation) * Scaling((Vector3)scaling) * RotationZ(scalingRotation) * Translation((Vector3)scalingCenter) * - Translation((Vector3)(-rotationCenter)) * RotationZ(rotation) * Translation((Vector3)rotationCenter) * Translation((Vector3)translation); - - result.M33 = 1f; - result.M44 = 1f; - } - - /// - /// Creates a 2D transformation matrix. - /// - /// Center point of the scaling operation. - /// Scaling rotation amount. - /// Scaling factor. - /// The center of the rotation. - /// The rotation of the transformation. - /// The translation factor of the transformation. - /// The created transformation matrix. - public static Matrix Transformation2D(Vector2 scalingCenter, float scalingRotation, Vector2 scaling, Vector2 rotationCenter, float rotation, Vector2 translation) - { - Matrix result; - Transformation2D(ref scalingCenter, scalingRotation, ref scaling, ref rotationCenter, rotation, ref translation, out result); - return result; - } - - /// - /// Adds two matricies. - /// - /// The first matrix to add. - /// The second matrix to add. - /// The sum of the two matricies. - public static Matrix operator +(Matrix left, Matrix right) - { - Matrix result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Assert a matrix (return it unchanged). - /// - /// The matrix to assert (unchange). - /// The asserted (unchanged) matrix. - public static Matrix operator +(Matrix value) - { - return value; - } - - /// - /// Subtracts two matricies. - /// - /// The first matrix to subtract. - /// The second matrix to subtract. - /// The difference between the two matricies. - public static Matrix operator -(Matrix left, Matrix right) - { - Matrix result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Negates a matrix. - /// - /// The matrix to negate. - /// The negated matrix. - public static Matrix operator -(Matrix value) - { - Matrix result; - Negate(ref value, out result); - return result; - } - - /// - /// Scales a matrix by a given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// The scaled matrix. - public static Matrix operator *(float scalar, Matrix right) - { - Matrix result; - Multiply(ref right, scalar, out result); - return result; - } - - /// - /// Scales a matrix by a given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// The scaled matrix. - public static Matrix operator *(Matrix left, float scalar) - { - Matrix result; - Multiply(ref left, scalar, out result); - return result; - } - - /// - /// Multiplies two matricies. - /// - /// The first matrix to multiply. - /// The second matrix to multiply. - /// The product of the two matricies. - public static Matrix operator *(Matrix left, Matrix right) - { - Matrix result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Scales a matrix by a given value. - /// - /// The matrix to scale. - /// The amount by which to scale. - /// The scaled matrix. - public static Matrix operator /(Matrix left, float scalar) - { - Matrix result; - Divide(ref left, scalar, out result); - return result; - } - - /// - /// Divides two matricies. - /// - /// The first matrix to divide. - /// The second matrix to divide. - /// The quotient of the two matricies. - public static Matrix operator /(Matrix left, Matrix right) - { - Matrix result; - Divide(ref left, ref right, out result); - return result; - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Matrix left, Matrix right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Matrix left, Matrix right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "[M11:{0} M12:{1} M13:{2} M14:{3}] [M21:{4} M22:{5} M23:{6} M24:{7}] [M31:{8} M32:{9} M33:{10} M34:{11}] [M41:{12} M42:{13} M43:{14} M44:{15}]", - M11, M12, M13, M14, M21, M22, M23, M24, M31, M32, M33, M34, M41, M42, M43, M44); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(format, CultureInfo.CurrentCulture, "[M11:{0} M12:{1} M13:{2} M14:{3}] [M21:{4} M22:{5} M23:{6} M24:{7}] [M31:{8} M32:{9} M33:{10} M34:{11}] [M41:{12} M42:{13} M43:{14} M44:{15}]", - M11.ToString(format, CultureInfo.CurrentCulture), M12.ToString(format, CultureInfo.CurrentCulture), M13.ToString(format, CultureInfo.CurrentCulture), M14.ToString(format, CultureInfo.CurrentCulture), - M21.ToString(format, CultureInfo.CurrentCulture), M22.ToString(format, CultureInfo.CurrentCulture), M23.ToString(format, CultureInfo.CurrentCulture), M24.ToString(format, CultureInfo.CurrentCulture), - M31.ToString(format, CultureInfo.CurrentCulture), M32.ToString(format, CultureInfo.CurrentCulture), M33.ToString(format, CultureInfo.CurrentCulture), M34.ToString(format, CultureInfo.CurrentCulture), - M41.ToString(format, CultureInfo.CurrentCulture), M42.ToString(format, CultureInfo.CurrentCulture), M43.ToString(format, CultureInfo.CurrentCulture), M44.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "[M11:{0} M12:{1} M13:{2} M14:{3}] [M21:{4} M22:{5} M23:{6} M24:{7}] [M31:{8} M32:{9} M33:{10} M34:{11}] [M41:{12} M42:{13} M43:{14} M44:{15}]", - M11.ToString(formatProvider), M12.ToString(formatProvider), M13.ToString(formatProvider), M14.ToString(formatProvider), - M21.ToString(formatProvider), M22.ToString(formatProvider), M23.ToString(formatProvider), M24.ToString(formatProvider), - M31.ToString(formatProvider), M32.ToString(formatProvider), M33.ToString(formatProvider), M34.ToString(formatProvider), - M41.ToString(formatProvider), M42.ToString(formatProvider), M43.ToString(formatProvider), M44.ToString(formatProvider)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(format, formatProvider, "[M11:{0} M12:{1} M13:{2} M14:{3}] [M21:{4} M22:{5} M23:{6} M24:{7}] [M31:{8} M32:{9} M33:{10} M34:{11}] [M41:{12} M42:{13} M43:{14} M44:{15}]", - M11.ToString(format, formatProvider), M12.ToString(format, formatProvider), M13.ToString(format, formatProvider), M14.ToString(format, formatProvider), - M21.ToString(format, formatProvider), M22.ToString(format, formatProvider), M23.ToString(format, formatProvider), M24.ToString(format, formatProvider), - M31.ToString(format, formatProvider), M32.ToString(format, formatProvider), M33.ToString(format, formatProvider), M34.ToString(format, formatProvider), - M41.ToString(format, formatProvider), M42.ToString(format, formatProvider), M43.ToString(format, formatProvider), M44.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return M11.GetHashCode() + M12.GetHashCode() + M13.GetHashCode() + M14.GetHashCode() + - M21.GetHashCode() + M22.GetHashCode() + M23.GetHashCode() + M24.GetHashCode() + - M31.GetHashCode() + M32.GetHashCode() + M33.GetHashCode() + M34.GetHashCode() + - M41.GetHashCode() + M42.GetHashCode() + M43.GetHashCode() + M44.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Matrix other) - { - return (other.M11 == M11 && - other.M12 == M12 && - other.M13 == M13 && - other.M14 == M14 && - - other.M21 == M21 && - other.M22 == M22 && - other.M23 == M23 && - other.M24 == M24 && - - other.M31 == M31 && - other.M32 == M32 && - other.M33 == M33 && - other.M34 == M34 && - - other.M41 == M41 && - other.M42 == M42 && - other.M43 == M43 && - other.M44 == M44); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// The amount of error allowed. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Matrix other, float epsilon) - { - return (Math.Abs(other.M11 - M11) < epsilon && - Math.Abs(other.M12 - M12) < epsilon && - Math.Abs(other.M13 - M13) < epsilon && - Math.Abs(other.M14 - M14) < epsilon && - - Math.Abs(other.M21 - M21) < epsilon && - Math.Abs(other.M22 - M22) < epsilon && - Math.Abs(other.M23 - M23) < epsilon && - Math.Abs(other.M24 - M24) < epsilon && - - Math.Abs(other.M31 - M31) < epsilon && - Math.Abs(other.M32 - M32) < epsilon && - Math.Abs(other.M33 - M33) < epsilon && - Math.Abs(other.M34 - M34) < epsilon && - - Math.Abs(other.M41 - M41) < epsilon && - Math.Abs(other.M42 - M42) < epsilon && - Math.Abs(other.M43 - M43) < epsilon && - Math.Abs(other.M44 - M44) < epsilon); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Matrix)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Matrix(Matrix value) - { - return new SlimDX.Matrix() - { - M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14, - M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24, - M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34, - M41 = value.M41, M42 = value.M42, M43 = value.M43, M44 = value.M44 - }; - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Matrix(SlimDX.Matrix value) - { - return new Matrix() - { - M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14, - M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24, - M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34, - M41 = value.M41, M42 = value.M42, M43 = value.M43, M44 = value.M44 - }; - } -#endif - -#if WPFInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator System.Windows.Media.Media3D.Matrix3D(Matrix value) - { - return new System.Windows.Media.Media3D.Matrix3D() - { - M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14, - M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24, - M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34, - OffsetX = value.M41, OffsetY = value.M42, OffsetZ = value.M43, M44 = value.M44 - }; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Matrix(System.Windows.Media.Media3D.Matrix3D value) - { - return new Matrix() - { - M11 = (float)value.M11, M12 = (float)value.M12, M13 = (float)value.M13, M14 = (float)value.M14, - M21 = (float)value.M21, M22 = (float)value.M22, M23 = (float)value.M23, M24 = (float)value.M24, - M31 = (float)value.M31, M32 = (float)value.M32, M33 = (float)value.M33, M34 = (float)value.M34, - M41 = (float)value.OffsetX, M42 = (float)value.OffsetY, M43 = (float)value.OffsetZ, M44 = (float)value.M44 - }; - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Matrix(Matrix value) - { - return new Microsoft.Xna.Framework.Matrix() - { - M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14, - M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24, - M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34, - M41 = value.M41, M42 = value.M42, M43 = value.M43, M44 = value.M44 - }; - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Matrix(Microsoft.Xna.Framework.Matrix value) - { - return new Matrix() - { - M11 = value.M11, M12 = value.M12, M13 = value.M13, M14 = value.M14, - M21 = value.M21, M22 = value.M22, M23 = value.M23, M24 = value.M24, - M31 = value.M31, M32 = value.M32, M33 = value.M33, M34 = value.M34, - M41 = value.M41, M42 = value.M42, M43 = value.M43, M44 = value.M44 - }; - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Matrix3x2.cs b/source/OrkEngine3D.Mathematics/Matrix3x2.cs deleted file mode 100644 index 662ccf5..0000000 --- a/source/OrkEngine3D.Mathematics/Matrix3x2.cs +++ /dev/null @@ -1,811 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace OrkEngine3D.Mathematics -{ - /// - /// A structure encapsulating a 3x2 matrix. - /// - public struct Matrix3x2 : IEquatable - { - #region Public Fields - /// - /// The first element of the first row - /// - public float M11; - /// - /// The second element of the first row - /// - public float M12; - /// - /// The first element of the second row - /// - public float M21; - /// - /// The second element of the second row - /// - public float M22; - /// - /// The first element of the third row - /// - public float M31; - /// - /// The second element of the third row - /// - public float M32; - #endregion Public Fields - - private static readonly Matrix3x2 _identity = new Matrix3x2 - ( - 1f, 0f, - 0f, 1f, - 0f, 0f - ); - - /// - /// Returns the multiplicative identity matrix. - /// - public static Matrix3x2 Identity - { - get { return _identity; } - } - - /// - /// Returns whether the matrix is the identity matrix. - /// - public bool IsIdentity - { - get - { - return M11 == 1f && M22 == 1f && // Check diagonal element first for early out. - M12 == 0f && - M21 == 0f && - M31 == 0f && M32 == 0f; - } - } - - /// - /// Gets or sets the translation component of this matrix. - /// - public Vector2 Translation - { - get - { - return new Vector2(M31, M32); - } - - set - { - M31 = value.X; - M32 = value.Y; - } - } - - /// - /// Constructs a Matrix3x2 from the given components. - /// - public Matrix3x2(float m11, float m12, - float m21, float m22, - float m31, float m32) - { - this.M11 = m11; - this.M12 = m12; - this.M21 = m21; - this.M22 = m22; - this.M31 = m31; - this.M32 = m32; - } - - /// - /// Creates a translation matrix from the given vector. - /// - /// The translation position. - /// A translation matrix. - public static Matrix3x2 CreateTranslation(Vector2 position) - { - Matrix3x2 result; - - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - - result.M31 = position.X; - result.M32 = position.Y; - - return result; - } - - /// - /// Creates a translation matrix from the given X and Y components. - /// - /// The X position. - /// The Y position. - /// A translation matrix. - public static Matrix3x2 CreateTranslation(float xPosition, float yPosition) - { - Matrix3x2 result; - - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - - result.M31 = xPosition; - result.M32 = yPosition; - - return result; - } - - /// - /// Creates a scale matrix from the given X and Y components. - /// - /// Value to scale by on the X-axis. - /// Value to scale by on the Y-axis. - /// A scaling matrix. - public static Matrix3x2 CreateScale(float xScale, float yScale) - { - Matrix3x2 result; - - result.M11 = xScale; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = yScale; - result.M31 = 0.0f; - result.M32 = 0.0f; - - return result; - } - - /// - /// Creates a scale matrix that is offset by a given center point. - /// - /// Value to scale by on the X-axis. - /// Value to scale by on the Y-axis. - /// The center point. - /// A scaling matrix. - public static Matrix3x2 CreateScale(float xScale, float yScale, Vector2 centerPoint) - { - Matrix3x2 result; - - float tx = centerPoint.X * (1 - xScale); - float ty = centerPoint.Y * (1 - yScale); - - result.M11 = xScale; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = yScale; - result.M31 = tx; - result.M32 = ty; - - return result; - } - - /// - /// Creates a scale matrix from the given vector scale. - /// - /// The scale to use. - /// A scaling matrix. - public static Matrix3x2 CreateScale(Vector2 scales) - { - Matrix3x2 result; - - result.M11 = scales.X; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = scales.Y; - result.M31 = 0.0f; - result.M32 = 0.0f; - - return result; - } - - /// - /// Creates a scale matrix from the given vector scale with an offset from the given center point. - /// - /// The scale to use. - /// The center offset. - /// A scaling matrix. - public static Matrix3x2 CreateScale(Vector2 scales, Vector2 centerPoint) - { - Matrix3x2 result; - - float tx = centerPoint.X * (1 - scales.X); - float ty = centerPoint.Y * (1 - scales.Y); - - result.M11 = scales.X; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = scales.Y; - result.M31 = tx; - result.M32 = ty; - - return result; - } - - /// - /// Creates a scale matrix that scales uniformly with the given scale. - /// - /// The uniform scale to use. - /// A scaling matrix. - public static Matrix3x2 CreateScale(float scale) - { - Matrix3x2 result; - - result.M11 = scale; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = scale; - result.M31 = 0.0f; - result.M32 = 0.0f; - - return result; - } - - /// - /// Creates a scale matrix that scales uniformly with the given scale with an offset from the given center. - /// - /// The uniform scale to use. - /// The center offset. - /// A scaling matrix. - public static Matrix3x2 CreateScale(float scale, Vector2 centerPoint) - { - Matrix3x2 result; - - float tx = centerPoint.X * (1 - scale); - float ty = centerPoint.Y * (1 - scale); - - result.M11 = scale; - result.M12 = 0.0f; - result.M21 = 0.0f; - result.M22 = scale; - result.M31 = tx; - result.M32 = ty; - - return result; - } - - /// - /// Creates a skew matrix from the given angles in radians. - /// - /// The X angle, in radians. - /// The Y angle, in radians. - /// A skew matrix. - public static Matrix3x2 CreateSkew(float radiansX, float radiansY) - { - Matrix3x2 result; - - float xTan = (float)Math.Tan(radiansX); - float yTan = (float)Math.Tan(radiansY); - - result.M11 = 1.0f; - result.M12 = yTan; - result.M21 = xTan; - result.M22 = 1.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - - return result; - } - - /// - /// Creates a skew matrix from the given angles in radians and a center point. - /// - /// The X angle, in radians. - /// The Y angle, in radians. - /// The center point. - /// A skew matrix. - public static Matrix3x2 CreateSkew(float radiansX, float radiansY, Vector2 centerPoint) - { - Matrix3x2 result; - - float xTan = (float)Math.Tan(radiansX); - float yTan = (float)Math.Tan(radiansY); - - float tx = -centerPoint.Y * xTan; - float ty = -centerPoint.X * yTan; - - result.M11 = 1.0f; - result.M12 = yTan; - result.M21 = xTan; - result.M22 = 1.0f; - result.M31 = tx; - result.M32 = ty; - - return result; - } - - /// - /// Creates a rotation matrix using the given rotation in radians. - /// - /// The amount of rotation, in radians. - /// A rotation matrix. - public static Matrix3x2 CreateRotation(float radians) - { - Matrix3x2 result; - - radians = (float)Math.IEEERemainder(radians, Math.PI * 2); - - float c, s; - - const float epsilon = 0.001f * (float)Math.PI / 180f; // 0.1% of a degree - - if (radians > -epsilon && radians < epsilon) - { - // Exact case for zero rotation. - c = 1; - s = 0; - } - else if (radians > Math.PI / 2 - epsilon && radians < Math.PI / 2 + epsilon) - { - // Exact case for 90 degree rotation. - c = 0; - s = 1; - } - else if (radians < -Math.PI + epsilon || radians > Math.PI - epsilon) - { - // Exact case for 180 degree rotation. - c = -1; - s = 0; - } - else if (radians > -Math.PI / 2 - epsilon && radians < -Math.PI / 2 + epsilon) - { - // Exact case for 270 degree rotation. - c = 0; - s = -1; - } - else - { - // Arbitrary rotation. - c = (float)Math.Cos(radians); - s = (float)Math.Sin(radians); - } - - // [ c s ] - // [ -s c ] - // [ 0 0 ] - result.M11 = c; - result.M12 = s; - result.M21 = -s; - result.M22 = c; - result.M31 = 0.0f; - result.M32 = 0.0f; - - return result; - } - - /// - /// Creates a rotation matrix using the given rotation in radians and a center point. - /// - /// The amount of rotation, in radians. - /// The center point. - /// A rotation matrix. - public static Matrix3x2 CreateRotation(float radians, Vector2 centerPoint) - { - Matrix3x2 result; - - radians = (float)Math.IEEERemainder(radians, Math.PI * 2); - - float c, s; - - const float epsilon = 0.001f * (float)Math.PI / 180f; // 0.1% of a degree - - if (radians > -epsilon && radians < epsilon) - { - // Exact case for zero rotation. - c = 1; - s = 0; - } - else if (radians > Math.PI / 2 - epsilon && radians < Math.PI / 2 + epsilon) - { - // Exact case for 90 degree rotation. - c = 0; - s = 1; - } - else if (radians < -Math.PI + epsilon || radians > Math.PI - epsilon) - { - // Exact case for 180 degree rotation. - c = -1; - s = 0; - } - else if (radians > -Math.PI / 2 - epsilon && radians < -Math.PI / 2 + epsilon) - { - // Exact case for 270 degree rotation. - c = 0; - s = -1; - } - else - { - // Arbitrary rotation. - c = (float)Math.Cos(radians); - s = (float)Math.Sin(radians); - } - - float x = centerPoint.X * (1 - c) + centerPoint.Y * s; - float y = centerPoint.Y * (1 - c) - centerPoint.X * s; - - // [ c s ] - // [ -s c ] - // [ x y ] - result.M11 = c; - result.M12 = s; - result.M21 = -s; - result.M22 = c; - result.M31 = x; - result.M32 = y; - - return result; - } - - /// - /// Calculates the determinant for this matrix. - /// The determinant is calculated by expanding the matrix with a third column whose values are (0,0,1). - /// - /// The determinant. - public float GetDeterminant() - { - // There isn't actually any such thing as a determinant for a non-square matrix, - // but this 3x2 type is really just an optimization of a 3x3 where we happen to - // know the rightmost column is always (0, 0, 1). So we expand to 3x3 format: - // - // [ M11, M12, 0 ] - // [ M21, M22, 0 ] - // [ M31, M32, 1 ] - // - // Sum the diagonal products: - // (M11 * M22 * 1) + (M12 * 0 * M31) + (0 * M21 * M32) - // - // Subtract the opposite diagonal products: - // (M31 * M22 * 0) + (M32 * 0 * M11) + (1 * M21 * M12) - // - // Collapse out the constants and oh look, this is just a 2x2 determinant! - - return (M11 * M22) - (M21 * M12); - } - - /// - /// Attempts to invert the given matrix. If the operation succeeds, the inverted matrix is stored in the result parameter. - /// - /// The source matrix. - /// The output matrix. - /// True if the operation succeeded, False otherwise. - public static bool Invert(Matrix3x2 matrix, out Matrix3x2 result) - { - float det = (matrix.M11 * matrix.M22) - (matrix.M21 * matrix.M12); - - if (Math.Abs(det) < float.Epsilon) - { - result = new Matrix3x2(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN); - return false; - } - - float invDet = 1.0f / det; - - result.M11 = matrix.M22 * invDet; - result.M12 = -matrix.M12 * invDet; - result.M21 = -matrix.M21 * invDet; - result.M22 = matrix.M11 * invDet; - result.M31 = (matrix.M21 * matrix.M32 - matrix.M31 * matrix.M22) * invDet; - result.M32 = (matrix.M31 * matrix.M12 - matrix.M11 * matrix.M32) * invDet; - - return true; - } - - /// - /// Linearly interpolates from matrix1 to matrix2, based on the third parameter. - /// - /// The first source matrix. - /// The second source matrix. - /// The relative weighting of matrix2. - /// The interpolated matrix. - public static Matrix3x2 Lerp(Matrix3x2 matrix1, Matrix3x2 matrix2, float amount) - { - Matrix3x2 result; - - // First row - result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount; - result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount; - - // Second row - result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount; - result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount; - - // Third row - result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount; - result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount; - - return result; - } - - /// - /// Negates the given matrix by multiplying all values by -1. - /// - /// The source matrix. - /// The negated matrix. - public static Matrix3x2 Negate(Matrix3x2 value) - { - Matrix3x2 result; - - result.M11 = -value.M11; - result.M12 = -value.M12; - result.M21 = -value.M21; - result.M22 = -value.M22; - result.M31 = -value.M31; - result.M32 = -value.M32; - - return result; - } - - /// - /// Adds each matrix element in value1 with its corresponding element in value2. - /// - /// The first source matrix. - /// The second source matrix. - /// The matrix containing the summed values. - public static Matrix3x2 Add(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 result; - - result.M11 = value1.M11 + value2.M11; - result.M12 = value1.M12 + value2.M12; - result.M21 = value1.M21 + value2.M21; - result.M22 = value1.M22 + value2.M22; - result.M31 = value1.M31 + value2.M31; - result.M32 = value1.M32 + value2.M32; - - return result; - } - - /// - /// Subtracts each matrix element in value2 from its corresponding element in value1. - /// - /// The first source matrix. - /// The second source matrix. - /// The matrix containing the resulting values. - public static Matrix3x2 Subtract(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 result; - - result.M11 = value1.M11 - value2.M11; - result.M12 = value1.M12 - value2.M12; - result.M21 = value1.M21 - value2.M21; - result.M22 = value1.M22 - value2.M22; - result.M31 = value1.M31 - value2.M31; - result.M32 = value1.M32 - value2.M32; - - return result; - } - - /// - /// Multiplies two matrices together and returns the resulting matrix. - /// - /// The first source matrix. - /// The second source matrix. - /// The product matrix. - public static Matrix3x2 Multiply(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 result; - - // First row - result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21; - result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22; - - // Second row - result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21; - result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22; - - // Third row - result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31; - result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32; - - return result; - } - - /// - /// Scales all elements in a matrix by the given scalar factor. - /// - /// The source matrix. - /// The scaling value to use. - /// The resulting matrix. - public static Matrix3x2 Multiply(Matrix3x2 value1, float value2) - { - Matrix3x2 result; - - result.M11 = value1.M11 * value2; - result.M12 = value1.M12 * value2; - result.M21 = value1.M21 * value2; - result.M22 = value1.M22 * value2; - result.M31 = value1.M31 * value2; - result.M32 = value1.M32 * value2; - - return result; - } - - /// - /// Negates the given matrix by multiplying all values by -1. - /// - /// The source matrix. - /// The negated matrix. - public static Matrix3x2 operator -(Matrix3x2 value) - { - Matrix3x2 m; - - m.M11 = -value.M11; - m.M12 = -value.M12; - m.M21 = -value.M21; - m.M22 = -value.M22; - m.M31 = -value.M31; - m.M32 = -value.M32; - - return m; - } - - /// - /// Adds each matrix element in value1 with its corresponding element in value2. - /// - /// The first source matrix. - /// The second source matrix. - /// The matrix containing the summed values. - public static Matrix3x2 operator +(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 m; - - m.M11 = value1.M11 + value2.M11; - m.M12 = value1.M12 + value2.M12; - m.M21 = value1.M21 + value2.M21; - m.M22 = value1.M22 + value2.M22; - m.M31 = value1.M31 + value2.M31; - m.M32 = value1.M32 + value2.M32; - - return m; - } - - /// - /// Subtracts each matrix element in value2 from its corresponding element in value1. - /// - /// The first source matrix. - /// The second source matrix. - /// The matrix containing the resulting values. - public static Matrix3x2 operator -(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 m; - - m.M11 = value1.M11 - value2.M11; - m.M12 = value1.M12 - value2.M12; - m.M21 = value1.M21 - value2.M21; - m.M22 = value1.M22 - value2.M22; - m.M31 = value1.M31 - value2.M31; - m.M32 = value1.M32 - value2.M32; - - return m; - } - - /// - /// Multiplies two matrices together and returns the resulting matrix. - /// - /// The first source matrix. - /// The second source matrix. - /// The product matrix. - public static Matrix3x2 operator *(Matrix3x2 value1, Matrix3x2 value2) - { - Matrix3x2 m; - - // First row - m.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21; - m.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22; - - // Second row - m.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21; - m.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22; - - // Third row - m.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31; - m.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32; - - return m; - } - - /// - /// Scales all elements in a matrix by the given scalar factor. - /// - /// The source matrix. - /// The scaling value to use. - /// The resulting matrix. - public static Matrix3x2 operator *(Matrix3x2 value1, float value2) - { - Matrix3x2 m; - - m.M11 = value1.M11 * value2; - m.M12 = value1.M12 * value2; - m.M21 = value1.M21 * value2; - m.M22 = value1.M22 * value2; - m.M31 = value1.M31 * value2; - m.M32 = value1.M32 * value2; - - return m; - } - - /// - /// Returns a boolean indicating whether the given matrices are equal. - /// - /// The first source matrix. - /// The second source matrix. - /// True if the matrices are equal; False otherwise. - public static bool operator ==(Matrix3x2 value1, Matrix3x2 value2) - { - return (value1.M11 == value2.M11 && value1.M22 == value2.M22 && // Check diagonal element first for early out. - value1.M12 == value2.M12 && - value1.M21 == value2.M21 && - value1.M31 == value2.M31 && value1.M32 == value2.M32); - } - - /// - /// Returns a boolean indicating whether the given matrices are not equal. - /// - /// The first source matrix. - /// The second source matrix. - /// True if the matrices are not equal; False if they are equal. - public static bool operator !=(Matrix3x2 value1, Matrix3x2 value2) - { - return (value1.M11 != value2.M11 || value1.M12 != value2.M12 || - value1.M21 != value2.M21 || value1.M22 != value2.M22 || - value1.M31 != value2.M31 || value1.M32 != value2.M32); - } - - /// - /// Returns a boolean indicating whether the matrix is equal to the other given matrix. - /// - /// The other matrix to test equality against. - /// True if this matrix is equal to other; False otherwise. - public bool Equals(Matrix3x2 other) - { - return (M11 == other.M11 && M22 == other.M22 && // Check diagonal element first for early out. - M12 == other.M12 && - M21 == other.M21 && - M31 == other.M31 && M32 == other.M32); - } - - /// - /// Returns a boolean indicating whether the given Object is equal to this matrix instance. - /// - /// The Object to compare against. - /// True if the Object is equal to this matrix; False otherwise. - public override bool Equals(object obj) - { - if (obj is Matrix3x2) - { - return Equals((Matrix3x2)obj); - } - - return false; - } - - /// - /// Returns a String representing this matrix instance. - /// - /// The string representation. - public override string ToString() - { - CultureInfo ci = CultureInfo.CurrentCulture; - return String.Format(ci, "{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}", - M11.ToString(ci), M12.ToString(ci), - M21.ToString(ci), M22.ToString(ci), - M31.ToString(ci), M32.ToString(ci)); - } - - /// - /// Returns the hash code for this instance. - /// - /// The hash code. - public override int GetHashCode() - { - return M11.GetHashCode() + M12.GetHashCode() + - M21.GetHashCode() + M22.GetHashCode() + - M31.GetHashCode() + M32.GetHashCode(); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Matrix4x4.cs b/source/OrkEngine3D.Mathematics/Matrix4x4.cs deleted file mode 100644 index 011730a..0000000 --- a/source/OrkEngine3D.Mathematics/Matrix4x4.cs +++ /dev/null @@ -1,2216 +0,0 @@ -using System; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; - -namespace OrkEngine3D.Mathematics -{ - /// - /// A structure encapsulating a 4x4 matrix. - /// - public struct Matrix4x4 : IEquatable - { - #region Public Fields - /// - /// Value at row 1, column 1 of the matrix. - /// - public float M11; - /// - /// Value at row 1, column 2 of the matrix. - /// - public float M12; - /// - /// Value at row 1, column 3 of the matrix. - /// - public float M13; - /// - /// Value at row 1, column 4 of the matrix. - /// - public float M14; - - /// - /// Value at row 2, column 1 of the matrix. - /// - public float M21; - /// - /// Value at row 2, column 2 of the matrix. - /// - public float M22; - /// - /// Value at row 2, column 3 of the matrix. - /// - public float M23; - /// - /// Value at row 2, column 4 of the matrix. - /// - public float M24; - - /// - /// Value at row 3, column 1 of the matrix. - /// - public float M31; - /// - /// Value at row 3, column 2 of the matrix. - /// - public float M32; - /// - /// Value at row 3, column 3 of the matrix. - /// - public float M33; - /// - /// Value at row 3, column 4 of the matrix. - /// - public float M34; - - /// - /// Value at row 4, column 1 of the matrix. - /// - public float M41; - /// - /// Value at row 4, column 2 of the matrix. - /// - public float M42; - /// - /// Value at row 4, column 3 of the matrix. - /// - public float M43; - /// - /// Value at row 4, column 4 of the matrix. - /// - public float M44; - #endregion Public Fields - - private static readonly Matrix4x4 _identity = new Matrix4x4 - ( - 1f, 0f, 0f, 0f, - 0f, 1f, 0f, 0f, - 0f, 0f, 1f, 0f, - 0f, 0f, 0f, 1f - ); - - /// - /// Returns the multiplicative identity matrix. - /// - public static Matrix4x4 Identity - { - get { return _identity; } - } - - /// - /// Returns whether the matrix is the identity matrix. - /// - public bool IsIdentity - { - get - { - return M11 == 1f && M22 == 1f && M33 == 1f && M44 == 1f && // Check diagonal element first for early out. - M12 == 0f && M13 == 0f && M14 == 0f && - M21 == 0f && M23 == 0f && M24 == 0f && - M31 == 0f && M32 == 0f && M34 == 0f && - M41 == 0f && M42 == 0f && M43 == 0f; - } - } - - /// - /// Gets or sets the translation component of this matrix. - /// - public Vector3 Translation - { - get - { - return new Vector3(M41, M42, M43); - } - set - { - M41 = value.X; - M42 = value.Y; - M43 = value.Z; - } - } - - /// - /// Constructs a Matrix4x4 from the given components. - /// - public Matrix4x4(float m11, float m12, float m13, float m14, - float m21, float m22, float m23, float m24, - float m31, float m32, float m33, float m34, - float m41, float m42, float m43, float m44) - { - this.M11 = m11; - this.M12 = m12; - this.M13 = m13; - this.M14 = m14; - - this.M21 = m21; - this.M22 = m22; - this.M23 = m23; - this.M24 = m24; - - this.M31 = m31; - this.M32 = m32; - this.M33 = m33; - this.M34 = m34; - - this.M41 = m41; - this.M42 = m42; - this.M43 = m43; - this.M44 = m44; - } - - /// - /// Constructs a Matrix4x4 from the given Matrix3x2. - /// - /// The source Matrix3x2. - public Matrix4x4(Matrix3x2 value) - { - M11 = value.M11; - M12 = value.M12; - M13 = 0f; - M14 = 0f; - M21 = value.M21; - M22 = value.M22; - M23 = 0f; - M24 = 0f; - M31 = 0f; - M32 = 0f; - M33 = 1f; - M34 = 0f; - M41 = value.M31; - M42 = value.M32; - M43 = 0f; - M44 = 1f; - } - - /// - /// Creates a spherical billboard that rotates around a specified object position. - /// - /// Position of the object the billboard will rotate around. - /// Position of the camera. - /// The up vector of the camera. - /// The forward vector of the camera. - /// The created billboard matrix - public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector) - { - const float epsilon = 1e-4f; - - Vector3 zaxis = new Vector3( - objectPosition.X - cameraPosition.X, - objectPosition.Y - cameraPosition.Y, - objectPosition.Z - cameraPosition.Z); - - float norm = zaxis.LengthSquared(); - - if (norm < epsilon) - { - zaxis = -cameraForwardVector; - } - else - { - zaxis = Vector3.Multiply(zaxis, 1.0f / (float)Math.Sqrt(norm)); - } - - Vector3 xaxis = Vector3.Normalize(Vector3.Cross(cameraUpVector, zaxis)); - - Vector3 yaxis = Vector3.Cross(zaxis, xaxis); - - Matrix4x4 result; - - result.M11 = xaxis.X; - result.M12 = xaxis.Y; - result.M13 = xaxis.Z; - result.M14 = 0.0f; - result.M21 = yaxis.X; - result.M22 = yaxis.Y; - result.M23 = yaxis.Z; - result.M24 = 0.0f; - result.M31 = zaxis.X; - result.M32 = zaxis.Y; - result.M33 = zaxis.Z; - result.M34 = 0.0f; - - result.M41 = objectPosition.X; - result.M42 = objectPosition.Y; - result.M43 = objectPosition.Z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a cylindrical billboard that rotates around a specified axis. - /// - /// Position of the object the billboard will rotate around. - /// Position of the camera. - /// Axis to rotate the billboard around. - /// Forward vector of the camera. - /// Forward vector of the object. - /// The created billboard matrix. - public static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector) - { - const float epsilon = 1e-4f; - const float minAngle = 1.0f - (0.1f * ((float)Math.PI / 180.0f)); // 0.1 degrees - - // Treat the case when object and camera positions are too close. - Vector3 faceDir = new Vector3( - objectPosition.X - cameraPosition.X, - objectPosition.Y - cameraPosition.Y, - objectPosition.Z - cameraPosition.Z); - - float norm = faceDir.LengthSquared(); - - if (norm < epsilon) - { - faceDir = -cameraForwardVector; - } - else - { - faceDir = Vector3.Multiply(faceDir, (1.0f / (float)Math.Sqrt(norm))); - } - - Vector3 yaxis = rotateAxis; - Vector3 xaxis; - Vector3 zaxis; - - // Treat the case when angle between faceDir and rotateAxis is too close to 0. - float dot = Vector3.Dot(rotateAxis, faceDir); - - if (Math.Abs(dot) > minAngle) - { - zaxis = objectForwardVector; - - // Make sure passed values are useful for compute. - dot = Vector3.Dot(rotateAxis, zaxis); - - if (Math.Abs(dot) > minAngle) - { - zaxis = (Math.Abs(rotateAxis.Z) > minAngle) ? new Vector3(1, 0, 0) : new Vector3(0, 0, -1); - } - - xaxis = Vector3.Normalize(Vector3.Cross(rotateAxis, zaxis)); - zaxis = Vector3.Normalize(Vector3.Cross(xaxis, rotateAxis)); - } - else - { - xaxis = Vector3.Normalize(Vector3.Cross(rotateAxis, faceDir)); - zaxis = Vector3.Normalize(Vector3.Cross(xaxis, yaxis)); - } - - Matrix4x4 result; - - result.M11 = xaxis.X; - result.M12 = xaxis.Y; - result.M13 = xaxis.Z; - result.M14 = 0.0f; - result.M21 = yaxis.X; - result.M22 = yaxis.Y; - result.M23 = yaxis.Z; - result.M24 = 0.0f; - result.M31 = zaxis.X; - result.M32 = zaxis.Y; - result.M33 = zaxis.Z; - result.M34 = 0.0f; - - result.M41 = objectPosition.X; - result.M42 = objectPosition.Y; - result.M43 = objectPosition.Z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The amount to translate in each axis. - /// The translation matrix. - public static Matrix4x4 CreateTranslation(Vector3 position) - { - Matrix4x4 result; - - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = 1.0f; - result.M34 = 0.0f; - - result.M41 = position.X; - result.M42 = position.Y; - result.M43 = position.Z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The amount to translate on the X-axis. - /// The amount to translate on the Y-axis. - /// The amount to translate on the Z-axis. - /// The translation matrix. - public static Matrix4x4 CreateTranslation(float xPosition, float yPosition, float zPosition) - { - Matrix4x4 result; - - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = 1.0f; - result.M34 = 0.0f; - - result.M41 = xPosition; - result.M42 = yPosition; - result.M43 = zPosition; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a scaling matrix. - /// - /// Value to scale by on the X-axis. - /// Value to scale by on the Y-axis. - /// Value to scale by on the Z-axis. - /// The scaling matrix. - public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale) - { - Matrix4x4 result; - - result.M11 = xScale; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = yScale; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = zScale; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a scaling matrix with a center point. - /// - /// Value to scale by on the X-axis. - /// Value to scale by on the Y-axis. - /// Value to scale by on the Z-axis. - /// The center point. - /// The scaling matrix. - public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale, Vector3 centerPoint) - { - Matrix4x4 result; - - float tx = centerPoint.X * (1 - xScale); - float ty = centerPoint.Y * (1 - yScale); - float tz = centerPoint.Z * (1 - zScale); - - result.M11 = xScale; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = yScale; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = zScale; - result.M34 = 0.0f; - result.M41 = tx; - result.M42 = ty; - result.M43 = tz; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a scaling matrix. - /// - /// The vector containing the amount to scale by on each axis. - /// The scaling matrix. - public static Matrix4x4 CreateScale(Vector3 scales) - { - Matrix4x4 result; - - result.M11 = scales.X; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = scales.Y; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = scales.Z; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a scaling matrix with a center point. - /// - /// The vector containing the amount to scale by on each axis. - /// The center point. - /// The scaling matrix. - public static Matrix4x4 CreateScale(Vector3 scales, Vector3 centerPoint) - { - Matrix4x4 result; - - float tx = centerPoint.X * (1 - scales.X); - float ty = centerPoint.Y * (1 - scales.Y); - float tz = centerPoint.Z * (1 - scales.Z); - - result.M11 = scales.X; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = scales.Y; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = scales.Z; - result.M34 = 0.0f; - result.M41 = tx; - result.M42 = ty; - result.M43 = tz; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a uniform scaling matrix that scales equally on each axis. - /// - /// The uniform scaling factor. - /// The scaling matrix. - public static Matrix4x4 CreateScale(float scale) - { - Matrix4x4 result; - - result.M11 = scale; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = scale; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = scale; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a uniform scaling matrix that scales equally on each axis with a center point. - /// - /// The uniform scaling factor. - /// The center point. - /// The scaling matrix. - public static Matrix4x4 CreateScale(float scale, Vector3 centerPoint) - { - Matrix4x4 result; - - float tx = centerPoint.X * (1 - scale); - float ty = centerPoint.Y * (1 - scale); - float tz = centerPoint.Z * (1 - scale); - - result.M11 = scale; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = scale; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = scale; - result.M34 = 0.0f; - result.M41 = tx; - result.M42 = ty; - result.M43 = tz; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the X-axis. - /// - /// The amount, in radians, by which to rotate around the X-axis. - /// The rotation matrix. - public static Matrix4x4 CreateRotationX(float radians) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - // [ 1 0 0 0 ] - // [ 0 c s 0 ] - // [ 0 -s c 0 ] - // [ 0 0 0 1 ] - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = c; - result.M23 = s; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = -s; - result.M33 = c; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the X-axis, from a center point. - /// - /// The amount, in radians, by which to rotate around the X-axis. - /// The center point. - /// The rotation matrix. - public static Matrix4x4 CreateRotationX(float radians, Vector3 centerPoint) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - float y = centerPoint.Y * (1 - c) + centerPoint.Z * s; - float z = centerPoint.Z * (1 - c) - centerPoint.Y * s; - - // [ 1 0 0 0 ] - // [ 0 c s 0 ] - // [ 0 -s c 0 ] - // [ 0 y z 1 ] - result.M11 = 1.0f; - result.M12 = 0.0f; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = c; - result.M23 = s; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = -s; - result.M33 = c; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = y; - result.M43 = z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the Y-axis. - /// - /// The amount, in radians, by which to rotate around the Y-axis. - /// The rotation matrix. - public static Matrix4x4 CreateRotationY(float radians) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - // [ c 0 -s 0 ] - // [ 0 1 0 0 ] - // [ s 0 c 0 ] - // [ 0 0 0 1 ] - result.M11 = c; - result.M12 = 0.0f; - result.M13 = -s; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = s; - result.M32 = 0.0f; - result.M33 = c; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the Y-axis, from a center point. - /// - /// The amount, in radians, by which to rotate around the Y-axis. - /// The center point. - /// The rotation matrix. - public static Matrix4x4 CreateRotationY(float radians, Vector3 centerPoint) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - float x = centerPoint.X * (1 - c) - centerPoint.Z * s; - float z = centerPoint.Z * (1 - c) + centerPoint.X * s; - - // [ c 0 -s 0 ] - // [ 0 1 0 0 ] - // [ s 0 c 0 ] - // [ x 0 z 1 ] - result.M11 = c; - result.M12 = 0.0f; - result.M13 = -s; - result.M14 = 0.0f; - result.M21 = 0.0f; - result.M22 = 1.0f; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = s; - result.M32 = 0.0f; - result.M33 = c; - result.M34 = 0.0f; - result.M41 = x; - result.M42 = 0.0f; - result.M43 = z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the Z-axis. - /// - /// The amount, in radians, by which to rotate around the Z-axis. - /// The rotation matrix. - public static Matrix4x4 CreateRotationZ(float radians) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - // [ c s 0 0 ] - // [ -s c 0 0 ] - // [ 0 0 1 0 ] - // [ 0 0 0 1 ] - result.M11 = c; - result.M12 = s; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = -s; - result.M22 = c; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = 1.0f; - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix for rotating points around the Z-axis, from a center point. - /// - /// The amount, in radians, by which to rotate around the Z-axis. - /// The center point. - /// The rotation matrix. - public static Matrix4x4 CreateRotationZ(float radians, Vector3 centerPoint) - { - Matrix4x4 result; - - float c = (float)Math.Cos(radians); - float s = (float)Math.Sin(radians); - - float x = centerPoint.X * (1 - c) + centerPoint.Y * s; - float y = centerPoint.Y * (1 - c) - centerPoint.X * s; - - // [ c s 0 0 ] - // [ -s c 0 0 ] - // [ 0 0 1 0 ] - // [ x y 0 1 ] - result.M11 = c; - result.M12 = s; - result.M13 = 0.0f; - result.M14 = 0.0f; - result.M21 = -s; - result.M22 = c; - result.M23 = 0.0f; - result.M24 = 0.0f; - result.M31 = 0.0f; - result.M32 = 0.0f; - result.M33 = 1.0f; - result.M34 = 0.0f; - result.M41 = x; - result.M42 = y; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a matrix that rotates around an arbitrary vector. - /// - /// The axis to rotate around. - /// The angle to rotate around the given axis, in radians. - /// The rotation matrix. - public static Matrix4x4 CreateFromAxisAngle(Vector3 axis, float angle) - { - // a: angle - // x, y, z: unit vector for axis. - // - // Rotation matrix M can compute by using below equation. - // - // T T - // M = uu + (cos a)( I-uu ) + (sin a)S - // - // Where: - // - // u = ( x, y, z ) - // - // [ 0 -z y ] - // S = [ z 0 -x ] - // [ -y x 0 ] - // - // [ 1 0 0 ] - // I = [ 0 1 0 ] - // [ 0 0 1 ] - // - // - // [ xx+cosa*(1-xx) yx-cosa*yx-sina*z zx-cosa*xz+sina*y ] - // M = [ xy-cosa*yx+sina*z yy+cosa(1-yy) yz-cosa*yz-sina*x ] - // [ zx-cosa*zx-sina*y zy-cosa*zy+sina*x zz+cosa*(1-zz) ] - // - float x = axis.X, y = axis.Y, z = axis.Z; - float sa = (float)Math.Sin(angle), ca = (float)Math.Cos(angle); - float xx = x * x, yy = y * y, zz = z * z; - float xy = x * y, xz = x * z, yz = y * z; - - Matrix4x4 result; - - result.M11 = xx + ca * (1.0f - xx); - result.M12 = xy - ca * xy + sa * z; - result.M13 = xz - ca * xz - sa * y; - result.M14 = 0.0f; - result.M21 = xy - ca * xy - sa * z; - result.M22 = yy + ca * (1.0f - yy); - result.M23 = yz - ca * yz + sa * x; - result.M24 = 0.0f; - result.M31 = xz - ca * xz + sa * y; - result.M32 = yz - ca * yz - sa * x; - result.M33 = zz + ca * (1.0f - zz); - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a perspective projection matrix based on a field of view, aspect ratio, and near and far view plane distances. - /// - /// Field of view in the y direction, in radians. - /// Aspect ratio, defined as view space width divided by height. - /// Distance to the near view plane. - /// Distance to the far view plane. - /// The perspective projection matrix. - public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) - { - if (fieldOfView <= 0.0f || fieldOfView >= Math.PI) - throw new ArgumentOutOfRangeException("fieldOfView"); - - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("farPlaneDistance"); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - float yScale = 1.0f / (float)Math.Tan(fieldOfView * 0.5f); - float xScale = yScale / aspectRatio; - - Matrix4x4 result; - - result.M11 = xScale; - result.M12 = result.M13 = result.M14 = 0.0f; - - result.M22 = yScale; - result.M21 = result.M23 = result.M24 = 0.0f; - - result.M31 = result.M32 = 0.0f; - result.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - result.M34 = -1.0f; - - result.M41 = result.M42 = result.M44 = 0.0f; - result.M43 = nearPlaneDistance * farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - - return result; - } - - /// - /// Creates a perspective projection matrix from the given view volume dimensions. - /// - /// Width of the view volume at the near view plane. - /// Height of the view volume at the near view plane. - /// Distance to the near view plane. - /// Distance to the far view plane. - /// The perspective projection matrix. - public static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance) - { - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("farPlaneDistance"); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - Matrix4x4 result; - - result.M11 = 2.0f * nearPlaneDistance / width; - result.M12 = result.M13 = result.M14 = 0.0f; - - result.M22 = 2.0f * nearPlaneDistance / height; - result.M21 = result.M23 = result.M24 = 0.0f; - - result.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - result.M31 = result.M32 = 0.0f; - result.M34 = -1.0f; - - result.M41 = result.M42 = result.M44 = 0.0f; - result.M43 = nearPlaneDistance * farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - - return result; - } - - /// - /// Creates a customized, perspective projection matrix. - /// - /// Minimum x-value of the view volume at the near view plane. - /// Maximum x-value of the view volume at the near view plane. - /// Minimum y-value of the view volume at the near view plane. - /// Maximum y-value of the view volume at the near view plane. - /// Distance to the near view plane. - /// Distance to of the far view plane. - /// The perspective projection matrix. - public static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance) - { - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException("farPlaneDistance"); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException("nearPlaneDistance"); - - Matrix4x4 result; - - result.M11 = 2.0f * nearPlaneDistance / (right - left); - result.M12 = result.M13 = result.M14 = 0.0f; - - result.M22 = 2.0f * nearPlaneDistance / (top - bottom); - result.M21 = result.M23 = result.M24 = 0.0f; - - result.M31 = (left + right) / (right - left); - result.M32 = (top + bottom) / (top - bottom); - result.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - result.M34 = -1.0f; - - result.M43 = nearPlaneDistance * farPlaneDistance / (nearPlaneDistance - farPlaneDistance); - result.M41 = result.M42 = result.M44 = 0.0f; - - return result; - } - - /// - /// Creates an orthographic perspective matrix from the given view volume dimensions. - /// - /// Width of the view volume. - /// Height of the view volume. - /// Minimum Z-value of the view volume. - /// Maximum Z-value of the view volume. - /// The orthographic projection matrix. - public static Matrix4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane) - { - Matrix4x4 result; - - result.M11 = 2.0f / width; - result.M12 = result.M13 = result.M14 = 0.0f; - - result.M22 = 2.0f / height; - result.M21 = result.M23 = result.M24 = 0.0f; - - result.M33 = 1.0f / (zNearPlane - zFarPlane); - result.M31 = result.M32 = result.M34 = 0.0f; - - result.M41 = result.M42 = 0.0f; - result.M43 = zNearPlane / (zNearPlane - zFarPlane); - result.M44 = 1.0f; - - return result; - } - - /// - /// Builds a customized, orthographic projection matrix. - /// - /// Minimum X-value of the view volume. - /// Maximum X-value of the view volume. - /// Minimum Y-value of the view volume. - /// Maximum Y-value of the view volume. - /// Minimum Z-value of the view volume. - /// Maximum Z-value of the view volume. - /// The orthographic projection matrix. - public static Matrix4x4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane) - { - Matrix4x4 result; - - result.M11 = 2.0f / (right - left); - result.M12 = result.M13 = result.M14 = 0.0f; - - result.M22 = 2.0f / (top - bottom); - result.M21 = result.M23 = result.M24 = 0.0f; - - result.M33 = 1.0f / (zNearPlane - zFarPlane); - result.M31 = result.M32 = result.M34 = 0.0f; - - result.M41 = (left + right) / (left - right); - result.M42 = (top + bottom) / (bottom - top); - result.M43 = zNearPlane / (zNearPlane - zFarPlane); - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a view matrix. - /// - /// The position of the camera. - /// The target towards which the camera is pointing. - /// The direction that is "up" from the camera's point of view. - /// The view matrix. - public static Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) - { - Vector3 zaxis = Vector3.Normalize(cameraPosition - cameraTarget); - Vector3 xaxis = Vector3.Normalize(Vector3.Cross(cameraUpVector, zaxis)); - Vector3 yaxis = Vector3.Cross(zaxis, xaxis); - - Matrix4x4 result; - - result.M11 = xaxis.X; - result.M12 = yaxis.X; - result.M13 = zaxis.X; - result.M14 = 0.0f; - result.M21 = xaxis.Y; - result.M22 = yaxis.Y; - result.M23 = zaxis.Y; - result.M24 = 0.0f; - result.M31 = xaxis.Z; - result.M32 = yaxis.Z; - result.M33 = zaxis.Z; - result.M34 = 0.0f; - result.M41 = -Vector3.Dot(xaxis, cameraPosition); - result.M42 = -Vector3.Dot(yaxis, cameraPosition); - result.M43 = -Vector3.Dot(zaxis, cameraPosition); - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a world matrix with the specified parameters. - /// - /// The position of the object; used in translation operations. - /// Forward direction of the object. - /// Upward direction of the object; usually [0, 1, 0]. - /// The world matrix. - public static Matrix4x4 CreateWorld(Vector3 position, Vector3 forward, Vector3 up) - { - Vector3 zaxis = Vector3.Normalize(-forward); - Vector3 xaxis = Vector3.Normalize(Vector3.Cross(up, zaxis)); - Vector3 yaxis = Vector3.Cross(zaxis, xaxis); - - Matrix4x4 result; - - result.M11 = xaxis.X; - result.M12 = xaxis.Y; - result.M13 = xaxis.Z; - result.M14 = 0.0f; - result.M21 = yaxis.X; - result.M22 = yaxis.Y; - result.M23 = yaxis.Z; - result.M24 = 0.0f; - result.M31 = zaxis.X; - result.M32 = zaxis.Y; - result.M33 = zaxis.Z; - result.M34 = 0.0f; - result.M41 = position.X; - result.M42 = position.Y; - result.M43 = position.Z; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a rotation matrix from the given Quaternion rotation value. - /// - /// The source Quaternion. - /// The rotation matrix. - public static Matrix4x4 CreateFromQuaternion(Quaternion quaternion) - { - Matrix4x4 result; - - float xx = quaternion.X * quaternion.X; - float yy = quaternion.Y * quaternion.Y; - float zz = quaternion.Z * quaternion.Z; - - float xy = quaternion.X * quaternion.Y; - float wz = quaternion.Z * quaternion.W; - float xz = quaternion.Z * quaternion.X; - float wy = quaternion.Y * quaternion.W; - float yz = quaternion.Y * quaternion.Z; - float wx = quaternion.X * quaternion.W; - - result.M11 = 1.0f - 2.0f * (yy + zz); - result.M12 = 2.0f * (xy + wz); - result.M13 = 2.0f * (xz - wy); - result.M14 = 0.0f; - result.M21 = 2.0f * (xy - wz); - result.M22 = 1.0f - 2.0f * (zz + xx); - result.M23 = 2.0f * (yz + wx); - result.M24 = 0.0f; - result.M31 = 2.0f * (xz + wy); - result.M32 = 2.0f * (yz - wx); - result.M33 = 1.0f - 2.0f * (yy + xx); - result.M34 = 0.0f; - result.M41 = 0.0f; - result.M42 = 0.0f; - result.M43 = 0.0f; - result.M44 = 1.0f; - - return result; - } - - /// - /// Creates a rotation matrix from the specified yaw, pitch, and roll. - /// - /// Angle of rotation, in radians, around the Y-axis. - /// Angle of rotation, in radians, around the X-axis. - /// Angle of rotation, in radians, around the Z-axis. - /// The rotation matrix. - public static Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll) - { - Quaternion q = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll); - - return Matrix4x4.CreateFromQuaternion(q); - } - - /// - /// Creates a Matrix that flattens geometry into a specified Plane as if casting a shadow from a specified light source. - /// - /// The direction from which the light that will cast the shadow is coming. - /// The Plane onto which the new matrix should flatten geometry so as to cast a shadow. - /// A new Matrix that can be used to flatten geometry onto the specified plane from the specified direction. - public static Matrix4x4 CreateShadow(Vector3 lightDirection, Plane plane) - { - Plane p = Plane.Normalize(plane); - - float dot = p.Normal.X * lightDirection.X + p.Normal.Y * lightDirection.Y + p.Normal.Z * lightDirection.Z; - float a = -p.Normal.X; - float b = -p.Normal.Y; - float c = -p.Normal.Z; - float d = -p.D; - - Matrix4x4 result; - - result.M11 = a * lightDirection.X + dot; - result.M21 = b * lightDirection.X; - result.M31 = c * lightDirection.X; - result.M41 = d * lightDirection.X; - - result.M12 = a * lightDirection.Y; - result.M22 = b * lightDirection.Y + dot; - result.M32 = c * lightDirection.Y; - result.M42 = d * lightDirection.Y; - - result.M13 = a * lightDirection.Z; - result.M23 = b * lightDirection.Z; - result.M33 = c * lightDirection.Z + dot; - result.M43 = d * lightDirection.Z; - - result.M14 = 0.0f; - result.M24 = 0.0f; - result.M34 = 0.0f; - result.M44 = dot; - - return result; - } - - /// - /// Creates a Matrix that reflects the coordinate system about a specified Plane. - /// - /// The Plane about which to create a reflection. - /// A new matrix expressing the reflection. - public static Matrix4x4 CreateReflection(Plane value) - { - value = Plane.Normalize(value); - - float a = value.Normal.X; - float b = value.Normal.Y; - float c = value.Normal.Z; - - float fa = -2.0f * a; - float fb = -2.0f * b; - float fc = -2.0f * c; - - Matrix4x4 result; - - result.M11 = fa * a + 1.0f; - result.M12 = fb * a; - result.M13 = fc * a; - result.M14 = 0.0f; - - result.M21 = fa * b; - result.M22 = fb * b + 1.0f; - result.M23 = fc * b; - result.M24 = 0.0f; - - result.M31 = fa * c; - result.M32 = fb * c; - result.M33 = fc * c + 1.0f; - result.M34 = 0.0f; - - result.M41 = fa * value.D; - result.M42 = fb * value.D; - result.M43 = fc * value.D; - result.M44 = 1.0f; - - return result; - } - - /// - /// Calculates the determinant of the matrix. - /// - /// The determinant of the matrix. - public float GetDeterminant() - { - // | a b c d | | f g h | | e g h | | e f h | | e f g | - // | e f g h | = a | j k l | - b | i k l | + c | i j l | - d | i j k | - // | i j k l | | n o p | | m o p | | m n p | | m n o | - // | m n o p | - // - // | f g h | - // a | j k l | = a ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) ) - // | n o p | - // - // | e g h | - // b | i k l | = b ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) ) - // | m o p | - // - // | e f h | - // c | i j l | = c ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) ) - // | m n p | - // - // | e f g | - // d | i j k | = d ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) ) - // | m n o | - // - // Cost of operation - // 17 adds and 28 muls. - // - // add: 6 + 8 + 3 = 17 - // mul: 12 + 16 = 28 - - float a = M11, b = M12, c = M13, d = M14; - float e = M21, f = M22, g = M23, h = M24; - float i = M31, j = M32, k = M33, l = M34; - float m = M41, n = M42, o = M43, p = M44; - - float kp_lo = k * p - l * o; - float jp_ln = j * p - l * n; - float jo_kn = j * o - k * n; - float ip_lm = i * p - l * m; - float io_km = i * o - k * m; - float in_jm = i * n - j * m; - - return a * (f * kp_lo - g * jp_ln + h * jo_kn) - - b * (e * kp_lo - g * ip_lm + h * io_km) + - c * (e * jp_ln - f * ip_lm + h * in_jm) - - d * (e * jo_kn - f * io_km + g * in_jm); - } - - /// - /// Attempts to calculate the inverse of the given matrix. If successful, result will contain the inverted matrix. - /// - /// The source matrix to invert. - /// If successful, contains the inverted matrix. - /// True if the source matrix could be inverted; False otherwise. - public static bool Invert(Matrix4x4 matrix, out Matrix4x4 result) - { - // -1 - // If you have matrix M, inverse Matrix M can compute - // - // -1 1 - // M = --------- A - // det(M) - // - // A is adjugate (adjoint) of M, where, - // - // T - // A = C - // - // C is Cofactor matrix of M, where, - // i + j - // C = (-1) * det(M ) - // ij ij - // - // [ a b c d ] - // M = [ e f g h ] - // [ i j k l ] - // [ m n o p ] - // - // First Row - // 2 | f g h | - // C = (-1) | j k l | = + ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) ) - // 11 | n o p | - // - // 3 | e g h | - // C = (-1) | i k l | = - ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) ) - // 12 | m o p | - // - // 4 | e f h | - // C = (-1) | i j l | = + ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) ) - // 13 | m n p | - // - // 5 | e f g | - // C = (-1) | i j k | = - ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) ) - // 14 | m n o | - // - // Second Row - // 3 | b c d | - // C = (-1) | j k l | = - ( b ( kp - lo ) - c ( jp - ln ) + d ( jo - kn ) ) - // 21 | n o p | - // - // 4 | a c d | - // C = (-1) | i k l | = + ( a ( kp - lo ) - c ( ip - lm ) + d ( io - km ) ) - // 22 | m o p | - // - // 5 | a b d | - // C = (-1) | i j l | = - ( a ( jp - ln ) - b ( ip - lm ) + d ( in - jm ) ) - // 23 | m n p | - // - // 6 | a b c | - // C = (-1) | i j k | = + ( a ( jo - kn ) - b ( io - km ) + c ( in - jm ) ) - // 24 | m n o | - // - // Third Row - // 4 | b c d | - // C = (-1) | f g h | = + ( b ( gp - ho ) - c ( fp - hn ) + d ( fo - gn ) ) - // 31 | n o p | - // - // 5 | a c d | - // C = (-1) | e g h | = - ( a ( gp - ho ) - c ( ep - hm ) + d ( eo - gm ) ) - // 32 | m o p | - // - // 6 | a b d | - // C = (-1) | e f h | = + ( a ( fp - hn ) - b ( ep - hm ) + d ( en - fm ) ) - // 33 | m n p | - // - // 7 | a b c | - // C = (-1) | e f g | = - ( a ( fo - gn ) - b ( eo - gm ) + c ( en - fm ) ) - // 34 | m n o | - // - // Fourth Row - // 5 | b c d | - // C = (-1) | f g h | = - ( b ( gl - hk ) - c ( fl - hj ) + d ( fk - gj ) ) - // 41 | j k l | - // - // 6 | a c d | - // C = (-1) | e g h | = + ( a ( gl - hk ) - c ( el - hi ) + d ( ek - gi ) ) - // 42 | i k l | - // - // 7 | a b d | - // C = (-1) | e f h | = - ( a ( fl - hj ) - b ( el - hi ) + d ( ej - fi ) ) - // 43 | i j l | - // - // 8 | a b c | - // C = (-1) | e f g | = + ( a ( fk - gj ) - b ( ek - gi ) + c ( ej - fi ) ) - // 44 | i j k | - // - // Cost of operation - // 53 adds, 104 muls, and 1 div. - float a = matrix.M11, b = matrix.M12, c = matrix.M13, d = matrix.M14; - float e = matrix.M21, f = matrix.M22, g = matrix.M23, h = matrix.M24; - float i = matrix.M31, j = matrix.M32, k = matrix.M33, l = matrix.M34; - float m = matrix.M41, n = matrix.M42, o = matrix.M43, p = matrix.M44; - - float kp_lo = k * p - l * o; - float jp_ln = j * p - l * n; - float jo_kn = j * o - k * n; - float ip_lm = i * p - l * m; - float io_km = i * o - k * m; - float in_jm = i * n - j * m; - - float a11 = +(f * kp_lo - g * jp_ln + h * jo_kn); - float a12 = -(e * kp_lo - g * ip_lm + h * io_km); - float a13 = +(e * jp_ln - f * ip_lm + h * in_jm); - float a14 = -(e * jo_kn - f * io_km + g * in_jm); - - float det = a * a11 + b * a12 + c * a13 + d * a14; - - if (Math.Abs(det) < float.Epsilon) - { - result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN); - return false; - } - - float invDet = 1.0f / det; - - result.M11 = a11 * invDet; - result.M21 = a12 * invDet; - result.M31 = a13 * invDet; - result.M41 = a14 * invDet; - - result.M12 = -(b * kp_lo - c * jp_ln + d * jo_kn) * invDet; - result.M22 = +(a * kp_lo - c * ip_lm + d * io_km) * invDet; - result.M32 = -(a * jp_ln - b * ip_lm + d * in_jm) * invDet; - result.M42 = +(a * jo_kn - b * io_km + c * in_jm) * invDet; - - float gp_ho = g * p - h * o; - float fp_hn = f * p - h * n; - float fo_gn = f * o - g * n; - float ep_hm = e * p - h * m; - float eo_gm = e * o - g * m; - float en_fm = e * n - f * m; - - result.M13 = +(b * gp_ho - c * fp_hn + d * fo_gn) * invDet; - result.M23 = -(a * gp_ho - c * ep_hm + d * eo_gm) * invDet; - result.M33 = +(a * fp_hn - b * ep_hm + d * en_fm) * invDet; - result.M43 = -(a * fo_gn - b * eo_gm + c * en_fm) * invDet; - - float gl_hk = g * l - h * k; - float fl_hj = f * l - h * j; - float fk_gj = f * k - g * j; - float el_hi = e * l - h * i; - float ek_gi = e * k - g * i; - float ej_fi = e * j - f * i; - - result.M14 = -(b * gl_hk - c * fl_hj + d * fk_gj) * invDet; - result.M24 = +(a * gl_hk - c * el_hi + d * ek_gi) * invDet; - result.M34 = -(a * fl_hj - b * el_hi + d * ej_fi) * invDet; - result.M44 = +(a * fk_gj - b * ek_gi + c * ej_fi) * invDet; - - return true; - } - - struct CanonicalBasis - { - public Vector3 Row0; - public Vector3 Row1; - public Vector3 Row2; - }; - - /* - [System.Security.SecuritySafeCritical] - struct VectorBasis - { - public unsafe Vector3* Element0; - public unsafe Vector3* Element1; - public unsafe Vector3* Element2; - } - - /// - /// Attempts to extract the scale, translation, and rotation components from the given scale/rotation/translation matrix. - /// If successful, the out parameters will contained the extracted values. - /// - /// The source matrix. - /// The scaling component of the transformation matrix. - /// The rotation component of the transformation matrix. - /// The translation component of the transformation matrix - /// True if the source matrix was successfully decomposed; False otherwise. - [System.Security.SecuritySafeCritical] - public static bool Decompose(Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation) - { - bool result = true; - - unsafe - { - fixed (Vector3* scaleBase = &scale) - { - float* pfScales = (float*)scaleBase; - const float EPSILON = 0.0001f; - float det; - - VectorBasis vectorBasis; - Vector3** pVectorBasis = (Vector3**)&vectorBasis; - - Matrix4x4 matTemp = Matrix4x4.Identity; - CanonicalBasis canonicalBasis = new CanonicalBasis(); - Vector3* pCanonicalBasis = &canonicalBasis.Row0; - - canonicalBasis.Row0 = new Vector3(1.0f, 0.0f, 0.0f); - canonicalBasis.Row1 = new Vector3(0.0f, 1.0f, 0.0f); - canonicalBasis.Row2 = new Vector3(0.0f, 0.0f, 1.0f); - - translation = new Vector3( - matrix.M41, - matrix.M42, - matrix.M43); - - pVectorBasis[0] = (Vector3*)&matTemp.M11; - pVectorBasis[1] = (Vector3*)&matTemp.M21; - pVectorBasis[2] = (Vector3*)&matTemp.M31; - - *(pVectorBasis[0]) = new Vector3(matrix.M11, matrix.M12, matrix.M13); - *(pVectorBasis[1]) = new Vector3(matrix.M21, matrix.M22, matrix.M23); - *(pVectorBasis[2]) = new Vector3(matrix.M31, matrix.M32, matrix.M33); - - scale.X = pVectorBasis[0]->Length(); - scale.Y = pVectorBasis[1]->Length(); - scale.Z = pVectorBasis[2]->Length(); - - uint a, b, c; - #region Ranking - float x = pfScales[0], y = pfScales[1], z = pfScales[2]; - if (x < y) - { - if (y < z) - { - a = 2; - b = 1; - c = 0; - } - else - { - a = 1; - - if (x < z) - { - b = 2; - c = 0; - } - else - { - b = 0; - c = 2; - } - } - } - else - { - if (x < z) - { - a = 2; - b = 0; - c = 1; - } - else - { - a = 0; - - if (y < z) - { - b = 2; - c = 1; - } - else - { - b = 1; - c = 2; - } - } - } - #endregion - - if (pfScales[a] < EPSILON) - { - *(pVectorBasis[a]) = pCanonicalBasis[a]; - } - - *pVectorBasis[a] = Vector3.Normalize(*pVectorBasis[a]); - - if (pfScales[b] < EPSILON) - { - uint cc; - float fAbsX, fAbsY, fAbsZ; - - fAbsX = (float)Math.Abs(pVectorBasis[a]->X); - fAbsY = (float)Math.Abs(pVectorBasis[a]->Y); - fAbsZ = (float)Math.Abs(pVectorBasis[a]->Z); - - #region Ranking - if (fAbsX < fAbsY) - { - if (fAbsY < fAbsZ) - { - cc = 0; - } - else - { - if (fAbsX < fAbsZ) - { - cc = 0; - } - else - { - cc = 2; - } - } - } - else - { - if (fAbsX < fAbsZ) - { - cc = 1; - } - else - { - if (fAbsY < fAbsZ) - { - cc = 1; - } - else - { - cc = 2; - } - } - } - #endregion - - *pVectorBasis[b] = Vector3.Cross(*pVectorBasis[a], *(pCanonicalBasis + cc)); - } - - *pVectorBasis[b] = Vector3.Normalize(*pVectorBasis[b]); - - if (pfScales[c] < EPSILON) - { - *pVectorBasis[c] = Vector3.Cross(*pVectorBasis[a], *pVectorBasis[b]); - } - - *pVectorBasis[c] = Vector3.Normalize(*pVectorBasis[c]); - - det = matTemp.GetDeterminant(); - - // use Kramer's rule to check for handedness of coordinate system - if (det < 0.0f) - { - // switch coordinate system by negating the scale and inverting the basis vector on the x-axis - pfScales[a] = -pfScales[a]; - *pVectorBasis[a] = -(*pVectorBasis[a]); - - det = -det; - } - - det -= 1.0f; - det *= det; - - if ((EPSILON < det)) - { - // Non-SRT matrix encountered - rotation = Quaternion.Identity; - result = false; - } - else - { - // generate the quaternion from the matrix - rotation = Quaternion.CreateFromRotationMatrix(matTemp); - } - } - } - - return result; - } - */ - - /// - /// Transforms the given matrix by applying the given Quaternion rotation. - /// - /// The source matrix to transform. - /// The rotation to apply. - /// The transformed matrix. - public static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation) - { - // Compute rotation matrix. - float x2 = rotation.X + rotation.X; - float y2 = rotation.Y + rotation.Y; - float z2 = rotation.Z + rotation.Z; - - float wx2 = rotation.W * x2; - float wy2 = rotation.W * y2; - float wz2 = rotation.W * z2; - float xx2 = rotation.X * x2; - float xy2 = rotation.X * y2; - float xz2 = rotation.X * z2; - float yy2 = rotation.Y * y2; - float yz2 = rotation.Y * z2; - float zz2 = rotation.Z * z2; - - float q11 = 1.0f - yy2 - zz2; - float q21 = xy2 - wz2; - float q31 = xz2 + wy2; - - float q12 = xy2 + wz2; - float q22 = 1.0f - xx2 - zz2; - float q32 = yz2 - wx2; - - float q13 = xz2 - wy2; - float q23 = yz2 + wx2; - float q33 = 1.0f - xx2 - yy2; - - Matrix4x4 result; - - // First row - result.M11 = value.M11 * q11 + value.M12 * q21 + value.M13 * q31; - result.M12 = value.M11 * q12 + value.M12 * q22 + value.M13 * q32; - result.M13 = value.M11 * q13 + value.M12 * q23 + value.M13 * q33; - result.M14 = value.M14; - - // Second row - result.M21 = value.M21 * q11 + value.M22 * q21 + value.M23 * q31; - result.M22 = value.M21 * q12 + value.M22 * q22 + value.M23 * q32; - result.M23 = value.M21 * q13 + value.M22 * q23 + value.M23 * q33; - result.M24 = value.M24; - - // Third row - result.M31 = value.M31 * q11 + value.M32 * q21 + value.M33 * q31; - result.M32 = value.M31 * q12 + value.M32 * q22 + value.M33 * q32; - result.M33 = value.M31 * q13 + value.M32 * q23 + value.M33 * q33; - result.M34 = value.M34; - - // Fourth row - result.M41 = value.M41 * q11 + value.M42 * q21 + value.M43 * q31; - result.M42 = value.M41 * q12 + value.M42 * q22 + value.M43 * q32; - result.M43 = value.M41 * q13 + value.M42 * q23 + value.M43 * q33; - result.M44 = value.M44; - - return result; - } - - /// - /// Transposes the rows and columns of a matrix. - /// - /// The source matrix. - /// The transposed matrix. - public static Matrix4x4 Transpose(Matrix4x4 matrix) - { - Matrix4x4 result; - - result.M11 = matrix.M11; - result.M12 = matrix.M21; - result.M13 = matrix.M31; - result.M14 = matrix.M41; - result.M21 = matrix.M12; - result.M22 = matrix.M22; - result.M23 = matrix.M32; - result.M24 = matrix.M42; - result.M31 = matrix.M13; - result.M32 = matrix.M23; - result.M33 = matrix.M33; - result.M34 = matrix.M43; - result.M41 = matrix.M14; - result.M42 = matrix.M24; - result.M43 = matrix.M34; - result.M44 = matrix.M44; - - return result; - } - - /// - /// Linearly interpolates between the corresponding values of two matrices. - /// - /// The first source matrix. - /// The second source matrix. - /// The relative weight of the second source matrix. - /// The interpolated matrix. - public static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount) - { - Matrix4x4 result; - - // First row - result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount; - result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount; - result.M13 = matrix1.M13 + (matrix2.M13 - matrix1.M13) * amount; - result.M14 = matrix1.M14 + (matrix2.M14 - matrix1.M14) * amount; - - // Second row - result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount; - result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount; - result.M23 = matrix1.M23 + (matrix2.M23 - matrix1.M23) * amount; - result.M24 = matrix1.M24 + (matrix2.M24 - matrix1.M24) * amount; - - // Third row - result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount; - result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount; - result.M33 = matrix1.M33 + (matrix2.M33 - matrix1.M33) * amount; - result.M34 = matrix1.M34 + (matrix2.M34 - matrix1.M34) * amount; - - // Fourth row - result.M41 = matrix1.M41 + (matrix2.M41 - matrix1.M41) * amount; - result.M42 = matrix1.M42 + (matrix2.M42 - matrix1.M42) * amount; - result.M43 = matrix1.M43 + (matrix2.M43 - matrix1.M43) * amount; - result.M44 = matrix1.M44 + (matrix2.M44 - matrix1.M44) * amount; - - return result; - } - - /// - /// Returns a new matrix with the negated elements of the given matrix. - /// - /// The source matrix. - /// The negated matrix. - public static Matrix4x4 Negate(Matrix4x4 value) - { - Matrix4x4 result; - - result.M11 = -value.M11; - result.M12 = -value.M12; - result.M13 = -value.M13; - result.M14 = -value.M14; - result.M21 = -value.M21; - result.M22 = -value.M22; - result.M23 = -value.M23; - result.M24 = -value.M24; - result.M31 = -value.M31; - result.M32 = -value.M32; - result.M33 = -value.M33; - result.M34 = -value.M34; - result.M41 = -value.M41; - result.M42 = -value.M42; - result.M43 = -value.M43; - result.M44 = -value.M44; - - return result; - } - - /// - /// Adds two matrices together. - /// - /// The first source matrix. - /// The second source matrix. - /// The resulting matrix. - public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 result; - - result.M11 = value1.M11 + value2.M11; - result.M12 = value1.M12 + value2.M12; - result.M13 = value1.M13 + value2.M13; - result.M14 = value1.M14 + value2.M14; - result.M21 = value1.M21 + value2.M21; - result.M22 = value1.M22 + value2.M22; - result.M23 = value1.M23 + value2.M23; - result.M24 = value1.M24 + value2.M24; - result.M31 = value1.M31 + value2.M31; - result.M32 = value1.M32 + value2.M32; - result.M33 = value1.M33 + value2.M33; - result.M34 = value1.M34 + value2.M34; - result.M41 = value1.M41 + value2.M41; - result.M42 = value1.M42 + value2.M42; - result.M43 = value1.M43 + value2.M43; - result.M44 = value1.M44 + value2.M44; - - return result; - } - - /// - /// Subtracts the second matrix from the first. - /// - /// The first source matrix. - /// The second source matrix. - /// The result of the subtraction. - public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 result; - - result.M11 = value1.M11 - value2.M11; - result.M12 = value1.M12 - value2.M12; - result.M13 = value1.M13 - value2.M13; - result.M14 = value1.M14 - value2.M14; - result.M21 = value1.M21 - value2.M21; - result.M22 = value1.M22 - value2.M22; - result.M23 = value1.M23 - value2.M23; - result.M24 = value1.M24 - value2.M24; - result.M31 = value1.M31 - value2.M31; - result.M32 = value1.M32 - value2.M32; - result.M33 = value1.M33 - value2.M33; - result.M34 = value1.M34 - value2.M34; - result.M41 = value1.M41 - value2.M41; - result.M42 = value1.M42 - value2.M42; - result.M43 = value1.M43 - value2.M43; - result.M44 = value1.M44 - value2.M44; - - return result; - } - - /// - /// Multiplies a matrix by another matrix. - /// - /// The first source matrix. - /// The second source matrix. - /// The result of the multiplication. - public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 result; - - // First row - result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41; - result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42; - result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43; - result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44; - - // Second row - result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41; - result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42; - result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43; - result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44; - - // Third row - result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41; - result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42; - result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43; - result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44; - - // Fourth row - result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41; - result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42; - result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43; - result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44; - - return result; - } - - /// - /// Multiplies a matrix by a scalar value. - /// - /// The source matrix. - /// The scaling factor. - /// The scaled matrix. - public static Matrix4x4 Multiply(Matrix4x4 value1, float value2) - { - Matrix4x4 result; - - result.M11 = value1.M11 * value2; - result.M12 = value1.M12 * value2; - result.M13 = value1.M13 * value2; - result.M14 = value1.M14 * value2; - result.M21 = value1.M21 * value2; - result.M22 = value1.M22 * value2; - result.M23 = value1.M23 * value2; - result.M24 = value1.M24 * value2; - result.M31 = value1.M31 * value2; - result.M32 = value1.M32 * value2; - result.M33 = value1.M33 * value2; - result.M34 = value1.M34 * value2; - result.M41 = value1.M41 * value2; - result.M42 = value1.M42 * value2; - result.M43 = value1.M43 * value2; - result.M44 = value1.M44 * value2; - - return result; - } - - /// - /// Returns a new matrix with the negated elements of the given matrix. - /// - /// The source matrix. - /// The negated matrix. - public static Matrix4x4 operator -(Matrix4x4 value) - { - Matrix4x4 m; - - m.M11 = -value.M11; - m.M12 = -value.M12; - m.M13 = -value.M13; - m.M14 = -value.M14; - m.M21 = -value.M21; - m.M22 = -value.M22; - m.M23 = -value.M23; - m.M24 = -value.M24; - m.M31 = -value.M31; - m.M32 = -value.M32; - m.M33 = -value.M33; - m.M34 = -value.M34; - m.M41 = -value.M41; - m.M42 = -value.M42; - m.M43 = -value.M43; - m.M44 = -value.M44; - - return m; - } - - /// - /// Adds two matrices together. - /// - /// The first source matrix. - /// The second source matrix. - /// The resulting matrix. - public static Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 m; - - m.M11 = value1.M11 + value2.M11; - m.M12 = value1.M12 + value2.M12; - m.M13 = value1.M13 + value2.M13; - m.M14 = value1.M14 + value2.M14; - m.M21 = value1.M21 + value2.M21; - m.M22 = value1.M22 + value2.M22; - m.M23 = value1.M23 + value2.M23; - m.M24 = value1.M24 + value2.M24; - m.M31 = value1.M31 + value2.M31; - m.M32 = value1.M32 + value2.M32; - m.M33 = value1.M33 + value2.M33; - m.M34 = value1.M34 + value2.M34; - m.M41 = value1.M41 + value2.M41; - m.M42 = value1.M42 + value2.M42; - m.M43 = value1.M43 + value2.M43; - m.M44 = value1.M44 + value2.M44; - - return m; - } - - /// - /// Subtracts the second matrix from the first. - /// - /// The first source matrix. - /// The second source matrix. - /// The result of the subtraction. - public static Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 m; - - m.M11 = value1.M11 - value2.M11; - m.M12 = value1.M12 - value2.M12; - m.M13 = value1.M13 - value2.M13; - m.M14 = value1.M14 - value2.M14; - m.M21 = value1.M21 - value2.M21; - m.M22 = value1.M22 - value2.M22; - m.M23 = value1.M23 - value2.M23; - m.M24 = value1.M24 - value2.M24; - m.M31 = value1.M31 - value2.M31; - m.M32 = value1.M32 - value2.M32; - m.M33 = value1.M33 - value2.M33; - m.M34 = value1.M34 - value2.M34; - m.M41 = value1.M41 - value2.M41; - m.M42 = value1.M42 - value2.M42; - m.M43 = value1.M43 - value2.M43; - m.M44 = value1.M44 - value2.M44; - - return m; - } - - /// - /// Multiplies a matrix by another matrix. - /// - /// The first source matrix. - /// The second source matrix. - /// The result of the multiplication. - public static Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2) - { - Matrix4x4 m; - - // First row - m.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41; - m.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42; - m.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43; - m.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44; - - // Second row - m.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41; - m.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42; - m.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43; - m.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44; - - // Third row - m.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41; - m.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42; - m.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43; - m.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44; - - // Fourth row - m.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41; - m.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42; - m.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43; - m.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44; - - return m; - } - - /// - /// Multiplies a matrix by a scalar value. - /// - /// The source matrix. - /// The scaling factor. - /// The scaled matrix. - public static Matrix4x4 operator *(Matrix4x4 value1, float value2) - { - Matrix4x4 m; - - m.M11 = value1.M11 * value2; - m.M12 = value1.M12 * value2; - m.M13 = value1.M13 * value2; - m.M14 = value1.M14 * value2; - m.M21 = value1.M21 * value2; - m.M22 = value1.M22 * value2; - m.M23 = value1.M23 * value2; - m.M24 = value1.M24 * value2; - m.M31 = value1.M31 * value2; - m.M32 = value1.M32 * value2; - m.M33 = value1.M33 * value2; - m.M34 = value1.M34 * value2; - m.M41 = value1.M41 * value2; - m.M42 = value1.M42 * value2; - m.M43 = value1.M43 * value2; - m.M44 = value1.M44 * value2; - return m; - } - - /// - /// Returns a boolean indicating whether the given two matrices are equal. - /// - /// The first matrix to compare. - /// The second matrix to compare. - /// True if the given matrices are equal; False otherwise. - public static bool operator ==(Matrix4x4 value1, Matrix4x4 value2) - { - return (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && // Check diagonal element first for early out. - value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && - value1.M21 == value2.M21 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && - value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M34 == value2.M34 && - value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43); - } - - /// - /// Returns a boolean indicating whether the given two matrices are not equal. - /// - /// The first matrix to compare. - /// The second matrix to compare. - /// True if the given matrices are not equal; False if they are equal. - public static bool operator !=(Matrix4x4 value1, Matrix4x4 value2) - { - return (value1.M11 != value2.M11 || value1.M12 != value2.M12 || value1.M13 != value2.M13 || value1.M14 != value2.M14 || - value1.M21 != value2.M21 || value1.M22 != value2.M22 || value1.M23 != value2.M23 || value1.M24 != value2.M24 || - value1.M31 != value2.M31 || value1.M32 != value2.M32 || value1.M33 != value2.M33 || value1.M34 != value2.M34 || - value1.M41 != value2.M41 || value1.M42 != value2.M42 || value1.M43 != value2.M43 || value1.M44 != value2.M44); - } - - /// - /// Returns a boolean indicating whether this matrix instance is equal to the other given matrix. - /// - /// The matrix to compare this instance to. - /// True if the matrices are equal; False otherwise. - public bool Equals(Matrix4x4 other) - { - return (M11 == other.M11 && M22 == other.M22 && M33 == other.M33 && M44 == other.M44 && // Check diagonal element first for early out. - M12 == other.M12 && M13 == other.M13 && M14 == other.M14 && - M21 == other.M21 && M23 == other.M23 && M24 == other.M24 && - M31 == other.M31 && M32 == other.M32 && M34 == other.M34 && - M41 == other.M41 && M42 == other.M42 && M43 == other.M43); - } - - /// - /// Returns a boolean indicating whether the given Object is equal to this matrix instance. - /// - /// The Object to compare against. - /// True if the Object is equal to this matrix; False otherwise. - public override bool Equals(object obj) - { - if (obj is Matrix4x4) - { - return Equals((Matrix4x4)obj); - } - - return false; - } - - /// - /// Returns a String representing this matrix instance. - /// - /// The string representation. - public override string ToString() - { - CultureInfo ci = CultureInfo.CurrentCulture; - - return String.Format(ci, "{{ {{M11:{0} M12:{1} M13:{2} M14:{3}}} {{M21:{4} M22:{5} M23:{6} M24:{7}}} {{M31:{8} M32:{9} M33:{10} M34:{11}}} {{M41:{12} M42:{13} M43:{14} M44:{15}}} }}", - M11.ToString(ci), M12.ToString(ci), M13.ToString(ci), M14.ToString(ci), - M21.ToString(ci), M22.ToString(ci), M23.ToString(ci), M24.ToString(ci), - M31.ToString(ci), M32.ToString(ci), M33.ToString(ci), M34.ToString(ci), - M41.ToString(ci), M42.ToString(ci), M43.ToString(ci), M44.ToString(ci)); - } - - /// - /// Returns the hash code for this instance. - /// - /// The hash code. - public override int GetHashCode() - { - return M11.GetHashCode() + M12.GetHashCode() + M13.GetHashCode() + M14.GetHashCode() + - M21.GetHashCode() + M22.GetHashCode() + M23.GetHashCode() + M24.GetHashCode() + - M31.GetHashCode() + M32.GetHashCode() + M33.GetHashCode() + M34.GetHashCode() + - M41.GetHashCode() + M42.GetHashCode() + M43.GetHashCode() + M44.GetHashCode(); - } - } -} diff --git a/source/OrkEngine3D.Mathematics/OrkEngine3D.Mathematics.csproj b/source/OrkEngine3D.Mathematics/OrkEngine3D.Mathematics.csproj deleted file mode 100644 index fba06c8..0000000 --- a/source/OrkEngine3D.Mathematics/OrkEngine3D.Mathematics.csproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - Library - net6.0 - - - False - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/OrkEngine3D.Mathematics/Plane.cs b/source/OrkEngine3D.Mathematics/Plane.cs deleted file mode 100644 index a377d48..0000000 --- a/source/OrkEngine3D.Mathematics/Plane.cs +++ /dev/null @@ -1,791 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a plane in three dimensional space. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct Plane : IEquatable, IFormattable -{ - /// - /// The normal vector of the plane. - /// - public Vector3 Normal; - - /// - /// The distance of the plane along its normal from the origin. - /// - public float D; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Plane(float value) - { - Normal.X = Normal.Y = Normal.Z = D = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The X component of the normal. - /// The Y component of the normal. - /// The Z component of the normal. - /// The distance of the plane along its normal from the origin. - public Plane(float a, float b, float c, float d) - { - Normal.X = a; - Normal.Y = b; - Normal.Z = c; - D = d; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The normal of the plane. - /// The distance of the plane along its normal from the origin - public Plane(Vector3 value, float d) - { - Normal = value; - D = d; - } - - /// - /// Initializes a new instance of the struct. - /// - /// Any point that lies along the plane. - /// The normal of the plane. - public Plane(Vector3 point, Vector3 normal) - { - Normal = normal; - D = -Vector3.Dot(normal, point); - } - - /// - /// Initializes a new instance of the struct. - /// - /// First point of a triangle defining the plane. - /// Second point of a triangle defining the plane. - /// Third point of a triangle defining the plane. - public Plane(Vector3 point1, Vector3 point2, Vector3 point3) - { - float x1 = point2.X - point1.X; - float y1 = point2.Y - point1.Y; - float z1 = point2.Z - point1.Z; - float x2 = point3.X - point1.X; - float y2 = point3.Y - point1.Y; - float z2 = point3.Z - point1.Z; - float yz = (y1 * z2) - (z1 * y2); - float xz = (z1 * x2) - (x1 * z2); - float xy = (x1 * y2) - (y1 * x2); - float invPyth = 1.0f / (float)(Math.Sqrt((yz * yz) + (xz * xz) + (xy * xy))); - - Normal.X = yz * invPyth; - Normal.Y = xz * invPyth; - Normal.Z = xy * invPyth; - D = -((Normal.X * point1.X) + (Normal.Y * point1.Y) + (Normal.Z * point1.Z)); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the A, B, C, and D components of the plane. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Plane(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 4) - throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Plane."); - - Normal.X = values[0]; - Normal.Y = values[1]; - Normal.Z = values[2]; - D = values[3]; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the A, B, C, or D component, depending on the index. - /// The index of the component to access. Use 0 for the A component, 1 for the B component, 2 for the C component, and 3 for the D component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return Normal.X; - case 1: return Normal.Y; - case 2: return Normal.Z; - case 3: return D; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Plane run from 0 to 3, inclusive."); - } - - set - { - switch (index) - { - case 0: Normal.X = value; break; - case 1: Normal.Y = value; break; - case 2: Normal.Z = value; break; - case 3: D = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Plane run from 0 to 3, inclusive."); - } - } - } - - /// - /// Changes the coefficients of the normal vector of the plane to make it of unit length. - /// - public void Normalize() - { - float magnitude = 1.0f / (float)(Math.Sqrt((Normal.X * Normal.X) + (Normal.Y * Normal.Y) + (Normal.Z * Normal.Z))); - - Normal.X *= magnitude; - Normal.Y *= magnitude; - Normal.Z *= magnitude; - D *= magnitude; - } - - /// - /// Creates an array containing the elements of the plane. - /// - /// A four-element array containing the components of the plane. - public float[] ToArray() - { - return new float[] { Normal.X, Normal.Y, Normal.Z, D }; - } - - /// - /// Determines if there is an intersection between the current object and a point. - /// - /// The point to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref Vector3 point) - { - return Collision.PlaneIntersectsPoint(ref this, ref point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray) - { - float distance; - return Collision.RayIntersectsPlane(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out float distance) - { - return Collision.RayIntersectsPlane(ref ray, ref this, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out Vector3 point) - { - return Collision.RayIntersectsPlane(ref ray, ref this, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// Whether the two objects intersected. - public bool Intersects(ref Plane plane) - { - return Collision.PlaneIntersectsPlane(ref this, ref plane); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// When the method completes, contains the line of intersection - /// as a , or a zero ray if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Plane plane, out Ray line) - { - return Collision.PlaneIntersectsPlane(ref this, ref plane, out line); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triagnle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - return Collision.PlaneIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref BoundingBox box) - { - return Collision.PlaneIntersectsBox(ref this, ref box); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// Whether the two objects intersected. - public PlaneIntersectionType Intersects(ref BoundingSphere sphere) - { - return Collision.PlaneIntersectsSphere(ref this, ref sphere); - } - - /// - /// Scales each component of the plane by the given scaling factor. - /// - /// The plane to scale. - /// The amount by which to scale the plane. - /// When the method completes, contains the scaled plane. - public static void Multiply(ref Plane value, float scale, out Plane result) - { - result.Normal.X = value.Normal.X * scale; - result.Normal.Y = value.Normal.Y * scale; - result.Normal.Z = value.Normal.Z * scale; - result.D = value.D * scale; - } - - /// - /// Scales each component of the plane by the given scaling factor. - /// - /// The plane to scale. - /// The amount by which to scale the plane. - /// The scaled plane. - public static Plane Multiply(Plane value, float scale) - { - return new Plane(value.Normal.X * scale, value.Normal.Y * scale, value.Normal.Z * scale, value.D * scale); - } - - /// - /// Scales the distance component of the plane by the given scaling factor. - /// - /// The plane to scale. - /// The amount by which to scale the plane. - /// When the method completes, contains the scaled plane. - public static void Scale(ref Plane value, float scale, out Plane result) - { - result.Normal = value.Normal; - result.D = value.D * scale; - } - - /// - /// Scales the distance component of the plane by the given scaling factor. - /// - /// The plane to scale. - /// The amount by which to scale the plane. - /// The scaled plane. - public static Plane Scale(Plane value, float scale) - { - Plane result; - Scale(ref value, scale, out result); - return result; - } - - /// - /// Calculates the dot product of the specified vector and plane. - /// - /// The source plane. - /// The source vector. - /// When the method completes, contains the dot product of the specified plane and vector. - public static void Dot(ref Plane left, ref Vector4 right, out float result) - { - result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + (left.D * right.W); - } - - /// - /// Calculates the dot product of the specified vector and plane. - /// - /// The source plane. - /// The source vector. - /// The dot product of the specified plane and vector. - public static float Dot(Plane left, Vector4 right) - { - return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + (left.D * right.W); - } - - /// - /// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane. - /// - /// The source plane. - /// The source vector. - /// When the method completes, contains the dot product of a specified vector and the normal of the Plane plus the distance value of the plane. - public static void DotCoordinate(ref Plane left, ref Vector3 right, out float result) - { - result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + left.D; - } - - /// - /// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane. - /// - /// The source plane. - /// The source vector. - /// The dot product of a specified vector and the normal of the Plane plus the distance value of the plane. - public static float DotCoordinate(Plane left, Vector3 right) - { - return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + left.D; - } - - /// - /// Calculates the dot product of the specified vector and the normal of the plane. - /// - /// The source plane. - /// The source vector. - /// When the method completes, contains the dot product of the specified vector and the normal of the plane. - public static void DotNormal(ref Plane left, ref Vector3 right, out float result) - { - result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z); - } - - /// - /// Calculates the dot product of the specified vector and the normal of the plane. - /// - /// The source plane. - /// The source vector. - /// The dot product of the specified vector and the normal of the plane. - public static float DotNormal(Plane left, Vector3 right) - { - return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z); - } - - /// - /// Changes the coefficients of the normal vector of the plane to make it of unit length. - /// - /// The source plane. - /// When the method completes, contains the normalized plane. - public static void Normalize(ref Plane plane, out Plane result) - { - float magnitude = 1.0f / (float)(Math.Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z))); - - result.Normal.X = plane.Normal.X * magnitude; - result.Normal.Y = plane.Normal.Y * magnitude; - result.Normal.Z = plane.Normal.Z * magnitude; - result.D = plane.D * magnitude; - } - - /// - /// Changes the coefficients of the normal vector of the plane to make it of unit length. - /// - /// The source plane. - /// The normalized plane. - public static Plane Normalize(Plane plane) - { - float magnitude = 1.0f / (float)(Math.Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z))); - return new Plane(plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude); - } - - /// - /// Transforms a normalized plane by a quaternion rotation. - /// - /// The normalized source plane. - /// The quaternion rotation. - /// When the method completes, contains the transformed plane. - public static void Transform(ref Plane plane, ref Quaternion rotation, out Plane result) - { - float x2 = rotation.X + rotation.X; - float y2 = rotation.Y + rotation.Y; - float z2 = rotation.Z + rotation.Z; - float wx = rotation.W * x2; - float wy = rotation.W * y2; - float wz = rotation.W * z2; - float xx = rotation.X * x2; - float xy = rotation.X * y2; - float xz = rotation.X * z2; - float yy = rotation.Y * y2; - float yz = rotation.Y * z2; - float zz = rotation.Z * z2; - - float x = plane.Normal.X; - float y = plane.Normal.Y; - float z = plane.Normal.Z; - - /* - * Note: - * Factor common arithmetic out of loop. - */ - result.Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy)); - result.Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx)); - result.Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy)); - result.D = plane.D; - } - - /// - /// Transforms a normalized plane by a quaternion rotation. - /// - /// The normalized source plane. - /// The quaternion rotation. - /// The transformed plane. - public static Plane Transform(Plane plane, Quaternion rotation) - { - Plane result; - float x2 = rotation.X + rotation.X; - float y2 = rotation.Y + rotation.Y; - float z2 = rotation.Z + rotation.Z; - float wx = rotation.W * x2; - float wy = rotation.W * y2; - float wz = rotation.W * z2; - float xx = rotation.X * x2; - float xy = rotation.X * y2; - float xz = rotation.X * z2; - float yy = rotation.Y * y2; - float yz = rotation.Y * z2; - float zz = rotation.Z * z2; - - float x = plane.Normal.X; - float y = plane.Normal.Y; - float z = plane.Normal.Z; - - /* - * Note: - * Factor common arithmetic out of loop. - */ - result.Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy)); - result.Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx)); - result.Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy)); - result.D = plane.D; - - return result; - } - - /// - /// Transforms an array of normalized planes by a quaternion rotation. - /// - /// The array of normalized planes to transform. - /// The quaternion rotation. - /// Thrown when is null. - public static void Transform(Plane[] planes, ref Quaternion rotation) - { - if (planes == null) - throw new ArgumentNullException("planes"); - - float x2 = rotation.X + rotation.X; - float y2 = rotation.Y + rotation.Y; - float z2 = rotation.Z + rotation.Z; - float wx = rotation.W * x2; - float wy = rotation.W * y2; - float wz = rotation.W * z2; - float xx = rotation.X * x2; - float xy = rotation.X * y2; - float xz = rotation.X * z2; - float yy = rotation.Y * y2; - float yz = rotation.Y * z2; - float zz = rotation.Z * z2; - - for (int i = 0; i < planes.Length; ++i) - { - float x = planes[i].Normal.X; - float y = planes[i].Normal.Y; - float z = planes[i].Normal.Z; - - /* - * Note: - * Factor common arithmetic out of loop. - */ - planes[i].Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy)); - planes[i].Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx)); - planes[i].Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy)); - } - } - - /// - /// Transforms a normalized plane by a matrix. - /// - /// The normalized source plane. - /// The transformation matrix. - /// When the method completes, contains the transformed plane. - public static void Transform(ref Plane plane, ref Matrix transformation, out Plane result) - { - float x = plane.Normal.X; - float y = plane.Normal.Y; - float z = plane.Normal.Z; - float d = plane.D; - - Matrix inverse; - Matrix.Invert(ref transformation, out inverse); - - result.Normal.X = (((x * inverse.M11) + (y * inverse.M12)) + (z * inverse.M13)) + (d * inverse.M14); - result.Normal.Y = (((x * inverse.M21) + (y * inverse.M22)) + (z * inverse.M23)) + (d * inverse.M24); - result.Normal.Z = (((x * inverse.M31) + (y * inverse.M32)) + (z * inverse.M33)) + (d * inverse.M34); - result.D = (((x * inverse.M41) + (y * inverse.M42)) + (z * inverse.M43)) + (d * inverse.M44); - } - - /// - /// Transforms a normalized plane by a matrix. - /// - /// The normalized source plane. - /// The transformation matrix. - /// When the method completes, contains the transformed plane. - public static Plane Transform(Plane plane, Matrix transformation) - { - Plane result; - float x = plane.Normal.X; - float y = plane.Normal.Y; - float z = plane.Normal.Z; - float d = plane.D; - - transformation.Invert(); - result.Normal.X = (((x * transformation.M11) + (y * transformation.M12)) + (z * transformation.M13)) + (d * transformation.M14); - result.Normal.Y = (((x * transformation.M21) + (y * transformation.M22)) + (z * transformation.M23)) + (d * transformation.M24); - result.Normal.Z = (((x * transformation.M31) + (y * transformation.M32)) + (z * transformation.M33)) + (d * transformation.M34); - result.D = (((x * transformation.M41) + (y * transformation.M42)) + (z * transformation.M43)) + (d * transformation.M44); - - return result; - } - - /// - /// Transforms an array of normalized planes by a matrix. - /// - /// The array of normalized planes to transform. - /// The transformation matrix. - /// Thrown when is null. - public static void Transform(Plane[] planes, ref Matrix transformation) - { - if (planes == null) - throw new ArgumentNullException("planes"); - - Matrix inverse; - Matrix.Invert(ref transformation, out inverse); - - for (int i = 0; i < planes.Length; ++i) - { - Transform(ref planes[i], ref transformation, out planes[i]); - } - } - - /// - /// Scales each component of the plane by the given value. - /// - /// The amount by which to scale the plane. - /// The plane to scale. - /// The scaled plane. - public static Plane operator *(float scale, Plane plane) - { - return new Plane(plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale); - } - - /// - /// Scales each component of the plane by the given value. - /// - /// The plane to scale. - /// The amount by which to scale the plane. - /// The scaled plane. - public static Plane operator *(Plane plane, float scale) - { - return new Plane(plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Plane left, Plane right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Plane left, Plane right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - return string.Format(CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString(format, CultureInfo.CurrentCulture), - Normal.Y.ToString(format, CultureInfo.CurrentCulture), Normal.Z.ToString(format, CultureInfo.CurrentCulture), D.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - return string.Format(formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString(format, formatProvider), - Normal.Y.ToString(format, formatProvider), Normal.Z.ToString(format, formatProvider), D.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Normal.GetHashCode() + D.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Plane value) - { - return Normal == value.Normal && D == value.D; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Plane)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Plane(Plane value) - { - return new SlimDX.Plane(value.Normal, value.D); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Plane(SlimDX.Plane value) - { - return new Plane(value.Normal, value.D); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Plane(Plane value) - { - return new Microsoft.Xna.Framework.Plane(value.Normal, value.D); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Plane(Microsoft.Xna.Framework.Plane value) - { - return new Plane(value.Normal, value.D); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Quaternion.cs b/source/OrkEngine3D.Mathematics/Quaternion.cs deleted file mode 100644 index 2d3275c..0000000 --- a/source/OrkEngine3D.Mathematics/Quaternion.cs +++ /dev/null @@ -1,1519 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Globalization; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a four dimensional mathematical quaternion. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -[TypeConverter(typeof(Design.QuaternionConverter))] -public struct Quaternion : IEquatable, IFormattable -{ - /// - /// The size of the type, in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Quaternion)); - - /// - /// A with all of its components set to zero. - /// - public static readonly Quaternion Zero = new Quaternion(); - - /// - /// A with all of its components set to one. - /// - public static readonly Quaternion One = new Quaternion(1.0f, 1.0f, 1.0f, 1.0f); - - /// - /// The identity (0, 0, 0, 1). - /// - public static readonly Quaternion Identity = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - - /// - /// The X component of the quaternion. - /// - public float X; - - /// - /// The Y component of the quaternion. - /// - public float Y; - - /// - /// The Z component of the quaternion. - /// - public float Z; - - /// - /// The W component of the quaternion. - /// - public float W; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Quaternion(float value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the components. - public Quaternion(Vector4 value) - { - X = value.X; - Y = value.Y; - Z = value.Z; - W = value.W; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the X, Y, and Z components. - /// Initial value for the W component of the quaternion. - public Quaternion(Vector3 value, float w) - { - X = value.X; - Y = value.Y; - Z = value.Z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the X and Y components. - /// Initial value for the Z component of the quaternion. - /// Initial value for the W component of the quaternion. - public Quaternion(Vector2 value, float z, float w) - { - X = value.X; - Y = value.Y; - Z = z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// Initial value for the X component of the quaternion. - /// Initial value for the Y component of the quaternion. - /// Initial value for the Z component of the quaternion. - /// Initial value for the W component of the quaternion. - public Quaternion(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X, Y, Z, and W components of the quaternion. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Quaternion(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 4) - throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Quaternion."); - - X = values[0]; - Y = values[1]; - Z = values[2]; - W = values[3]; - } - - /// - /// Gets a value indicating whether this instance is equivalent to the identity quaternion. - /// - /// - /// true if this instance is an identity quaternion; otherwise, false. - /// - public bool IsIdentity - { - get { return this.Equals(Identity); } - } - - /// - /// Gets a value indicting whether this instance is normalized. - /// - public bool IsNormalized - { - get { return Math.Abs((X * X) + (Y * Y) + (Z * Z) + (W * W) - 1f) < Utilities.ZeroTolerance; } - } - - /// - /// Gets the angle of the quaternion. - /// - /// The quaternion's angle. - public float Angle - { - get - { - float length = (X * X) + (Y * Y) + (Z * Z); - if (length < Utilities.ZeroTolerance) - return 0.0f; - - return (float)(2.0 * Math.Acos(W)); - } - } - - /// - /// Gets the axis components of the quaternion. - /// - /// The axis components of the quaternion. - public Vector3 Axis - { - get - { - float length = (X * X) + (Y * Y) + (Z * Z); - if (length < Utilities.ZeroTolerance) - return Vector3.UnitX; - - float inv = 1.0f / length; - return new Vector3(X * inv, Y * inv, Z * inv); - } - } - - /// - /// Calculates the length of the Quaternion. - /// - /// The computed length of the Quaternion. - public float Length() - { - float ls = X * X + Y * Y + Z * Z + W * W; - - return (float)Math.Sqrt((double)ls); - } - - /// - /// Calculates the length squared of the Quaternion. This operation is cheaper than Length(). - /// - /// The length squared of the Quaternion. - public float LengthSquared() - { - return X * X + Y * Y + Z * Z + W * W; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the X, Y, Z, or W component, depending on the index. - /// The index of the component to access. Use 0 for the X component, 1 for the Y component, 2 for the Z component, and 3 for the W component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return X; - case 1: return Y; - case 2: return Z; - case 3: return W; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Quaternion run from 0 to 3, inclusive."); - } - - set - { - switch (index) - { - case 0: X = value; break; - case 1: Y = value; break; - case 2: Z = value; break; - case 3: W = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Quaternion run from 0 to 3, inclusive."); - } - } - } - - /// - /// Conjugates the quaternion. - /// - public void Conjugate() - { - X = -X; - Y = -Y; - Z = -Z; - } - - /// - /// Reverses the direction of a given quaternion. - /// - public void Negate() - { - this.X = -X; - this.Y = -Y; - this.Z = -Z; - this.W = -W; - } - - /// - /// Conjugates and renormalizes the quaternion. - /// - public void Invert() - { - float lengthSq = LengthSquared(); - if (lengthSq > Utilities.ZeroTolerance) - { - lengthSq = 1.0f / lengthSq; - - X = -X * lengthSq; - Y = -Y * lengthSq; - Z = -Z * lengthSq; - W = W * lengthSq; - } - } - - /// - /// Converts the quaternion into a unit quaternion. - /// - public void Normalize() - { - float length = Length(); - if (length > Utilities.ZeroTolerance) - { - float inverse = 1.0f / length; - X *= inverse; - Y *= inverse; - Z *= inverse; - W *= inverse; - } - } - - /// - /// Exponentiates a quaternion. - /// - public void Exponential() - { - Exponential(ref this, out this); - } - - /// - /// Calculates the natural logarithm of the specified quaternion. - /// - public void Logarithm() - { - Logarithm(ref this, out this); - } - - /// - /// Creates an array containing the elements of the quaternion. - /// - /// A four-element array containing the components of the quaternion. - public float[] ToArray() - { - return new float[] { X, Y, Z, W }; - } - - /// - /// Adds two quaternions. - /// - /// The first quaternion to add. - /// The second quaternion to add. - /// When the method completes, contains the sum of the two quaternions. - public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result.X = left.X + right.X; - result.Y = left.Y + right.Y; - result.Z = left.Z + right.Z; - result.W = left.W + right.W; - } - - /// - /// Adds two quaternions. - /// - /// The first quaternion to add. - /// The second quaternion to add. - /// The sum of the two quaternions. - public static Quaternion Add(Quaternion left, Quaternion right) - { - Quaternion result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts two quaternions. - /// - /// The first quaternion to subtract. - /// The second quaternion to subtract. - /// When the method completes, contains the difference of the two quaternions. - public static void Subtract(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result.X = left.X - right.X; - result.Y = left.Y - right.Y; - result.Z = left.Z - right.Z; - result.W = left.W - right.W; - } - - /// - /// Subtracts two quaternions. - /// - /// The first quaternion to subtract. - /// The second quaternion to subtract. - /// The difference of the two quaternions. - public static Quaternion Subtract(Quaternion left, Quaternion right) - { - Quaternion result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Scales a quaternion by the given value. - /// - /// The quaternion to scale. - /// The amount by which to scale the quaternion. - /// When the method completes, contains the scaled quaternion. - public static void Multiply(ref Quaternion value, float scalar, out Quaternion result) - { - result.X = value.X * scalar; - result.Y = value.Y * scalar; - result.Z = value.Z * scalar; - result.W = value.W * scalar; - } - - /// - /// Scales a quaternion by the given value. - /// - /// The quaternion to scale. - /// The amount by which to scale the quaternion. - /// The scaled quaternion. - public static Quaternion Multiply(Quaternion value, float scalar) - { - Quaternion result; - Multiply(ref value, scalar, out result); - return result; - } - - /// - /// Modulates a quaternion by another. - /// - /// The first quaternion to modulate. - /// The second quaternion to modulate. - /// When the moethod completes, contains the modulated quaternion. - public static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - float lx = left.X; - float ly = left.Y; - float lz = left.Z; - float lw = left.W; - float rx = right.X; - float ry = right.Y; - float rz = right.Z; - float rw = right.W; - - result.X = (rx * lw + lx * rw + ry * lz) - (rz * ly); - result.Y = (ry * lw + ly * rw + rz * lx) - (rx * lz); - result.Z = (rz * lw + lz * rw + rx * ly) - (ry * lx); - result.W = (rw * lw) - (rx * lx + ry * ly + rz * lz); - } - - /// - /// Modulates a quaternion by another. - /// - /// The first quaternion to modulate. - /// The second quaternion to modulate. - /// The modulated quaternion. - public static Quaternion Multiply(Quaternion left, Quaternion right) - { - Quaternion result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Divide(ref Quaternion value, float scalar, out Quaternion result) - { - result = new Quaternion(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Quaternion Divide(Quaternion value, float scalar) - { - return new Quaternion(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Reverses the direction of a given quaternion. - /// - /// The quaternion to negate. - /// When the method completes, contains a quaternion facing in the opposite direction. - public static void Negate(ref Quaternion value, out Quaternion result) - { - result.X = -value.X; - result.Y = -value.Y; - result.Z = -value.Z; - result.W = -value.W; - } - - /// - /// Reverses the direction of a given quaternion. - /// - /// The quaternion to negate. - /// A quaternion facing in the opposite direction. - public static Quaternion Negate(Quaternion value) - { - Quaternion result; - Negate(ref value, out result); - return result; - } - - /// - /// Returns a containing the 4D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 2D triangle. - /// - /// A containing the 4D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// When the method completes, contains a new containing the 4D Cartesian coordinates of the specified point. - public static void Barycentric(ref Quaternion value1, ref Quaternion value2, ref Quaternion value3, float amount1, float amount2, out Quaternion result) - { - Quaternion start, end; - Slerp(ref value1, ref value2, amount1 + amount2, out start); - Slerp(ref value1, ref value3, amount1 + amount2, out end); - Slerp(ref start, ref end, amount2 / (amount1 + amount2), out result); - } - - /// - /// Returns a containing the 4D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 2D triangle. - /// - /// A containing the 4D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// A new containing the 4D Cartesian coordinates of the specified point. - public static Quaternion Barycentric(Quaternion value1, Quaternion value2, Quaternion value3, float amount1, float amount2) - { - Quaternion result; - Barycentric(ref value1, ref value2, ref value3, amount1, amount2, out result); - return result; - } - - /// - /// Conjugates a quaternion. - /// - /// The quaternion to conjugate. - /// When the method completes, contains the conjugated quaternion. - public static void Conjugate(ref Quaternion value, out Quaternion result) - { - result.X = -value.X; - result.Y = -value.Y; - result.Z = -value.Z; - result.W = value.W; - } - - /// - /// Conjugates a quaternion. - /// - /// The quaternion to conjugate. - /// The conjugated quaternion. - public static Quaternion Conjugate(Quaternion value) - { - Quaternion result; - Conjugate(ref value, out result); - return result; - } - - /// - /// Returns the inverse of a Quaternion. - /// - /// The source Quaternion. - /// The inverted Quaternion. - public static Quaternion Inverse(Quaternion value) - { - // -1 ( a -v ) - // q = ( ------------- ------------- ) - // ( a^2 + |v|^2 , a^2 + |v|^2 ) - - Quaternion ans; - - float ls = value.X * value.X + value.Y * value.Y + value.Z * value.Z + value.W * value.W; - float invNorm = 1.0f / ls; - - ans.X = -value.X * invNorm; - ans.Y = -value.Y * invNorm; - ans.Z = -value.Z * invNorm; - ans.W = value.W * invNorm; - - return ans; - } - - /// - /// Creates a Quaternion from a vector and an angle to rotate about the vector. - /// - /// The vector to rotate around. - /// The angle, in radians, to rotate around the vector. - /// The created Quaternion. - public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle) - { - Quaternion ans; - - float halfAngle = angle * 0.5f; - float s = (float)Math.Sin(halfAngle); - float c = (float)Math.Cos(halfAngle); - - ans.X = axis.X * s; - ans.Y = axis.Y * s; - ans.Z = axis.Z * s; - ans.W = c; - - return ans; - } - - /// - /// Creates a new Quaternion from the given yaw, pitch, and roll, in radians. - /// - /// The yaw angle, in radians, around the Y-axis. - /// The pitch angle, in radians, around the X-axis. - /// The roll angle, in radians, around the Z-axis. - /// - public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll) - { - // Roll first, about axis the object is facing, then - // pitch upward, then yaw to face into the new heading - float sr, cr, sp, cp, sy, cy; - - float halfRoll = roll * 0.5f; - sr = (float)Math.Sin(halfRoll); - cr = (float)Math.Cos(halfRoll); - - float halfPitch = pitch * 0.5f; - sp = (float)Math.Sin(halfPitch); - cp = (float)Math.Cos(halfPitch); - - float halfYaw = yaw * 0.5f; - sy = (float)Math.Sin(halfYaw); - cy = (float)Math.Cos(halfYaw); - - Quaternion result; - - result.X = cy * sp * cr + sy * cp * sr; - result.Y = sy * cp * cr - cy * sp * sr; - result.Z = cy * cp * sr - sy * sp * cr; - result.W = cy * cp * cr + sy * sp * sr; - - return result; - } - - /// - /// Creates a Quaternion from the given rotation matrix. - /// - /// The rotation matrix. - /// The created Quaternion. - public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix) - { - float trace = matrix.M11 + matrix.M22 + matrix.M33; - - Quaternion q = new Quaternion(); - - if (trace > 0.0f) - { - float s = (float)Math.Sqrt(trace + 1.0f); - q.W = s * 0.5f; - s = 0.5f / s; - q.X = (matrix.M23 - matrix.M32) * s; - q.Y = (matrix.M31 - matrix.M13) * s; - q.Z = (matrix.M12 - matrix.M21) * s; - } - else - { - if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33) - { - float s = (float)Math.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33); - float invS = 0.5f / s; - q.X = 0.5f * s; - q.Y = (matrix.M12 + matrix.M21) * invS; - q.Z = (matrix.M13 + matrix.M31) * invS; - q.W = (matrix.M23 - matrix.M32) * invS; - } - else if (matrix.M22 > matrix.M33) - { - float s = (float)Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33); - float invS = 0.5f / s; - q.X = (matrix.M21 + matrix.M12) * invS; - q.Y = 0.5f * s; - q.Z = (matrix.M32 + matrix.M23) * invS; - q.W = (matrix.M31 - matrix.M13) * invS; - } - else - { - float s = (float)Math.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22); - float invS = 0.5f / s; - q.X = (matrix.M31 + matrix.M13) * invS; - q.Y = (matrix.M32 + matrix.M23) * invS; - q.Z = 0.5f * s; - q.W = (matrix.M12 - matrix.M21) * invS; - } - } - - return q; - } - - /// - /// Calculates the dot product of two quaternions. - /// - /// First source quaternion. - /// Second source quaternion. - /// When the method completes, contains the dot product of the two quaternions. - public static void Dot(ref Quaternion left, ref Quaternion right, out float result) - { - result = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W); - } - - /// - /// Calculates the dot product of two quaternions. - /// - /// First source quaternion. - /// Second source quaternion. - /// The dot product of the two quaternions. - public static float Dot(Quaternion left, Quaternion right) - { - return (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W); - } - - /// - /// Exponentiates a quaternion. - /// - /// The quaternion to exponentiate. - /// When the method completes, contains the exponentiated quaternion. - public static void Exponential(ref Quaternion value, out Quaternion result) - { - float angle = (float)Math.Sqrt((value.X * value.X) + (value.Y * value.Y) + (value.Z * value.Z)); - float sin = (float)Math.Sin(angle); - - if (Math.Abs(sin) >= Utilities.ZeroTolerance) - { - float coeff = sin / angle; - result.X = coeff * value.X; - result.Y = coeff * value.Y; - result.Z = coeff * value.Z; - } - else - { - result = value; - } - - result.W = (float)Math.Cos(angle); - } - - /// - /// Exponentiates a quaternion. - /// - /// The quaternion to exponentiate. - /// The exponentiated quaternion. - public static Quaternion Exponential(Quaternion value) - { - Quaternion result; - Exponential(ref value, out result); - return result; - } - - /// - /// Conjugates and renormalizes the quaternion. - /// - /// The quaternion to conjugate and renormalize. - /// When the method completes, contains the conjugated and renormalized quaternion. - public static void Invert(ref Quaternion value, out Quaternion result) - { - result = value; - result.Invert(); - } - - /// - /// Conjugates and renormalizes the quaternion. - /// - /// The quaternion to conjugate and renormalize. - /// The conjugated and renormalized quaternion. - public static Quaternion Invert(Quaternion value) - { - Quaternion result; - Invert(ref value, out result); - return result; - } - - /// - /// Performs a linear interpolation between two quaternions. - /// - /// Start quaternion. - /// End quaternion. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two quaternions. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Quaternion start, ref Quaternion end, float amount, out Quaternion result) - { - float inverse = 1.0f - amount; - - if (Dot(start, end) >= 0.0f) - { - result.X = (inverse * start.X) + (amount * end.X); - result.Y = (inverse * start.Y) + (amount * end.Y); - result.Z = (inverse * start.Z) + (amount * end.Z); - result.W = (inverse * start.W) + (amount * end.W); - } - else - { - result.X = (inverse * start.X) - (amount * end.X); - result.Y = (inverse * start.Y) - (amount * end.Y); - result.Z = (inverse * start.Z) - (amount * end.Z); - result.W = (inverse * start.W) - (amount * end.W); - } - - result.Normalize(); - } - - /// - /// Performs a linear interpolation between two quaternion. - /// - /// Start quaternion. - /// End quaternion. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two quaternions. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Quaternion Lerp(Quaternion start, Quaternion end, float amount) - { - Quaternion result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Concatenates two Quaternions; the result represents the value1 rotation followed by the value2 rotation. - /// - /// The first Quaternion rotation in the series. - /// The second Quaternion rotation in the series. - /// A new Quaternion representing the concatenation of the value1 rotation followed by the value2 rotation. - public static Quaternion Concatenate(Quaternion value1, Quaternion value2) - { - Quaternion ans; - - // Concatenate rotation is actually q2 * q1 instead of q1 * q2. - // So that's why value2 goes q1 and value1 goes q2. - float q1x = value2.X; - float q1y = value2.Y; - float q1z = value2.Z; - float q1w = value2.W; - - float q2x = value1.X; - float q2y = value1.Y; - float q2z = value1.Z; - float q2w = value1.W; - - // cross(av, bv) - float cx = q1y * q2z - q1z * q2y; - float cy = q1z * q2x - q1x * q2z; - float cz = q1x * q2y - q1y * q2x; - - float dot = q1x * q2x + q1y * q2y + q1z * q2z; - - ans.X = q1x * q2w + q2x * q1w + cx; - ans.Y = q1y * q2w + q2y * q1w + cy; - ans.Z = q1z * q2w + q2z * q1w + cz; - ans.W = q1w * q2w - dot; - - return ans; - } - - /// - /// Calculates the natural logarithm of the specified quaternion. - /// - /// The quaternion whose logarithm will be calculated. - /// When the method completes, contains the natural logarithm of the quaternion. - public static void Logarithm(ref Quaternion value, out Quaternion result) - { - if (Math.Abs(value.W) < 1.0f) - { - float angle = (float)Math.Acos(value.W); - float sin = (float)Math.Sin(angle); - - if (Math.Abs(sin) >= Utilities.ZeroTolerance) - { - float coeff = angle / sin; - result.X = value.X * coeff; - result.Y = value.Y * coeff; - result.Z = value.Z * coeff; - } - else - { - result = value; - } - } - else - { - result = value; - } - - result.W = 0.0f; - } - - /// - /// Calculates the natural logarithm of the specified quaternion. - /// - /// The quaternion whose logarithm will be calculated. - /// The natural logarithm of the quaternion. - public static Quaternion Logarithm(Quaternion value) - { - Quaternion result; - Logarithm(ref value, out result); - return result; - } - - /// - /// Converts the quaternion into a unit quaternion. - /// - /// The quaternion to normalize. - /// When the method completes, contains the normalized quaternion. - public static void Normalize(ref Quaternion value, out Quaternion result) - { - Quaternion temp = value; - result = temp; - result.Normalize(); - } - - /// - /// Converts the quaternion into a unit quaternion. - /// - /// The quaternion to normalize. - /// The normalized quaternion. - public static Quaternion Normalize(Quaternion value) - { - value.Normalize(); - return value; - } - - /// - /// Creates a quaternion given a rotation and an axis. - /// - /// The axis of rotation. - /// The angle of rotation. - /// When the method completes, contains the newly created quaternion. - public static void RotationAxis(ref Vector3 axis, float angle, out Quaternion result) - { - Vector3 normalized; - Vector3.Normalize(ref axis, out normalized); - - float half = angle * 0.5f; - float sin = (float)Math.Sin(half); - float cos = (float)Math.Cos(half); - - result.X = normalized.X * sin; - result.Y = normalized.Y * sin; - result.Z = normalized.Z * sin; - result.W = cos; - } - - /// - /// Creates a quaternion given a rotation and an axis. - /// - /// The axis of rotation. - /// The angle of rotation. - /// The newly created quaternion. - public static Quaternion RotationAxis(Vector3 axis, float angle) - { - Quaternion result; - RotationAxis(ref axis, angle, out result); - return result; - } - - /// - /// Creates a quaternion given a rotation matrix. - /// - /// The rotation matrix. - /// When the method completes, contains the newly created quaternion. - public static void RotationMatrix(ref Matrix matrix, out Quaternion result) - { - float sqrt; - float half; - float scale = matrix.M11 + matrix.M22 + matrix.M33; - - if (scale > 0.0f) - { - sqrt = (float)Math.Sqrt(scale + 1.0f); - result.W = sqrt * 0.5f; - sqrt = 0.5f / sqrt; - - result.X = (matrix.M23 - matrix.M32) * sqrt; - result.Y = (matrix.M31 - matrix.M13) * sqrt; - result.Z = (matrix.M12 - matrix.M21) * sqrt; - } - else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33)) - { - sqrt = (float)Math.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33); - half = 0.5f / sqrt; - - result.X = 0.5f * sqrt; - result.Y = (matrix.M12 + matrix.M21) * half; - result.Z = (matrix.M13 + matrix.M31) * half; - result.W = (matrix.M23 - matrix.M32) * half; - } - else if (matrix.M22 > matrix.M33) - { - sqrt = (float)Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33); - half = 0.5f / sqrt; - - result.X = (matrix.M21 + matrix.M12) * half; - result.Y = 0.5f * sqrt; - result.Z = (matrix.M32 + matrix.M23) * half; - result.W = (matrix.M31 - matrix.M13) * half; - } - else - { - sqrt = (float)Math.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22); - half = 0.5f / sqrt; - - result.X = (matrix.M31 + matrix.M13) * half; - result.Y = (matrix.M32 + matrix.M23) * half; - result.Z = 0.5f * sqrt; - result.W = (matrix.M12 - matrix.M21) * half; - } - } - - /// - /// Creates a quaternion given a rotation matrix. - /// - /// The rotation matrix. - /// The newly created quaternion. - public static Quaternion RotationMatrix(Matrix matrix) - { - Quaternion result; - RotationMatrix(ref matrix, out result); - return result; - } - - /// - /// Creates a quaternion given a yaw, pitch, and roll value. - /// - /// The yaw of rotation. - /// The pitch of rotation. - /// The roll of rotation. - /// When the method completes, contains the newly created quaternion. - public static void RotationYawPitchRoll(float yaw, float pitch, float roll, out Quaternion result) - { - float halfRoll = roll * 0.5f; - float halfPitch = pitch * 0.5f; - float halfYaw = yaw * 0.5f; - - float sinRoll = (float)Math.Sin(halfRoll); - float cosRoll = (float)Math.Cos(halfRoll); - float sinPitch = (float)Math.Sin(halfPitch); - float cosPitch = (float)Math.Cos(halfPitch); - float sinYaw = (float)Math.Sin(halfYaw); - float cosYaw = (float)Math.Cos(halfYaw); - - result.X = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll); - result.Y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll); - result.Z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll); - result.W = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll); - } - - /// - /// Creates a quaternion given a yaw, pitch, and roll value. - /// - /// The yaw of rotation. - /// The pitch of rotation. - /// The roll of rotation. - /// The newly created quaternion. - public static Quaternion RotationYawPitchRoll(float yaw, float pitch, float roll) - { - Quaternion result; - RotationYawPitchRoll(yaw, pitch, roll, out result); - return result; - } - - /// - /// Interpolates between two quaternions, using spherical linear interpolation. - /// - /// Start quaternion. - /// End quaternion. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the spherical linear interpolation of the two quaternions. - public static void Slerp(ref Quaternion start, ref Quaternion end, float amount, out Quaternion result) - { - float opposite; - float inverse; - float dot = Dot(start, end); - - if (Math.Abs(dot) > 1.0f - Utilities.ZeroTolerance) - { - inverse = 1.0f - amount; - opposite = amount * Math.Sign(dot); - } - else - { - float acos = (float)Math.Acos(Math.Abs(dot)); - float invSin = (float)(1.0f / Math.Sin(acos)); - - inverse = (float)Math.Sin((1.0f - amount) * acos) * invSin; - opposite = (float)Math.Sin(amount * acos) * invSin * Math.Sign(dot); - } - - result.X = (inverse * start.X) + (opposite * end.X); - result.Y = (inverse * start.Y) + (opposite * end.Y); - result.Z = (inverse * start.Z) + (opposite * end.Z); - result.W = (inverse * start.W) + (opposite * end.W); - } - - /// - /// Interpolates between two quaternions, using spherical linear interpolation. - /// - /// Start quaternion. - /// End quaternion. - /// Value between 0 and 1 indicating the weight of . - /// The spherical linear interpolation of the two quaternions. - public static Quaternion Slerp(Quaternion start, Quaternion end, float amount) - { - Quaternion result; - Slerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Interpolates between quaternions, using spherical quadrangle interpolation. - /// - /// First source quaternion. - /// Second source quaternion. - /// Thrid source quaternion. - /// Fourth source quaternion. - /// Value between 0 and 1 indicating the weight of interpolation. - /// When the method completes, contains the spherical quadrangle interpolation of the quaternions. - public static void Squad(ref Quaternion value1, ref Quaternion value2, ref Quaternion value3, ref Quaternion value4, float amount, out Quaternion result) - { - Quaternion start, end; - Slerp(ref value1, ref value4, amount, out start); - Slerp(ref value2, ref value3, amount, out end); - Slerp(ref start, ref end, 2.0f * amount * (1.0f - amount), out result); - } - - /// - /// Interpolates between quaternions, using spherical quadrangle interpolation. - /// - /// First source quaternion. - /// Second source quaternion. - /// Thrid source quaternion. - /// Fourth source quaternion. - /// Value between 0 and 1 indicating the weight of interpolation. - /// The spherical quadrangle interpolation of the quaternions. - public static Quaternion Squad(Quaternion value1, Quaternion value2, Quaternion value3, Quaternion value4, float amount) - { - Quaternion result; - Squad(ref value1, ref value2, ref value3, ref value4, amount, out result); - return result; - } - - /// - /// Sets up control points for spherical quadrangle interpolation. - /// - /// First source quaternion. - /// Second source quaternion. - /// Third source quaternion. - /// Fourth source quaternion. - /// When the method completes, contains the first control point for spherical quadrangle interpolation. - /// When the method completes, contains the second control point for spherical quadrangle interpolation. - /// When the method completes, contains the third control point for spherical quadrangle interpolation. - public static void SquadSetup(ref Quaternion value1, ref Quaternion value2, ref Quaternion value3, ref Quaternion value4, out Quaternion result1, out Quaternion result2, out Quaternion result3) - { - Quaternion q0 = (value1 + value2).LengthSquared() < (value1 - value2).LengthSquared() ? -value1 : value1; - Quaternion q2 = (value2 + value3).LengthSquared() < (value2 - value3).LengthSquared() ? -value3 : value3; - Quaternion q3 = (value3 + value4).LengthSquared() < (value3 - value4).LengthSquared() ? -value4 : value4; - Quaternion q1 = value2; - - Quaternion q1Exp, q2Exp; - Exponential(ref q1, out q1Exp); - Exponential(ref q2, out q2Exp); - - result1 = q1 * Exponential(-0.25f * (Logarithm(q1Exp * q2) + Logarithm(q1Exp * q0))); - result2 = q2 * Exponential(-0.25f * (Logarithm(q2Exp * q3) + Logarithm(q2Exp * q1))); - result3 = q2; - } - - /// - /// Sets up control points for spherical quadrangle interpolation. - /// - /// First source quaternion. - /// Second source quaternion. - /// Third source quaternion. - /// Fourth source quaternion. - /// An array of three quaternions that represent control points for spherical quadrangle interpolation. - public static Quaternion[] SquadSetup(Quaternion value1, Quaternion value2, Quaternion value3, Quaternion value4) - { - Quaternion[] results = new Quaternion[3]; - SquadSetup(ref value1, ref value2, ref value3, ref value4, out results[0], out results[1], out results[2]); - - return results; - } - - /// - /// Adds two quaternions. - /// - /// The first quaternion to add. - /// The second quaternion to add. - /// The sum of the two quaternions. - public static Quaternion operator +(Quaternion left, Quaternion right) - { - Quaternion result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts two quaternions. - /// - /// The first quaternion to subtract. - /// The second quaternion to subtract. - /// The difference of the two quaternions. - public static Quaternion operator -(Quaternion left, Quaternion right) - { - Quaternion result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Reverses the direction of a given quaternion. - /// - /// The quaternion to negate. - /// A quaternion facing in the opposite direction. - public static Quaternion operator -(Quaternion value) - { - Quaternion result; - Negate(ref value, out result); - return result; - } - - /// - /// Scales a quaternion by the given value. - /// - /// The quaternion to scale. - /// The amount by which to scale the quaternion. - /// The scaled quaternion. - public static Quaternion operator *(float scalar, Quaternion value) - { - Quaternion result; - Multiply(ref value, scalar, out result); - return result; - } - - /// - /// Scales a quaternion by the given value. - /// - /// The quaternion to scale. - /// The amount by which to scale the quaternion. - /// The scaled quaternion. - public static Quaternion operator *(Quaternion value, float scalar) - { - Quaternion result; - Multiply(ref value, scalar, out result); - return result; - } - - /// - /// Multiplies a quaternion by another. - /// - /// The first quaternion to multiply. - /// The second quaternion to multiply. - /// The multiplied quaternion. - public static Quaternion operator *(Quaternion left, Quaternion right) - { - Quaternion result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Quaternion operator /(Quaternion value, float scalar) - { - return new Quaternion(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Quaternion left, Quaternion right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Quaternion left, Quaternion right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, CultureInfo.CurrentCulture), - Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture), W.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, formatProvider), - Y.ToString(format, formatProvider), Z.ToString(format, formatProvider), W.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Quaternion other) - { - return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z) && (this.W == other.W); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// The amount of error allowed. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Quaternion other, float epsilon) - { - return ((float)Math.Abs(other.X - X) < epsilon && - (float)Math.Abs(other.Y - Y) < epsilon && - (float)Math.Abs(other.Z - Z) < epsilon && - (float)Math.Abs(other.W - W) < epsilon); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Quaternion)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Quaternion(Quaternion value) - { - return new SlimDX.Quaternion(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Quaternion(SlimDX.Quaternion value) - { - return new Quaternion(value.X, value.Y, value.Z, value.W); - } -#endif - -#if WPFInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator System.Windows.Media.Media3D.Quaternion(Quaternion value) - { - return new System.Windows.Media.Media3D.Quaternion(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Quaternion(System.Windows.Media.Media3D.Quaternion value) - { - return new Quaternion((float)value.X, (float)value.Y, (float)value.Z, (float)value.W); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Quaternion(Quaternion value) - { - return new Microsoft.Xna.Framework.Quaternion(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Quaternion(Microsoft.Xna.Framework.Quaternion value) - { - return new Quaternion(value.X, value.Y, value.Z, value.W); - } -#endif - // Wikipedia - public static Vector3 ToEulerAngles(Quaternion q) { - Vector3 angles; - - // roll (x-axis rotation) - float sinr_cosp = 2 * (q.W * q.X + q.Y * q.Z); - float cosr_cosp = 1 - 2 * (q.X * q.X + q.Y * q.Y); - angles.X = MathF.Atan2(sinr_cosp, cosr_cosp); - - // pitch (y-axis rotation) - float sinp = 2 * (q.W * q.Y - q.Z * q.X); - if (MathF.Abs(sinp) >= 1) - angles.Z = MathF.CopySign(MathF.PI / 2, sinp); // use 90 degrees if out of range - else - angles.Z = MathF.Asin(sinp); - - // yaw (z-axis rotation) - float siny_cosp = 2 * (q.W * q.Z + q.X * q.Y); - float cosy_cosp = 1 - 2 * (q.Y * q.Y + q.Z * q.Z); - angles.Y = MathF.Atan2(siny_cosp, cosy_cosp); - - return angles; - } -} diff --git a/source/OrkEngine3D.Mathematics/Ray.cs b/source/OrkEngine3D.Mathematics/Ray.cs deleted file mode 100644 index 4e7395c..0000000 --- a/source/OrkEngine3D.Mathematics/Ray.cs +++ /dev/null @@ -1,393 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a three dimensional line based on a point in space and a direction. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct Ray : IEquatable, IFormattable -{ - /// - /// The position in three dimensional space where the ray starts. - /// - public Vector3 Position; - - /// - /// The normalized direction in which the ray points. - /// - public Vector3 Direction; - - /// - /// Initializes a new instance of the struct. - /// - /// The position in three dimensional space of the origin of the ray. - /// The normalized direction of the ray. - public Ray(Vector3 position, Vector3 direction) - { - this.Position = position; - this.Direction = direction; - } - - /// - /// Determines if there is an intersection between the current object and a point. - /// - /// The point to test. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 point) - { - return Collision.RayIntersectsPoint(ref this, ref point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray) - { - Vector3 point; - return Collision.RayIntersectsRay(ref this, ref ray, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The ray to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Ray ray, out Vector3 point) - { - return Collision.RayIntersectsRay(ref this, ref ray, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test - /// Whether the two objects intersected. - public bool Intersects(ref Plane plane) - { - float distance; - return Collision.RayIntersectsPlane(ref this, ref plane, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Plane plane, out float distance) - { - return Collision.RayIntersectsPlane(ref this, ref plane, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The plane to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Plane plane, out Vector3 point) - { - return Collision.RayIntersectsPlane(ref this, ref plane, out point); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triangle to test. - /// The third vertex of the triangle to test. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3) - { - float distance; - return Collision.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triangle to test. - /// The third vertex of the triangle to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out float distance) - { - return Collision.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a triangle. - /// - /// The first vertex of the triangle to test. - /// The second vertex of the triangle to test. - /// The third vertex of the triangle to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 point) - { - return Collision.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingBox box) - { - float distance; - return Collision.RayIntersectsBox(ref this, ref box, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingBox box, out float distance) - { - return Collision.RayIntersectsBox(ref this, ref box, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The box to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingBox box, out Vector3 point) - { - return Collision.RayIntersectsBox(ref this, ref box, out point); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingSphere sphere) - { - float distance; - return Collision.RayIntersectsSphere(ref this, ref sphere, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// When the method completes, contains the distance of the intersection, - /// or 0 if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingSphere sphere, out float distance) - { - return Collision.RayIntersectsSphere(ref this, ref sphere, out distance); - } - - /// - /// Determines if there is an intersection between the current object and a . - /// - /// The sphere to test. - /// When the method completes, contains the point of intersection, - /// or if there was no intersection. - /// Whether the two objects intersected. - public bool Intersects(ref BoundingSphere sphere, out Vector3 point) - { - return Collision.RayIntersectsSphere(ref this, ref sphere, out point); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Ray left, Ray right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Ray left, Ray right) - { - return !left.Equals(right); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Position:{0} Direction:{1}", Position.ToString(), Direction.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - return string.Format(CultureInfo.CurrentCulture, "Position:{0} Direction:{1}", Position.ToString(format, CultureInfo.CurrentCulture), - Direction.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Position:{0} Direction:{1}", Position.ToString(), Direction.ToString()); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - return string.Format(formatProvider, "Position:{0} Direction:{1}", Position.ToString(format, formatProvider), - Direction.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Position.GetHashCode() + Direction.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Ray value) - { - return Position == value.Position && Direction == value.Direction; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Ray)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Ray(Ray value) - { - return new SlimDX.Ray(value.Position, value.Direction); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Ray(SlimDX.Ray value) - { - return new Ray(value.Position, value.Direction); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Ray(Ray value) - { - return new Microsoft.Xna.Framework.Ray(value.Position, value.Direction); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Ray(Microsoft.Xna.Framework.Ray value) - { - return new Ray(value.Position, value.Direction); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Utilities.cs b/source/OrkEngine3D.Mathematics/Utilities.cs deleted file mode 100644 index c941427..0000000 --- a/source/OrkEngine3D.Mathematics/Utilities.cs +++ /dev/null @@ -1,87 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OrkEngine3D.Mathematics; - -static class Utilities -{ - /// - /// The value for which all absolute numbers smaller than are considered equal to zero. - /// - public const float ZeroTolerance = 1e-6f; - - /// - /// Compares two floating point numbers based on an epsilon zero tolerance. - /// - /// The first number to compare. - /// The second number to compare. - /// true if is within epsilon of ; otherwise, false. - public static bool EpsilonEquals(float left, float right) - { - return Math.Abs(left - right) <= ZeroTolerance; - } - - /// - /// Compares two floating point numbers based on an epsilon zero tolerance. - /// - /// The first number to compare. - /// The second number to compare. - /// The epsilon value to use for zero tolerance. - /// true if is within epsilon of ; otherwise, false. - public static bool EpsilonEquals(float left, float right, float epsilon) - { - return Math.Abs(left - right) <= epsilon; - } - - /// - /// Swaps two items. - /// - /// The type of the items to swap. - /// The first item to swap. - /// The second item to swap. - public static void Swap(ref T left, ref T right) - { - T temp = left; - left = right; - right = temp; - } - - /// - /// Does something with arrays. - /// - /// Most likely the type of elements in the array. - /// Who knows what this is for. - /// Probably the length of the array. - /// An array of who knows what. - public static T[] Array(T value, int count) - { - T[] result = new T[count]; - for (int i = 0; i < count; i++) - result[i] = value; - - return result; - } -} diff --git a/source/OrkEngine3D.Mathematics/Vector.cs b/source/OrkEngine3D.Mathematics/Vector.cs deleted file mode 100644 index 002e42c..0000000 --- a/source/OrkEngine3D.Mathematics/Vector.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace OrkEngine3D.Mathematics -{ - /// - /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another. - /// - internal static class Vector - { - // Every operation must either be a JIT intrinsic or implemented over a JIT intrinsic - // as a thin wrapper - // Operations implemented over a JIT intrinsic should be inlined - // Methods that do not have a type parameter are recognized as intrinsics - /// - /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support. - /// - public static bool IsHardwareAccelerated - { - get - { - return false; - } - } - } -} diff --git a/source/OrkEngine3D.Mathematics/Vector2.cs b/source/OrkEngine3D.Mathematics/Vector2.cs deleted file mode 100644 index c2e3076..0000000 --- a/source/OrkEngine3D.Mathematics/Vector2.cs +++ /dev/null @@ -1,1743 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a two dimensional mathematical vector. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -[TypeConverter(typeof(Design.Vector2Converter))] -public struct Vector2 : IEquatable, IFormattable -{ - /// - /// The size of the type, in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Vector2)); - - /// - /// A with all of its components set to zero. - /// - public static readonly Vector2 Zero = new Vector2(); - - /// - /// The X unit (1, 0). - /// - public static readonly Vector2 UnitX = new Vector2(1.0f, 0.0f); - - /// - /// The Y unit (0, 1). - /// - public static readonly Vector2 UnitY = new Vector2(0.0f, 1.0f); - - /// - /// A with all of its components set to one. - /// - public static readonly Vector2 One = new Vector2(1.0f, 1.0f); - - /// - /// The X component of the vector. - /// - public float X; - - /// - /// The Y component of the vector. - /// - public float Y; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Vector2(float value) - { - X = value; - Y = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// Initial value for the X component of the vector. - /// Initial value for the Y component of the vector. - public Vector2(float x, float y) - { - X = x; - Y = y; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X and Y components of the vector. This must be an array with two elements. - /// Thrown when is null. - /// Thrown when contains more or less than two elements. - public Vector2(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 2) - throw new ArgumentOutOfRangeException("values", "There must be two and only two input values for Vector2."); - - X = values[0]; - Y = values[1]; - } - - /// - /// Gets a value indicting whether this instance is normalized. - /// - public bool IsNormalized - { - get { return Math.Abs((X * X) + (Y * Y) - 1f) < Utilities.ZeroTolerance; } - } - - /// - /// Calculates the length of the vector. - /// - /// - /// may be preferred when only the relative length is needed - /// and speed is of the essence. - /// - public float Length() - { - return (float)Math.Sqrt((X * X) + (Y * Y)); - } - - /// - /// Calculates the squared length of the vector. - /// - /// - /// This property may be preferred to when only a relative length is needed - /// and speed is of the essence. - /// - public float LengthSquared() - { - return (X * X) + (Y * Y); - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the X or Y component, depending on the index. - /// The index of the component to access. Use 0 for the X component and 1 for the Y component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 1]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return X; - case 1: return Y; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Vector2 run from 0 to 1, inclusive."); - } - - set - { - switch (index) - { - case 0: X = value; break; - case 1: Y = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Vector2 run from 0 to 1, inclusive."); - } - } - } - - /// - /// Converts the vector into a unit vector. - /// - public void Normalize() - { - float length = Length(); - if (length > Utilities.ZeroTolerance) - { - float inv = 1.0f / length; - X *= inv; - Y *= inv; - } - } - - /// - /// Reverses the direction of a given vector. - /// - public void Negate() - { - X = -X; - Y = -Y; - } - - /// - /// Takes the absolute value of each component. - /// - public void Abs() - { - this.X = Math.Abs(X); - this.Y = Math.Abs(Y); - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A two-element array containing the components of the vector. - public float[] ToArray() - { - return new float[] { X, Y }; - } - - #region Transcendentals - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// When the method completes, contains a vector that is the square root of the input vector. - public static void Sqrt(ref Vector2 value, out Vector2 result) - { - result.X = (float)Math.Sqrt(value.X); - result.Y = (float)Math.Sqrt(value.Y); - } - - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// A vector that is the square root of the input vector. - public static Vector2 Sqrt(Vector2 value) - { - Vector2 temp; - Sqrt(ref value, out temp); - return temp; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// When the method completes, contains a vector that is the reciprocal of the input vector. - public static void Reciprocal(ref Vector2 value, out Vector2 result) - { - result.X = 1.0f / value.X; - result.Y = 1.0f / value.Y; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// A vector that is the reciprocal of the input vector. - public static Vector2 Reciprocal(Vector2 value) - { - Vector2 temp; - Reciprocal(ref value, out temp); - return temp; - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// When the method completes, contains a vector that is the square root and reciprocal of the input vector. - public static void ReciprocalSqrt(ref Vector2 value, out Vector2 result) - { - result.X = 1.0f / (float)Math.Sqrt(value.X); - result.Y = 1.0f / (float)Math.Sqrt(value.Y); - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// A vector that is the square root and reciprocal of the input vector. - public static Vector2 ReciprocalSqrt(Vector2 value) - { - Vector2 temp; - ReciprocalSqrt(ref value, out temp); - return temp; - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// When the method completes, contains a vector that has e raised to each of the components in the input vector. - public static void Exp(ref Vector2 value, out Vector2 result) - { - result.X = (float)Math.Exp(value.X); - result.Y = (float)Math.Exp(value.Y); - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// A vector that has e raised to each of the components in the input vector. - public static Vector2 Exp(Vector2 value) - { - Vector2 temp; - Exp(ref value, out temp); - return temp; - } - - /// - /// Takes the sine and than the cosine of each component in the vector. - /// - /// The vector to take the sine and cosine of. - /// When the method completes, contains the sine of each component in the input vector. - /// When the method completes, contains the cpsome pf each component in the input vector. - public static void SinCos(ref Vector2 value, out Vector2 sinResult, out Vector2 cosResult) - { - sinResult.X = (float)Math.Sin(value.X); - sinResult.Y = (float)Math.Sin(value.Y); - - cosResult.X = (float)Math.Cos(value.X); - cosResult.Y = (float)Math.Cos(value.Y); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// When the method completes, a vector that contains the sine of each component in the input vector. - public static void Sin(ref Vector2 value, out Vector2 result) - { - result.X = (float)Math.Sin(value.X); - result.Y = (float)Math.Sin(value.Y); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// A vector that contains the sine of each component in the input vector. - public static Vector2 Sin(Vector2 value) - { - Vector2 temp; - Sin(ref value, out temp); - return temp; - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// When the method completes, contains a vector that contains the cosine of each component in the input vector. - public static void Cos(ref Vector2 value, out Vector2 result) - { - result.X = (float)Math.Cos(value.X); - result.Y = (float)Math.Cos(value.Y); - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// A vector that contains the cosine of each component in the input vector. - public static Vector2 Cos(Vector2 value) - { - Vector2 temp; - Cos(ref value, out temp); - return temp; - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// When the method completes, contains a vector that contains the tangent of each component in the input vector. - public static void Tan(ref Vector2 value, out Vector2 result) - { - result.X = (float)Math.Tan(value.X); - result.Y = (float)Math.Tan(value.Y); - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// A vector that contains the tangent of each component in the input vector. - public static Vector2 Tan(Vector2 value) - { - Vector2 temp; - Tan(ref value, out temp); - return temp; - } - #endregion - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// When the method completes, contains the sum of the two vectors. - public static void Add(ref Vector2 left, ref Vector2 right, out Vector2 result) - { - result = new Vector2(left.X + right.X, left.Y + right.Y); - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector2 Add(Vector2 left, Vector2 right) - { - return new Vector2(left.X + right.X, left.Y + right.Y); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// When the method completes, contains the difference of the two vectors. - public static void Subtract(ref Vector2 left, ref Vector2 right, out Vector2 result) - { - result = new Vector2(left.X - right.X, left.Y - right.Y); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector2 Subtract(Vector2 left, Vector2 right) - { - return new Vector2(left.X - right.X, left.Y - right.Y); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Multiply(ref Vector2 value, float scalar, out Vector2 result) - { - result = new Vector2(value.X * scalar, value.Y * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector2 Multiply(Vector2 value, float scalar) - { - return new Vector2(value.X * scalar, value.Y * scalar); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// When the method completes, contains the modulated vector. - public static void Modulate(ref Vector2 left, ref Vector2 right, out Vector2 result) - { - result = new Vector2(left.X * right.X, left.Y * right.Y); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// The modulated vector. - public static Vector2 Modulate(Vector2 left, Vector2 right) - { - return new Vector2(left.X * right.X, left.Y * right.Y); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Divide(ref Vector2 value, float scalar, out Vector2 result) - { - result = new Vector2(value.X / scalar, value.Y / scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector2 Divide(Vector2 value, float scalar) - { - return new Vector2(value.X / scalar, value.Y / scalar); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// When the method completes, contains a vector facing in the opposite direction. - public static void Negate(ref Vector2 value, out Vector2 result) - { - result = new Vector2(-value.X, -value.Y); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector2 Negate(Vector2 value) - { - return new Vector2(-value.X, -value.Y); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// When the method completes, contains a vector that has all positive components. - public static void Abs(ref Vector2 value, out Vector2 result) - { - result = new Vector2(Math.Abs(value.X), Math.Abs(value.Y)); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// A vector that has all positive components. - public static Vector2 Abs(Vector2 value) - { - return new Vector2(Math.Abs(value.X), Math.Abs(value.Y)); - } - - /// - /// Returns a containing the 2D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 2D triangle. - /// - /// A containing the 2D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 2D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 2D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// When the method completes, contains the 2D Cartesian coordinates of the specified point. - public static void Barycentric(ref Vector2 value1, ref Vector2 value2, ref Vector2 value3, float amount1, float amount2, out Vector2 result) - { - result = new Vector2((value1.X + (amount1 * (value2.X - value1.X))) + (amount2 * (value3.X - value1.X)), - (value1.Y + (amount1 * (value2.Y - value1.Y))) + (amount2 * (value3.Y - value1.Y))); - } - - /// - /// Returns a containing the 2D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 2D triangle. - /// - /// A containing the 2D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 2D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 2D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// A new containing the 2D Cartesian coordinates of the specified point. - public static Vector2 Barycentric(Vector2 value1, Vector2 value2, Vector2 value3, float amount1, float amount2) - { - Vector2 result; - Barycentric(ref value1, ref value2, ref value3, amount1, amount2, out result); - return result; - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Vector2 value, ref Vector2 min, ref Vector2 max, out Vector2 result) - { - float x = value.X; - x = (x > max.X) ? max.X : x; - x = (x < min.X) ? min.X : x; - - float y = value.Y; - y = (y > max.Y) ? max.Y : y; - y = (y < min.Y) ? min.Y : y; - - result = new Vector2(x, y); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Vector2 Clamp(Vector2 value, Vector2 min, Vector2 max) - { - Vector2 result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// When the method completes, contains the distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static void Distance(ref Vector2 value1, ref Vector2 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - - result = (float)Math.Sqrt((x * x) + (y * y)); - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static float Distance(Vector2 value1, Vector2 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - - return (float)Math.Sqrt((x * x) + (y * y)); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector - /// When the method completes, contains the squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static void DistanceSquared(ref Vector2 value1, ref Vector2 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - - result = (x * x) + (y * y); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static float DistanceSquared(Vector2 value1, Vector2 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - - return (x * x) + (y * y); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// When the method completes, contains the dot product of the two vectors. - public static void Dot(ref Vector2 left, ref Vector2 right, out float result) - { - result = (left.X * right.X) + (left.Y * right.Y); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// The dot product of the two vectors. - public static float Dot(Vector2 left, Vector2 right) - { - return (left.X * right.X) + (left.Y * right.Y); - } - - /// - /// Calculates a vector that is perpendicular to the given vector. - /// - /// The vector to base the perpendicular vector on. - /// When the method completes, contains the perpendicular vector. - /// - /// This method finds the perpendicular vector using a 90 degree counterclockwise rotation. - /// - public static void Perp(ref Vector2 value, out Vector2 result) - { - result.X = -value.Y; - result.Y = value.X; - } - - /// - /// Calculates a vector that is perpendicular to the given vector. - /// - /// The vector to base the perpendicular vector on. - /// The perpendicular vector. - /// - /// This method finds the perpendicular vector using a 90 degree counterclockwise rotation. - /// - public static Vector2 Perp(Vector2 value) - { - Vector2 result; - Perp(ref value, out result); - return result; - } - - /// - /// Calculates the perp dot product. - /// - /// First source vector. - /// Second source vector. - /// When the method completes, contains the perp dot product of the two vectors. - /// - /// The perp dot product is defined as taking the dot product of the perpendicular vector - /// of the left vector with the right vector. - /// - public static void PerpDot(ref Vector2 left, ref Vector2 right, out float result) - { - Vector2 temp; - Perp(ref left, out temp); - - Dot(ref temp, ref right, out result); - } - - /// - /// Calculates the perp dot product. - /// - /// First source vector. - /// Second source vector. - /// The perp dot product of the two vectors. - /// - /// The perp dot product is defined as taking the dot product of the perpendicular vector - /// of the left vector with the right vector. - /// - public static float PerpDot(Vector2 left, Vector2 right) - { - float result; - PerpDot(ref left, ref right, out result); - return result; - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// When the method completes, contains the normalized vector. - public static void Normalize(ref Vector2 value, out Vector2 result) - { - result = value; - result.Normalize(); - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// The normalized vector. - public static Vector2 Normalize(Vector2 value) - { - value.Normalize(); - return value; - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Vector2 start, ref Vector2 end, float amount, out Vector2 result) - { - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Vector2 Lerp(Vector2 start, Vector2 end, float amount) - { - Vector2 result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Move a point from current to target - /// - /// current point - /// target point - /// distance between - /// distance - public static Vector2 MoveTowards(Vector2 current, Vector2 target, float maxDistanceDelta) - { - float toV_x = target.X - current.X; - float toV_y = target.Y - current.Y; - - float sqDistance = toV_x * toV_x + toV_y * toV_y; - - if (sqDistance == 0 || (maxDistanceDelta >= 0 && sqDistance <= maxDistanceDelta * maxDistanceDelta)) - return target; - - float distance = (float)Math.Sqrt(sqDistance); - - return new Vector2(current.X + toV_x / distance * maxDistanceDelta, - current.Y + toV_y / distance * maxDistanceDelta); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two vectors. - public static void SmoothStep(ref Vector2 start, ref Vector2 end, float amount, out Vector2 result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two vectors. - public static Vector2 SmoothStep(Vector2 start, Vector2 end, float amount) - { - Vector2 result; - SmoothStep(ref start, ref end, amount, out result); - return result; - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// When the method completes, contains the result of the Hermite spline interpolation. - public static void Hermite(ref Vector2 value1, ref Vector2 tangent1, ref Vector2 value2, ref Vector2 tangent2, float amount, out Vector2 result) - { - float squared = amount * amount; - float cubed = amount * squared; - float part1 = ((2.0f * cubed) - (3.0f * squared)) + 1.0f; - float part2 = (-2.0f * cubed) + (3.0f * squared); - float part3 = (cubed - (2.0f * squared)) + amount; - float part4 = cubed - squared; - - result.X = (((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4); - result.Y = (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4); - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// The result of the Hermite spline interpolation. - public static Vector2 Hermite(Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount) - { - Vector2 result; - Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result); - return result; - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// When the method completes, contains the result of the Catmull-Rom interpolation. - public static void CatmullRom(ref Vector2 value1, ref Vector2 value2, ref Vector2 value3, ref Vector2 value4, float amount, out Vector2 result) - { - float squared = amount * amount; - float cubed = amount * squared; - - result.X = 0.5f * ((((2.0f * value2.X) + ((-value1.X + value3.X) * amount)) + - (((((2.0f * value1.X) - (5.0f * value2.X)) + (4.0f * value3.X)) - value4.X) * squared)) + - ((((-value1.X + (3.0f * value2.X)) - (3.0f * value3.X)) + value4.X) * cubed)); - - result.Y = 0.5f * ((((2.0f * value2.Y) + ((-value1.Y + value3.Y) * amount)) + - (((((2.0f * value1.Y) - (5.0f * value2.Y)) + (4.0f * value3.Y)) - value4.Y) * squared)) + - ((((-value1.Y + (3.0f * value2.Y)) - (3.0f * value3.Y)) + value4.Y) * cubed)); - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// A vector that is the result of the Catmull-Rom interpolation. - public static Vector2 CatmullRom(Vector2 value1, Vector2 value2, Vector2 value3, Vector2 value4, float amount) - { - Vector2 result; - CatmullRom(ref value1, ref value2, ref value3, ref value4, amount, out result); - return result; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the largest components of the source vectors. - public static void Max(ref Vector2 value1, ref Vector2 value2, out Vector2 result) - { - result.X = (value1.X > value2.X) ? value1.X : value2.X; - result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the largest components of the source vectors. - public static Vector2 Max(Vector2 value1, Vector2 value2) - { - Vector2 result; - Max(ref value1, ref value2, out result); - return result; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the smallest components of the source vectors. - public static void Min(ref Vector2 value1, ref Vector2 value2, out Vector2 result) - { - result.X = (value1.X < value2.X) ? value1.X : value2.X; - result.Y = (value1.Y < value2.Y) ? value1.Y : value2.Y; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the smallest components of the source vectors. - public static Vector2 Min(Vector2 value1, Vector2 value2) - { - Vector2 result; - Min(ref value1, ref value2, out result); - return result; - } - - /// - /// Returns the reflection of a vector off a surface that has the specified normal. - /// - /// The source vector. - /// Normal of the surface. - /// When the method completes, contains the reflected vector. - /// Reflect only gives the direction of a reflection off a surface, it does not determine - /// whether the original vector was close enough to the surface to hit it. - public static void Reflect(ref Vector2 vector, ref Vector2 normal, out Vector2 result) - { - float dot = (vector.X * normal.X) + (vector.Y * normal.Y); - - result.X = vector.X - ((2.0f * dot) * normal.X); - result.Y = vector.Y - ((2.0f * dot) * normal.Y); - } - - /// - /// Returns the reflection of a vector off a surface that has the specified normal. - /// - /// The source vector. - /// Normal of the surface. - /// The reflected vector. - /// Reflect only gives the direction of a reflection off a surface, it does not determine - /// whether the original vector was close enough to the surface to hit it. - public static Vector2 Reflect(Vector2 vector, Vector2 normal) - { - Vector2 result; - Reflect(ref vector, ref normal, out result); - return result; - } - - /// - /// Returns the fraction of a vector off a surface that has the specified normal and index. - /// - /// The source vector. - /// Normal of the surface. - /// Index of refraction. - /// When the method completes, contains the refracted vector. - public static void Refract(ref Vector2 vector, ref Vector2 normal, float index, out Vector2 result) - { - float cos1; - Dot(ref vector, ref normal, out cos1); - - float radicand = 1.0f - (index * index) * (1.0f - (cos1 * cos1)); - - if (radicand < 0.0f) - { - result = Vector2.Zero; - } - else - { - float cos2 = (float)Math.Sqrt(radicand); - result = (index * vector) + ((cos2 - index * cos1) * normal); - } - } - - /// - /// Returns the fraction of a vector off a surface that has the specified normal and index. - /// - /// The source vector. - /// Normal of the surface. - /// Index of refraction. - /// The refracted vector. - public static Vector2 Refract(Vector2 vector, Vector2 normal, float index) - { - Vector2 result; - Refract(ref vector, ref normal, index, out result); - return result; - } - - /// - /// Orthogonalizes a list of vectors. - /// - /// The list of orthogonalized vectors. - /// The list of vectors to orthogonalize. - /// - /// Orthogonalization is the process of making all vectors orthogonal to each other. This - /// means that any given vector in the list will be orthogonal to any other given vector in the - /// list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthogonalize(Vector2[] destination, params Vector2[] source) - { - //Uses the modified Gram-Schmidt process. - //q1 = m1 - //q2 = m2 - ((q1 ⋅ m2) / (q1 ⋅ q1)) * q1 - //q3 = m3 - ((q1 ⋅ m3) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m3) / (q2 ⋅ q2)) * q2 - //q4 = m4 - ((q1 ⋅ m4) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m4) / (q2 ⋅ q2)) * q2 - ((q3 ⋅ m4) / (q3 ⋅ q3)) * q3 - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector2 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= (Vector2.Dot(destination[r], newvector) / Vector2.Dot(destination[r], destination[r])) * destination[r]; - } - - destination[i] = newvector; - } - } - - /// - /// Orthonormalizes a list of vectors. - /// - /// The list of orthonormalized vectors. - /// The list of vectors to orthonormalize. - /// - /// Orthonormalization is the process of making all vectors orthogonal to each - /// other and making all vectors of unit length. This means that any given vector will - /// be orthogonal to any other given vector in the list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthonormalize(Vector2[] destination, params Vector2[] source) - { - //Uses the modified Gram-Schmidt process. - //Because we are making unit vectors, we can optimize the math for orthogonalization - //and simplify the projection operation to remove the division. - //q1 = m1 / |m1| - //q2 = (m2 - (q1 ⋅ m2) * q1) / |m2 - (q1 ⋅ m2) * q1| - //q3 = (m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2) / |m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2| - //q4 = (m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3) / |m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3| - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector2 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= Vector2.Dot(destination[r], newvector) * destination[r]; - } - - newvector.Normalize(); - destination[i] = newvector; - } - } - - /// - /// Transforms a 2D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// When the method completes, contains the transformed . - public static void Transform(ref Vector2 vector, ref Quaternion rotation, out Vector2 result) - { - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float yy = rotation.Y * y; - float zz = rotation.Z * z; - - float num1 = (1.0f - yy - zz); - float num2 = (xy - wz); - float num3 = (xy + wz); - float num4 = (1.0f - xx - zz); - - result = new Vector2( - (vector.X * num1) + (vector.Y * num2), - (vector.X * num3) + (vector.Y * num4)); - } - - /// - /// Transforms a 2D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// The transformed . - public static Vector2 Transform(Vector2 vector, Quaternion rotation) - { - Vector2 result; - Transform(ref vector, ref rotation, out result); - return result; - } - - /// - /// Transforms an array of vectors by the given rotation. - /// - /// The array of vectors to transform. - /// The rotation to apply. - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector2[] source, ref Quaternion rotation, Vector2[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float yy = rotation.Y * y; - float zz = rotation.Z * z; - - float num1 = (1.0f - yy - zz); - float num2 = (xy - wz); - float num3 = (xy + wz); - float num4 = (1.0f - xx - zz); - - for (int i = 0; i < source.Length; ++i) - { - destination[i] = new Vector2( - (source[i].X * num1) + (source[i].Y * num2), - (source[i].X * num3) + (source[i].Y * num4)); - } - } - - /// - /// Transforms a 2D vector by the given . - /// - /// The source vector. - /// The transformation . - /// When the method completes, contains the transformed . - public static void Transform(ref Vector2 vector, ref Matrix transform, out Vector4 result) - { - result = new Vector4( - (vector.X * transform.M11) + (vector.Y * transform.M21) + transform.M41, - (vector.X * transform.M12) + (vector.Y * transform.M22) + transform.M42, - (vector.X * transform.M13) + (vector.Y * transform.M23) + transform.M43, - (vector.X * transform.M14) + (vector.Y * transform.M24) + transform.M44); - } - - /// - /// Transforms a 2D vector by the given . - /// - /// The source vector. - /// The transformation . - /// The transformed . - public static Vector4 Transform(Vector2 vector, Matrix transform) - { - Vector4 result; - Transform(ref vector, ref transform, out result); - return result; - } - - /// - /// Transforms an array of 2D vectors by the given . - /// - /// The array of vectors to transform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector2[] source, ref Matrix transform, Vector4[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Transform(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Performs a coordinate transformation using the given . - /// - /// The coordinate vector to transform. - /// The transformation . - /// When the method completes, contains the transformed coordinates. - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static void TransformCoordinate(ref Vector2 coordinate, ref Matrix transform, out Vector2 result) - { - Vector4 vector = new Vector4(); - vector.X = (coordinate.X * transform.M11) + (coordinate.Y * transform.M21) + transform.M41; - vector.Y = (coordinate.X * transform.M12) + (coordinate.Y * transform.M22) + transform.M42; - vector.Z = (coordinate.X * transform.M13) + (coordinate.Y * transform.M23) + transform.M43; - vector.W = 1f / ((coordinate.X * transform.M14) + (coordinate.Y * transform.M24) + transform.M44); - - result = new Vector2(vector.X * vector.W, vector.Y * vector.W); - } - - /// - /// Performs a coordinate transformation using the given . - /// - /// The coordinate vector to transform. - /// The transformation . - /// The transformed coordinates. - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static Vector2 TransformCoordinate(Vector2 coordinate, Matrix transform) - { - Vector2 result; - TransformCoordinate(ref coordinate, ref transform, out result); - return result; - } - - /// - /// Performs a coordinate transformation on an array of vectors using the given . - /// - /// The array of coordinate vectors to trasnform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static void TransformCoordinate(Vector2[] source, ref Matrix transform, Vector2[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - TransformCoordinate(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Performs a normal transformation using the given . - /// - /// The normal vector to transform. - /// The transformation . - /// When the method completes, contains the transformed normal. - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static void TransformNormal(ref Vector2 normal, ref Matrix transform, out Vector2 result) - { - result = new Vector2( - (normal.X * transform.M11) + (normal.Y * transform.M21), - (normal.X * transform.M12) + (normal.Y * transform.M22)); - } - - /// - /// Performs a normal transformation using the given . - /// - /// The normal vector to transform. - /// The transformation . - /// The transformed normal. - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static Vector2 TransformNormal(Vector2 normal, Matrix transform) - { - Vector2 result; - TransformNormal(ref normal, ref transform, out result); - return result; - } - - /// - /// Performs a normal transformation on an array of vectors using the given . - /// - /// The array of normal vectors to transform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static void TransformNormal(Vector2[] source, ref Matrix transform, Vector2[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - TransformNormal(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector2 operator +(Vector2 left, Vector2 right) - { - return new Vector2(left.X + right.X, left.Y + right.Y); - } - - /// - /// Assert a vector (return it unchanged). - /// - /// The vector to assert (unchange). - /// The asserted (unchanged) vector. - public static Vector2 operator +(Vector2 value) - { - return value; - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector2 operator -(Vector2 left, Vector2 right) - { - return new Vector2(left.X - right.X, left.Y - right.Y); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector2 operator -(Vector2 value) - { - return new Vector2(-value.X, -value.Y); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector2 operator *(float scalar, Vector2 value) - { - return new Vector2(value.X * scalar, value.Y * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector2 operator *(Vector2 value, float scalar) - { - return new Vector2(value.X * scalar, value.Y * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector2 operator /(Vector2 value, float scalar) - { - return new Vector2(value.X / scalar, value.Y / scalar); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Vector2 left, Vector2 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Vector2 left, Vector2 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(Vector2 value) - { - return new Vector3(value, 0.0f); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector4(Vector2 value) - { - return new Vector4(value, 0.0f, 0.0f); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X, Y); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X.ToString(format, CultureInfo.CurrentCulture), Y.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1}", X, Y); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1}", X.ToString(format, formatProvider), Y.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector2 other) - { - return (this.X == other.X) && (this.Y == other.Y); - } - - /// - /// Determines whether the specified is equal to this instance using an epsilon value. - /// - /// The to compare with this instance. - /// The amount of error allowed. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector2 other, float epsilon) - { - return ((float)Math.Abs(other.X - X) < epsilon && - (float)Math.Abs(other.Y - Y) < epsilon); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Vector2)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Vector2(Vector2 value) - { - return new SlimDX.Vector2(value.X, value.Y); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector2(SlimDX.Vector2 value) - { - return new Vector2(value.X, value.Y); - } -#endif - -#if WPFInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator System.Windows.Point(Vector2 value) - { - return new System.Windows.Point(value.X, value.Y); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector2(System.Windows.Point value) - { - return new Vector2((float)value.X, (float)value.Y); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Vector2(Vector2 value) - { - return new Microsoft.Xna.Framework.Vector2(value.X, value.Y); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector2(Microsoft.Xna.Framework.Vector2 value) - { - return new Vector2(value.X, value.Y); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Vector3.cs b/source/OrkEngine3D.Mathematics/Vector3.cs deleted file mode 100644 index 1add121..0000000 --- a/source/OrkEngine3D.Mathematics/Vector3.cs +++ /dev/null @@ -1,1953 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a three dimensional mathematical vector. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -[TypeConverter(typeof(Design.Vector3Converter))] -public struct Vector3 : IEquatable, IFormattable -{ - /// - /// The size of the type, in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Vector3)); - - /// - /// A with all of its components set to zero. - /// - public static readonly Vector3 Zero = new Vector3(); - - /// - /// The X unit (1, 0, 0). - /// - public static readonly Vector3 UnitX = new Vector3(1.0f, 0.0f, 0.0f); - - /// - /// The Y unit (0, 1, 0). - /// - public static readonly Vector3 UnitY = new Vector3(0.0f, 1.0f, 0.0f); - - /// - /// The Z unit (0, 0, 1). - /// - public static readonly Vector3 UnitZ = new Vector3(0.0f, 0.0f, 1.0f); - - /// - /// A with all of its components set to one. - /// - public static readonly Vector3 One = new Vector3(1.0f, 1.0f, 1.0f); - - /// - /// The X component of the vector. - /// - public float X; - - /// - /// The Y component of the vector. - /// - public float Y; - - /// - /// The Z component of the vector. - /// - public float Z; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Vector3(float value) - { - X = value; - Y = value; - Z = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// Initial value for the X component of the vector. - /// Initial value for the Y component of the vector. - /// Initial value for the Z component of the vector. - public Vector3(float x, float y, float z) - { - X = x; - Y = y; - Z = z; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the X and Y components. - /// Initial value for the Z component of the vector. - public Vector3(Vector2 value, float z) - { - X = value.X; - Y = value.Y; - Z = z; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X, Y, and Z components of the vector. This must be an array with three elements. - /// Thrown when is null. - /// Thrown when contains more or less than three elements. - public Vector3(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 3) - throw new ArgumentOutOfRangeException("values", "There must be three and only three input values for Vector3."); - - X = values[0]; - Y = values[1]; - Z = values[2]; - } - - /// - /// Gets a value indicting whether this instance is normalized. - /// - public bool IsNormalized - { - get { return Math.Abs((X * X) + (Y * Y) + (Z * Z) - 1f) < Utilities.ZeroTolerance; } - } - - // - /// Returns the length of the vector. - /// - /// The vector's length. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Length() - { - if (Vector.IsHardwareAccelerated) - { - float ls = Vector3.Dot(this, this); - return (float)System.Math.Sqrt(ls); - } - else - { - float ls = X * X + Y * Y + Z * Z; - return (float)System.Math.Sqrt(ls); - } - } - - /// - /// Returns the length of the vector squared. This operation is cheaper than Length(). - /// - /// The vector's length squared. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float LengthSquared() - { - if (Vector.IsHardwareAccelerated) - { - return Vector3.Dot(this, this); - } - else - { - return X * X + Y * Y + Z * Z; - } - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the X, Y, or Z component, depending on the index. - /// The index of the component to access. Use 0 for the X component, 1 for the Y component, and 2 for the Z component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 2]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return X; - case 1: return Y; - case 2: return Z; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Vector3 run from 0 to 2, inclusive."); - } - - set - { - switch (index) - { - case 0: X = value; break; - case 1: Y = value; break; - case 2: Z = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Vector3 run from 0 to 2, inclusive."); - } - } - } - - /// - /// Converts the vector into a unit vector. - /// - public void Normalize() - { - float length = Length(); - if (length > Utilities.ZeroTolerance) - { - float inv = 1.0f / length; - X *= inv; - Y *= inv; - Z *= inv; - } - } - - /// - /// Reverses the direction of a given vector. - /// - public void Negate() - { - X = -X; - Y = -Y; - Z = -Z; - } - - /// - /// Takes the absolute value of each component. - /// - public void Abs() - { - this.X = Math.Abs(X); - this.Y = Math.Abs(Y); - this.Z = Math.Abs(Z); - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A three-element array containing the components of the vector. - public float[] ToArray() - { - return new float[] { X, Y, Z }; - } - - #region Transcendentals - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// When the method completes, contains a vector that is the square root of the input vector. - public static void Sqrt(ref Vector3 value, out Vector3 result) - { - result.X = (float)Math.Sqrt(value.X); - result.Y = (float)Math.Sqrt(value.Y); - result.Z = (float)Math.Sqrt(value.Z); - } - - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// A vector that is the square root of the input vector. - public static Vector3 Sqrt(Vector3 value) - { - Vector3 temp; - Sqrt(ref value, out temp); - return temp; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// When the method completes, contains a vector that is the reciprocal of the input vector. - public static void Reciprocal(ref Vector3 value, out Vector3 result) - { - result.X = 1.0f / value.X; - result.Y = 1.0f / value.Y; - result.Z = 1.0f / value.Z; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// A vector that is the reciprocal of the input vector. - public static Vector3 Reciprocal(Vector3 value) - { - Vector3 temp; - Reciprocal(ref value, out temp); - return temp; - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// When the method completes, contains a vector that is the square root and reciprocal of the input vector. - public static void ReciprocalSqrt(ref Vector3 value, out Vector3 result) - { - result.X = 1.0f / (float)Math.Sqrt(value.X); - result.Y = 1.0f / (float)Math.Sqrt(value.Y); - result.Z = 1.0f / (float)Math.Sqrt(value.Z); - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// A vector that is the square root and reciprocal of the input vector. - public static Vector3 ReciprocalSqrt(Vector3 value) - { - Vector3 temp; - ReciprocalSqrt(ref value, out temp); - return temp; - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// When the method completes, contains a vector that has e raised to each of the components in the input vector. - public static void Exp(ref Vector3 value, out Vector3 result) - { - result.X = (float)Math.Exp(value.X); - result.Y = (float)Math.Exp(value.Y); - result.Z = (float)Math.Exp(value.Z); - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// A vector that has e raised to each of the components in the input vector. - public static Vector3 Exp(Vector3 value) - { - Vector3 temp; - Exp(ref value, out temp); - return temp; - } - - /// - /// Takes the sine and than the cosine of each component in the vector. - /// - /// The vector to take the sine and cosine of. - /// When the method completes, contains the sine of each component in the input vector. - /// When the method completes, contains the cpsome pf each component in the input vector. - public static void SinCos(ref Vector3 value, out Vector3 sinResult, out Vector3 cosResult) - { - sinResult.X = (float)Math.Sin(value.X); - sinResult.Y = (float)Math.Sin(value.Y); - sinResult.Z = (float)Math.Sin(value.Z); - - cosResult.X = (float)Math.Cos(value.X); - cosResult.Y = (float)Math.Cos(value.Y); - cosResult.Z = (float)Math.Cos(value.Z); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// When the method completes, a vector that contains the sine of each component in the input vector. - public static void Sin(ref Vector3 value, out Vector3 result) - { - result.X = (float)Math.Sin(value.X); - result.Y = (float)Math.Sin(value.Y); - result.Z = (float)Math.Sin(value.Z); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// A vector that contains the sine of each component in the input vector. - public static Vector3 Sin(Vector3 value) - { - Vector3 temp; - Sin(ref value, out temp); - return temp; - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// When the method completes, contains a vector that contains the cosine of each component in the input vector. - public static void Cos(ref Vector3 value, out Vector3 result) - { - result.X = (float)Math.Cos(value.X); - result.Y = (float)Math.Cos(value.Y); - result.Z = (float)Math.Cos(value.Z); - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// A vector that contains the cosine of each component in the input vector. - public static Vector3 Cos(Vector3 value) - { - Vector3 temp; - Cos(ref value, out temp); - return temp; - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// When the method completes, contains a vector that contains the tangent of each component in the input vector. - public static void Tan(ref Vector3 value, out Vector3 result) - { - result.X = (float)Math.Tan(value.X); - result.Y = (float)Math.Tan(value.Y); - result.Z = (float)Math.Tan(value.Z); - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// A vector that contains the tangent of each component in the input vector. - public static Vector3 Tan(Vector3 value) - { - Vector3 temp; - Tan(ref value, out temp); - return temp; - } - #endregion - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// When the method completes, contains the sum of the two vectors. - public static void Add(ref Vector3 left, ref Vector3 right, out Vector3 result) - { - result = new Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z); - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector3 Add(Vector3 left, Vector3 right) - { - return new Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// When the method completes, contains the difference of the two vectors. - public static void Subtract(ref Vector3 left, ref Vector3 right, out Vector3 result) - { - result = new Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector3 Subtract(Vector3 left, Vector3 right) - { - return new Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Multiply(ref Vector3 value, float scalar, out Vector3 result) - { - result = new Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector3 Multiply(Vector3 value, float scalar) - { - return new Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// When the method completes, contains the modulated vector. - public static void Modulate(ref Vector3 left, ref Vector3 right, out Vector3 result) - { - result = new Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// The modulated vector. - public static Vector3 Modulate(Vector3 left, Vector3 right) - { - return new Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Divide(ref Vector3 value, float scalar, out Vector3 result) - { - result = new Vector3(value.X / scalar, value.Y / scalar, value.Z / scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector3 Divide(Vector3 value, float scalar) - { - return new Vector3(value.X / scalar, value.Y / scalar, value.Z / scalar); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// When the method completes, contains a vector facing in the opposite direction. - public static void Negate(ref Vector3 value, out Vector3 result) - { - result = new Vector3(-value.X, -value.Y, -value.Z); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector3 Negate(Vector3 value) - { - return new Vector3(-value.X, -value.Y, -value.Z); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// When the method completes, contains a vector that has all positive components. - public static void Abs(ref Vector3 value, out Vector3 result) - { - result = new Vector3(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z)); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// A vector that has all positive components. - public static Vector3 Abs(Vector3 value) - { - return new Vector3(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z)); - } - - /// - /// Returns a containing the 3D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 3D triangle. - /// - /// A containing the 3D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 3D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 3D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// When the method completes, contains the 3D Cartesian coordinates of the specified point. - public static void Barycentric(ref Vector3 value1, ref Vector3 value2, ref Vector3 value3, float amount1, float amount2, out Vector3 result) - { - result = new Vector3((value1.X + (amount1 * (value2.X - value1.X))) + (amount2 * (value3.X - value1.X)), - (value1.Y + (amount1 * (value2.Y - value1.Y))) + (amount2 * (value3.Y - value1.Y)), - (value1.Z + (amount1 * (value2.Z - value1.Z))) + (amount2 * (value3.Z - value1.Z))); - } - - /// - /// Returns a containing the 3D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 3D triangle. - /// - /// A containing the 3D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 3D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 3D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// A new containing the 3D Cartesian coordinates of the specified point. - public static Vector3 Barycentric(Vector3 value1, Vector3 value2, Vector3 value3, float amount1, float amount2) - { - Vector3 result; - Barycentric(ref value1, ref value2, ref value3, amount1, amount2, out result); - return result; - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Vector3 value, ref Vector3 min, ref Vector3 max, out Vector3 result) - { - float x = value.X; - x = (x > max.X) ? max.X : x; - x = (x < min.X) ? min.X : x; - - float y = value.Y; - y = (y > max.Y) ? max.Y : y; - y = (y < min.Y) ? min.Y : y; - - float z = value.Z; - z = (z > max.Z) ? max.Z : z; - z = (z < min.Z) ? min.Z : z; - - result = new Vector3(x, y, z); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Vector3 Clamp(Vector3 value, Vector3 min, Vector3 max) - { - Vector3 result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Calculates the cross product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// When the method completes, contains the cross product of the two vectors. - public static void Cross(ref Vector3 left, ref Vector3 right, out Vector3 result) - { - result = new Vector3( - (left.Y * right.Z) - (left.Z * right.Y), - (left.Z * right.X) - (left.X * right.Z), - (left.X * right.Y) - (left.Y * right.X)); - } - - /// - /// Calculates the cross product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// The cross product of the two vectors. - public static Vector3 Cross(Vector3 left, Vector3 right) - { - Vector3 result; - Cross(ref left, ref right, out result); - return result; - } - - /// - /// Calculates the tripple cross product of three vectors. - /// - /// First source vector. - /// Second source vector. - /// Third source vector. - /// When the method completes, contains the tripple cross product of the three vectors. - public static void TripleProduct(ref Vector3 value1, ref Vector3 value2, ref Vector3 value3, out float result) - { - Vector3 temp; - Vector3.Cross(ref value2, ref value3, out temp); - Vector3.Dot(ref value1, ref temp, out result); - } - - /// - /// Calculates the tripple cross product of three vectors. - /// - /// First source vector. - /// Second source vector. - /// Third source vector. - /// The tripple cross product of the three vectors. - public static float TripleProduct(Vector3 value1, Vector3 value2, Vector3 value3) - { - float result; - TripleProduct(ref value1, ref value2, ref value3, out result); - return result; - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// When the method completes, contains the distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static void Distance(ref Vector3 value1, ref Vector3 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - - result = (float)Math.Sqrt((x * x) + (y * y) + (z * z)); - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static float Distance(Vector3 value1, Vector3 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - - return (float)Math.Sqrt((x * x) + (y * y) + (z * z)); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// When the method completes, contains the squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static void DistanceSquared(ref Vector3 value1, ref Vector3 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - - result = (x * x) + (y * y) + (z * z); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static float DistanceSquared(Vector3 value1, Vector3 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - - return (x * x) + (y * y) + (z * z); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// When the method completes, contains the dot product of the two vectors. - public static void Dot(ref Vector3 left, ref Vector3 right, out float result) - { - result = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// The dot product of the two vectors. - public static float Dot(Vector3 left, Vector3 right) - { - return (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z); - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// When the method completes, contains the normalized vector. - public static void Normalize(ref Vector3 value, out Vector3 result) - { - result = value; - result.Normalize(); - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// The normalized vector. - public static Vector3 Normalize(Vector3 value) - { - value.Normalize(); - return value; - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Vector3 start, ref Vector3 end, float amount, out Vector3 result) - { - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - result.Z = start.Z + ((end.Z - start.Z) * amount); - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Vector3 Lerp(Vector3 start, Vector3 end, float amount) - { - Vector3 result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Move a point from current to target - /// - /// current point - /// target point - /// distance between - /// distance - public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta) - { - float toV_x = target.X - current.X; - float toV_y = target.Y - current.Y; - float toV_z = target.Z - current.Z; - - float sqDistance = toV_x * toV_x + toV_y * toV_y + toV_z * toV_z; - - if (sqDistance == 0 || (maxDistanceDelta >= 0 && sqDistance <= maxDistanceDelta * maxDistanceDelta)) - return target; - - var distance = (float)Math.Sqrt(sqDistance); - - return new Vector3(current.X + toV_x / distance * maxDistanceDelta, - current.Y + toV_y / distance * maxDistanceDelta, - current.Z + toV_z / distance * maxDistanceDelta); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two vectors. - public static void SmoothStep(ref Vector3 start, ref Vector3 end, float amount, out Vector3 result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - result.Z = start.Z + ((end.Z - start.Z) * amount); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two vectors. - public static Vector3 SmoothStep(Vector3 start, Vector3 end, float amount) - { - Vector3 result; - SmoothStep(ref start, ref end, amount, out result); - return result; - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// When the method completes, contains the result of the Hermite spline interpolation. - public static void Hermite(ref Vector3 value1, ref Vector3 tangent1, ref Vector3 value2, ref Vector3 tangent2, float amount, out Vector3 result) - { - float squared = amount * amount; - float cubed = amount * squared; - float part1 = ((2.0f * cubed) - (3.0f * squared)) + 1.0f; - float part2 = (-2.0f * cubed) + (3.0f * squared); - float part3 = (cubed - (2.0f * squared)) + amount; - float part4 = cubed - squared; - - result.X = (((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4); - result.Y = (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4); - result.Z = (((value1.Z * part1) + (value2.Z * part2)) + (tangent1.Z * part3)) + (tangent2.Z * part4); - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// The result of the Hermite spline interpolation. - public static Vector3 Hermite(Vector3 value1, Vector3 tangent1, Vector3 value2, Vector3 tangent2, float amount) - { - Vector3 result; - Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result); - return result; - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// When the method completes, contains the result of the Catmull-Rom interpolation. - public static void CatmullRom(ref Vector3 value1, ref Vector3 value2, ref Vector3 value3, ref Vector3 value4, float amount, out Vector3 result) - { - float squared = amount * amount; - float cubed = amount * squared; - - result.X = 0.5f * ((((2.0f * value2.X) + ((-value1.X + value3.X) * amount)) + - (((((2.0f * value1.X) - (5.0f * value2.X)) + (4.0f * value3.X)) - value4.X) * squared)) + - ((((-value1.X + (3.0f * value2.X)) - (3.0f * value3.X)) + value4.X) * cubed)); - - result.Y = 0.5f * ((((2.0f * value2.Y) + ((-value1.Y + value3.Y) * amount)) + - (((((2.0f * value1.Y) - (5.0f * value2.Y)) + (4.0f * value3.Y)) - value4.Y) * squared)) + - ((((-value1.Y + (3.0f * value2.Y)) - (3.0f * value3.Y)) + value4.Y) * cubed)); - - result.Z = 0.5f * ((((2.0f * value2.Z) + ((-value1.Z + value3.Z) * amount)) + - (((((2.0f * value1.Z) - (5.0f * value2.Z)) + (4.0f * value3.Z)) - value4.Z) * squared)) + - ((((-value1.Z + (3.0f * value2.Z)) - (3.0f * value3.Z)) + value4.Z) * cubed)); - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// A vector that is the result of the Catmull-Rom interpolation. - public static Vector3 CatmullRom(Vector3 value1, Vector3 value2, Vector3 value3, Vector3 value4, float amount) - { - Vector3 result; - CatmullRom(ref value1, ref value2, ref value3, ref value4, amount, out result); - return result; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the largest components of the source vectors. - public static void Max(ref Vector3 value1, ref Vector3 value2, out Vector3 result) - { - result.X = (value1.X > value2.X) ? value1.X : value2.X; - result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y; - result.Z = (value1.Z > value2.Z) ? value1.Z : value2.Z; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the largest components of the source vectors. - public static Vector3 Max(Vector3 value1, Vector3 value2) - { - Vector3 result; - Max(ref value1, ref value2, out result); - return result; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the smallest components of the source vectors. - public static void Min(ref Vector3 value1, ref Vector3 value2, out Vector3 result) - { - result.X = (value1.X < value2.X) ? value1.X : value2.X; - result.Y = (value1.Y < value2.Y) ? value1.Y : value2.Y; - result.Z = (value1.Z < value2.Z) ? value1.Z : value2.Z; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the smallest components of the source vectors. - public static Vector3 Min(Vector3 value1, Vector3 value2) - { - Vector3 result; - Min(ref value1, ref value2, out result); - return result; - } - - /// - /// Projects a 3D vector from object space into screen space. - /// - /// The vector to project. - /// The X position of the viewport. - /// The Y position of the viewport. - /// The width of the viewport. - /// The height of the viewport. - /// The minimum depth of the viewport. - /// The maximum depth of the viewport. - /// The combined world-view-projection matrix. - /// When the method completes, contains the vector in screen space. - public static void Project(ref Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, ref Matrix worldViewProjection, out Vector3 result) - { - Vector3 v = new Vector3(); - TransformCoordinate(ref vector, ref worldViewProjection, out v); - - result = new Vector3(((1.0f + v.X) * 0.5f * width) + x, ((1.0f - v.Y) * 0.5f * height) + y, (v.Z * (maxZ - minZ)) + minZ); - } - - /// - /// Projects a 3D vector from object space into screen space. - /// - /// The vector to project. - /// The X position of the viewport. - /// The Y position of the viewport. - /// The width of the viewport. - /// The height of the viewport. - /// The minimum depth of the viewport. - /// The maximum depth of the viewport. - /// The combined world-view-projection matrix. - /// The vector in screen space. - public static Vector3 Project(Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, Matrix worldViewProjection) - { - Vector3 result; - Project(ref vector, x, y, width, height, minZ, maxZ, ref worldViewProjection, out result); - return result; - } - - /// - /// Projects a 3D vector from screen space into object space. - /// - /// The vector to project. - /// The X position of the viewport. - /// The Y position of the viewport. - /// The width of the viewport. - /// The height of the viewport. - /// The minimum depth of the viewport. - /// The maximum depth of the viewport. - /// The combined world-view-projection matrix. - /// When the method completes, contains the vector in object space. - public static void Unproject(ref Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, ref Matrix worldViewProjection, out Vector3 result) - { - Vector3 v = new Vector3(); - Matrix matrix = new Matrix(); - Matrix.Invert(ref worldViewProjection, out matrix); - - v.X = (((vector.X - x) / width) * 2.0f) - 1.0f; - v.Y = -((((vector.Y - y) / height) * 2.0f) - 1.0f); - v.Z = (vector.Z - minZ) / (maxZ - minZ); - - TransformCoordinate(ref v, ref matrix, out result); - } - - /// - /// Projects a 3D vector from screen space into object space. - /// - /// The vector to project. - /// The X position of the viewport. - /// The Y position of the viewport. - /// The width of the viewport. - /// The height of the viewport. - /// The minimum depth of the viewport. - /// The maximum depth of the viewport. - /// The combined world-view-projection matrix. - /// The vector in object space. - public static Vector3 Unproject(Vector3 vector, float x, float y, float width, float height, float minZ, float maxZ, Matrix worldViewProjection) - { - Vector3 result; - Unproject(ref vector, x, y, width, height, minZ, maxZ, ref worldViewProjection, out result); - return result; - } - - /// - /// Returns the reflection of a vector off a surface that has the specified normal. - /// - /// The source vector. - /// Normal of the surface. - /// When the method completes, contains the reflected vector. - /// Reflect only gives the direction of a reflection off a surface, it does not determine - /// whether the original vector was close enough to the surface to hit it. - public static void Reflect(ref Vector3 vector, ref Vector3 normal, out Vector3 result) - { - float dot = (vector.X * normal.X) + (vector.Y * normal.Y) + (vector.Z * normal.Z); - - result.X = vector.X - ((2.0f * dot) * normal.X); - result.Y = vector.Y - ((2.0f * dot) * normal.Y); - result.Z = vector.Z - ((2.0f * dot) * normal.Z); - } - - /// - /// Returns the reflection of a vector off a surface that has the specified normal. - /// - /// The source vector. - /// Normal of the surface. - /// The reflected vector. - /// Reflect only gives the direction of a reflection off a surface, it does not determine - /// whether the original vector was close enough to the surface to hit it. - public static Vector3 Reflect(Vector3 vector, Vector3 normal) - { - Vector3 result; - Reflect(ref vector, ref normal, out result); - return result; - } - - /// - /// Returns the fraction of a vector off a surface that has the specified normal and index. - /// - /// The source vector. - /// Normal of the surface. - /// Index of refraction. - /// When the method completes, contains the refracted vector. - public static void Refract(ref Vector3 vector, ref Vector3 normal, float index, out Vector3 result) - { - float cos1; - Dot(ref vector, ref normal, out cos1); - - float radicand = 1.0f - (index * index) * (1.0f - (cos1 * cos1)); - - if (radicand < 0.0f) - { - result = Vector3.Zero; - } - else - { - float cos2 = (float)Math.Sqrt(radicand); - result = (index * vector) + ((cos2 - index * cos1) * normal); - } - } - - /// - /// Returns the fraction of a vector off a surface that has the specified normal and index. - /// - /// The source vector. - /// Normal of the surface. - /// Index of refraction. - /// The refracted vector. - public static Vector3 Refract(Vector3 vector, Vector3 normal, float index) - { - Vector3 result; - Refract(ref vector, ref normal, index, out result); - return result; - } - - /// - /// Orthogonalizes a list of vectors. - /// - /// The list of orthogonalized vectors. - /// The list of vectors to orthogonalize. - /// - /// Orthogonalization is the process of making all vectors orthogonal to each other. This - /// means that any given vector in the list will be orthogonal to any other given vector in the - /// list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthogonalize(Vector3[] destination, params Vector3[] source) - { - //Uses the modified Gram-Schmidt process. - //q1 = m1 - //q2 = m2 - ((q1 ⋅ m2) / (q1 ⋅ q1)) * q1 - //q3 = m3 - ((q1 ⋅ m3) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m3) / (q2 ⋅ q2)) * q2 - //q4 = m4 - ((q1 ⋅ m4) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m4) / (q2 ⋅ q2)) * q2 - ((q3 ⋅ m4) / (q3 ⋅ q3)) * q3 - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector3 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= (Vector3.Dot(destination[r], newvector) / Vector3.Dot(destination[r], destination[r])) * destination[r]; - } - - destination[i] = newvector; - } - } - - /// - /// Orthonormalizes a list of vectors. - /// - /// The list of orthonormalized vectors. - /// The list of vectors to orthonormalize. - /// - /// Orthonormalization is the process of making all vectors orthogonal to each - /// other and making all vectors of unit length. This means that any given vector will - /// be orthogonal to any other given vector in the list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthonormalize(Vector3[] destination, params Vector3[] source) - { - //Uses the modified Gram-Schmidt process. - //Because we are making unit vectors, we can optimize the math for orthogonalization - //and simplify the projection operation to remove the division. - //q1 = m1 / |m1| - //q2 = (m2 - (q1 ⋅ m2) * q1) / |m2 - (q1 ⋅ m2) * q1| - //q3 = (m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2) / |m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2| - //q4 = (m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3) / |m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3| - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector3 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= Vector3.Dot(destination[r], newvector) * destination[r]; - } - - newvector.Normalize(); - destination[i] = newvector; - } - } - - /// - /// Transforms a 3D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// When the method completes, contains the transformed . - public static void Transform(ref Vector3 vector, ref Quaternion rotation, out Vector3 result) - { - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wx = rotation.W * x; - float wy = rotation.W * y; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float xz = rotation.X * z; - float yy = rotation.Y * y; - float yz = rotation.Y * z; - float zz = rotation.Z * z; - - float num1 = ((1.0f - yy) - zz); - float num2 = (xy - wz); - float num3 = (xz + wy); - float num4 = (xy + wz); - float num5 = ((1.0f - xx) - zz); - float num6 = (yz - wx); - float num7 = (xz - wy); - float num8 = (yz + wx); - float num9 = ((1.0f - xx) - yy); - - result = new Vector3( - ((vector.X * num1) + (vector.Y * num2)) + (vector.Z * num3), - ((vector.X * num4) + (vector.Y * num5)) + (vector.Z * num6), - ((vector.X * num7) + (vector.Y * num8)) + (vector.Z * num9)); - } - - /// - /// Transforms a 3D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// The transformed . - public static Vector3 Transform(Vector3 vector, Quaternion rotation) - { - Vector3 result; - Transform(ref vector, ref rotation, out result); - return result; - } - - /// - /// Transforms an array of vectors by the given rotation. - /// - /// The array of vectors to transform. - /// The rotation to apply. - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector3[] source, ref Quaternion rotation, Vector3[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wx = rotation.W * x; - float wy = rotation.W * y; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float xz = rotation.X * z; - float yy = rotation.Y * y; - float yz = rotation.Y * z; - float zz = rotation.Z * z; - - float num1 = ((1.0f - yy) - zz); - float num2 = (xy - wz); - float num3 = (xz + wy); - float num4 = (xy + wz); - float num5 = ((1.0f - xx) - zz); - float num6 = (yz - wx); - float num7 = (xz - wy); - float num8 = (yz + wx); - float num9 = ((1.0f - xx) - yy); - - for (int i = 0; i < source.Length; ++i) - { - destination[i] = new Vector3( - ((source[i].X * num1) + (source[i].Y * num2)) + (source[i].Z * num3), - ((source[i].X * num4) + (source[i].Y * num5)) + (source[i].Z * num6), - ((source[i].X * num7) + (source[i].Y * num8)) + (source[i].Z * num9)); - } - } - - /// - /// Transforms a 3D vector by the given . - /// - /// The source vector. - /// The transformation . - /// When the method completes, contains the transformed . - public static void Transform(ref Vector3 vector, ref Matrix transform, out Vector4 result) - { - result = new Vector4( - (vector.X * transform.M11) + (vector.Y * transform.M21) + (vector.Z * transform.M31) + transform.M41, - (vector.X * transform.M12) + (vector.Y * transform.M22) + (vector.Z * transform.M32) + transform.M42, - (vector.X * transform.M13) + (vector.Y * transform.M23) + (vector.Z * transform.M33) + transform.M43, - (vector.X * transform.M14) + (vector.Y * transform.M24) + (vector.Z * transform.M34) + transform.M44); - } - - /// - /// Transforms a 3D vector by the given . - /// - /// The source vector. - /// The transformation . - /// The transformed . - public static Vector4 Transform(Vector3 vector, Matrix transform) - { - Vector4 result; - Transform(ref vector, ref transform, out result); - return result; - } - - /// - /// Transforms an array of 3D vectors by the given . - /// - /// The array of vectors to transform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector3[] source, ref Matrix transform, Vector4[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Transform(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Transforms a vector by the given matrix. - /// - /// The source vector. - /// The transformation matrix. - /// The transformed vector. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Transform(Vector3 position, Matrix4x4 matrix) - { - return new Vector3( - position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31 + matrix.M41, - position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32 + matrix.M42, - position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33 + matrix.M43); - } - - /// - /// Performs a coordinate transformation using the given . - /// - /// The coordinate vector to transform. - /// The transformation . - /// When the method completes, contains the transformed coordinates. - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static void TransformCoordinate(ref Vector3 coordinate, ref Matrix transform, out Vector3 result) - { - Vector4 vector = new Vector4(); - vector.X = (coordinate.X * transform.M11) + (coordinate.Y * transform.M21) + (coordinate.Z * transform.M31) + transform.M41; - vector.Y = (coordinate.X * transform.M12) + (coordinate.Y * transform.M22) + (coordinate.Z * transform.M32) + transform.M42; - vector.Z = (coordinate.X * transform.M13) + (coordinate.Y * transform.M23) + (coordinate.Z * transform.M33) + transform.M43; - vector.W = 1f / ((coordinate.X * transform.M14) + (coordinate.Y * transform.M24) + (coordinate.Z * transform.M34) + transform.M44); - - result = new Vector3(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W); - } - - /// - /// Performs a coordinate transformation using the given . - /// - /// The coordinate vector to transform. - /// The transformation . - /// The transformed coordinates. - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static Vector3 TransformCoordinate(Vector3 coordinate, Matrix transform) - { - Vector3 result; - TransformCoordinate(ref coordinate, ref transform, out result); - return result; - } - - /// - /// Performs a coordinate transformation on an array of vectors using the given . - /// - /// The array of coordinate vectors to trasnform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - /// - /// A coordinate transform performs the transformation with the assumption that the w component - /// is one. The four dimensional vector obtained from the transformation operation has each - /// component in the vector divided by the w component. This forces the wcomponent to be one and - /// therefore makes the vector homogeneous. The homogeneous vector is often prefered when working - /// with coordinates as the w component can safely be ignored. - /// - public static void TransformCoordinate(Vector3[] source, ref Matrix transform, Vector3[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - TransformCoordinate(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Performs a normal transformation using the given . - /// - /// The normal vector to transform. - /// The transformation . - /// When the method completes, contains the transformed normal. - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static void TransformNormal(ref Vector3 normal, ref Matrix transform, out Vector3 result) - { - result = new Vector3( - (normal.X * transform.M11) + (normal.Y * transform.M21) + (normal.Z * transform.M31), - (normal.X * transform.M12) + (normal.Y * transform.M22) + (normal.Z * transform.M32), - (normal.X * transform.M13) + (normal.Y * transform.M23) + (normal.Z * transform.M33)); - } - - /// - /// Performs a normal transformation using the given . - /// - /// The normal vector to transform. - /// The transformation . - /// The transformed normal. - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static Vector3 TransformNormal(Vector3 normal, Matrix transform) - { - Vector3 result; - TransformNormal(ref normal, ref transform, out result); - return result; - } - - /// - /// Performs a normal transformation on an array of vectors using the given . - /// - /// The array of normal vectors to transform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - /// - /// A normal transform performs the transformation with the assumption that the w component - /// is zero. This causes the fourth row and fourth collumn of the matrix to be unused. The - /// end result is a vector that is not translated, but all other transformation properties - /// apply. This is often prefered for normal vectors as normals purely represent direction - /// rather than location because normal vectors should not be translated. - /// - public static void TransformNormal(Vector3[] source, ref Matrix transform, Vector3[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - TransformNormal(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector3 operator +(Vector3 left, Vector3 right) - { - return new Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z); - } - - /// - /// Assert a vector (return it unchanged). - /// - /// The vector to assert (unchange). - /// The asserted (unchanged) vector. - public static Vector3 operator +(Vector3 value) - { - return value; - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector3 operator -(Vector3 left, Vector3 right) - { - return new Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector3 operator -(Vector3 value) - { - return new Vector3(-value.X, -value.Y, -value.Z); - } - - /// - /// Divides the first vector by the second. - /// - /// The first source vector. - /// The second source vector. - /// The vector resulting from the division. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator /(Vector3 left, Vector3 right) - { - return new Vector3(left.X / right.X, left.Y / right.Y, left.Z / right.Z); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector3 operator *(float scalar, Vector3 value) - { - return new Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector3 operator *(Vector3 value, float scalar) - { - return new Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar); - } - - /// - /// Multiplies two vectors together. - /// - /// The first source vector. - /// The second source vector. - /// The product vector. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator *(Vector3 left, Vector3 right) - { - return new Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector3 operator /(Vector3 value, float scalar) - { - return new Vector3(value.X / scalar, value.Y / scalar, value.Z / scalar); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Vector3 left, Vector3 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Vector3 left, Vector3 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector2(Vector3 value) - { - return new Vector2(value.X, value.Y); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector4(Vector3 value) - { - return new Vector4(value, 0.0f); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2}", X, Y, Z); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2}", X.ToString(format, CultureInfo.CurrentCulture), - Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X, Y, Z); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - return ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X.ToString(format, formatProvider), - Y.ToString(format, formatProvider), Z.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector3 other) - { - return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// The amount of error allowed. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector3 other, float epsilon) - { - return ((float)Math.Abs(other.X - X) < epsilon && - (float)Math.Abs(other.Y - Y) < epsilon && - (float)Math.Abs(other.Z - Z) < epsilon); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Vector3)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Vector3(Vector3 value) - { - return new SlimDX.Vector3(value.X, value.Y, value.Z); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector3(SlimDX.Vector3 value) - { - return new Vector3(value.X, value.Y, value.Z); - } -#endif - -#if WPFInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator System.Windows.Media.Media3D.Vector3D(Vector3 value) - { - return new System.Windows.Media.Media3D.Vector3D(value.X, value.Y, value.Z); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(System.Windows.Media.Media3D.Vector3D value) - { - return new Vector3((float)value.X, (float)value.Y, (float)value.Z); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Vector3(Vector3 value) - { - return new Microsoft.Xna.Framework.Vector3(value.X, value.Y, value.Z); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector3(Microsoft.Xna.Framework.Vector3 value) - { - return new Vector3(value.X, value.Y, value.Z); - } -#endif -} diff --git a/source/OrkEngine3D.Mathematics/Vector4.cs b/source/OrkEngine3D.Mathematics/Vector4.cs deleted file mode 100644 index d4bd688..0000000 --- a/source/OrkEngine3D.Mathematics/Vector4.cs +++ /dev/null @@ -1,1618 +0,0 @@ -/* -* Copyright (c) 2007-2010 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace OrkEngine3D.Mathematics; - -/// -/// Represents a four dimensional mathematical vector. -/// -[Serializable] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -[TypeConverter(typeof(Design.Vector4Converter))] -public struct Vector4 : IEquatable, IFormattable -{ - /// - /// The size of the type, in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Vector4)); - - /// - /// A with all of its components set to zero. - /// - public static readonly Vector4 Zero = new Vector4(); - - /// - /// The X unit (1, 0, 0, 0). - /// - public static readonly Vector4 UnitX = new Vector4(1.0f, 0.0f, 0.0f, 0.0f); - - /// - /// The Y unit (0, 1, 0, 0). - /// - public static readonly Vector4 UnitY = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); - - /// - /// The Z unit (0, 0, 1, 0). - /// - public static readonly Vector4 UnitZ = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); - - /// - /// The W unit (0, 0, 0, 1). - /// - public static readonly Vector4 UnitW = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); - - /// - /// A with all of its components set to one. - /// - public static readonly Vector4 One = new Vector4(1.0f, 1.0f, 1.0f, 1.0f); - - /// - /// The X component of the vector. - /// - public float X; - - /// - /// The Y component of the vector. - /// - public float Y; - - /// - /// The Z component of the vector. - /// - public float Z; - - /// - /// The W component of the vector. - /// - public float W; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Vector4(float value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// Initial value for the X component of the vector. - /// Initial value for the Y component of the vector. - /// Initial value for the Z component of the vector. - /// Initial value for the W component of the vector. - public Vector4(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the X, Y, and Z components. - /// Initial value for the W component of the vector. - public Vector4(Vector3 value, float w) - { - X = value.X; - Y = value.Y; - Z = value.Z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the values with which to initialize the X and Y components. - /// Initial value for the Z component of the vector. - /// Initial value for the W component of the vector. - public Vector4(Vector2 value, float z, float w) - { - X = value.X; - Y = value.Y; - Z = z; - W = w; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the X, Y, Z, and W components of the vector. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Vector4(float[] values) - { - if (values == null) - throw new ArgumentNullException("values"); - if (values.Length != 4) - throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Vector4."); - - X = values[0]; - Y = values[1]; - Z = values[2]; - W = values[3]; - } - - /// - /// Gets a value indicting whether this instance is normalized. - /// - public bool IsNormalized - { - get { return Math.Abs((X * X) + (Y * Y) + (Z * Z) + (W * W) - 1f) < Utilities.ZeroTolerance; } - } - - /// - /// Calculates the length of the vector. - /// - /// - /// may be preferred when only the relative length is needed - /// and speed is of the essence. - /// - public float Length - { - get { return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W)); } - } - - /// - /// Calculates the squared length of the vector. - /// - /// - /// This property may be preferred to when only a relative length is needed - /// and speed is of the essence. - /// - public float LengthSquared - { - get { return (X * X) + (Y * Y) + (Z * Z) + (W * W); } - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the X, Y, Z, or W component, depending on the index. - /// The index of the component to access. Use 0 for the X component, 1 for the Y component, 2 for the Z component, and 3 for the W component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public float this[int index] - { - get - { - switch (index) - { - case 0: return X; - case 1: return Y; - case 2: return Z; - case 3: return W; - } - - throw new ArgumentOutOfRangeException("index", "Indices for Vector4 run from 0 to 3, inclusive."); - } - - set - { - switch (index) - { - case 0: X = value; break; - case 1: Y = value; break; - case 2: Z = value; break; - case 3: W = value; break; - default: throw new ArgumentOutOfRangeException("index", "Indices for Vector4 run from 0 to 3, inclusive."); - } - } - } - - /// - /// Converts the vector into a unit vector. - /// - public void Normalize() - { - float length = Length; - if (length > Utilities.ZeroTolerance) - { - float inverse = 1.0f / length; - X *= inverse; - Y *= inverse; - Z *= inverse; - W *= inverse; - } - } - - /// - /// Reverses the direction of a given vector. - /// - public void Negate() - { - X = -X; - Y = -Y; - Z = -Z; - W = -W; - } - - /// - /// Takes the absolute value of each component. - /// - public void Abs() - { - this.X = Math.Abs(X); - this.Y = Math.Abs(Y); - this.Z = Math.Abs(Z); - this.W = Math.Abs(W); - } - - /// - /// Creates an array containing the elements of the vector. - /// - /// A four-element array containing the components of the vector. - public float[] ToArray() - { - return new float[] { X, Y, Z, W }; - } - - #region Transcendentals - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// When the method completes, contains a vector that is the square root of the input vector. - public static void Sqrt(ref Vector4 value, out Vector4 result) - { - result.X = (float)Math.Sqrt(value.X); - result.Y = (float)Math.Sqrt(value.Y); - result.Z = (float)Math.Sqrt(value.Z); - result.W = (float)Math.Sqrt(value.W); - } - - /// - /// Takes the square root of each component in the vector. - /// - /// The vector to take the square root of. - /// A vector that is the square root of the input vector. - public static Vector4 Sqrt(Vector4 value) - { - Vector4 temp; - Sqrt(ref value, out temp); - return temp; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// When the method completes, contains a vector that is the reciprocal of the input vector. - public static void Reciprocal(ref Vector4 value, out Vector4 result) - { - result.X = 1.0f / value.X; - result.Y = 1.0f / value.Y; - result.Z = 1.0f / value.Z; - result.W = 1.0f / value.W; - } - - /// - /// Takes the reciprocal of each component in the vector. - /// - /// The vector to take the reciprocal of. - /// A vector that is the reciprocal of the input vector. - public static Vector4 Reciprocal(Vector4 value) - { - Vector4 temp; - Reciprocal(ref value, out temp); - return temp; - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// When the method completes, contains a vector that is the square root and reciprocal of the input vector. - public static void ReciprocalSqrt(ref Vector4 value, out Vector4 result) - { - result.X = 1.0f / (float)Math.Sqrt(value.X); - result.Y = 1.0f / (float)Math.Sqrt(value.Y); - result.Z = 1.0f / (float)Math.Sqrt(value.Z); - result.W = 1.0f / (float)Math.Sqrt(value.W); - } - - /// - /// Takes the square root of each component in the vector and than takes the reciprocal of each component in the vector. - /// - /// The vector to take the square root and recpirocal of. - /// A vector that is the square root and reciprocal of the input vector. - public static Vector4 ReciprocalSqrt(Vector4 value) - { - Vector4 temp; - ReciprocalSqrt(ref value, out temp); - return temp; - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// When the method completes, contains a vector that has e raised to each of the components in the input vector. - public static void Exp(ref Vector4 value, out Vector4 result) - { - result.X = (float)Math.Exp(value.X); - result.Y = (float)Math.Exp(value.Y); - result.Z = (float)Math.Exp(value.Z); - result.W = (float)Math.Exp(value.W); - } - - /// - /// Takes e raised to the component in the vector. - /// - /// The value to take e raised to each component of. - /// A vector that has e raised to each of the components in the input vector. - public static Vector4 Exp(Vector4 value) - { - Vector4 temp; - Exp(ref value, out temp); - return temp; - } - - /// - /// Takes the sine and than the cosine of each component in the vector. - /// - /// The vector to take the sine and cosine of. - /// When the method completes, contains the sine of each component in the input vector. - /// When the method completes, contains the cpsome pf each component in the input vector. - public static void SinCos(ref Vector4 value, out Vector4 sinResult, out Vector4 cosResult) - { - sinResult.X = (float)Math.Sin(value.X); - sinResult.Y = (float)Math.Sin(value.Y); - sinResult.Z = (float)Math.Sin(value.Z); - sinResult.W = (float)Math.Sin(value.W); - - cosResult.X = (float)Math.Cos(value.X); - cosResult.Y = (float)Math.Cos(value.Y); - cosResult.Z = (float)Math.Cos(value.Z); - cosResult.W = (float)Math.Cos(value.W); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// When the method completes, a vector that contains the sine of each component in the input vector. - public static void Sin(ref Vector4 value, out Vector4 result) - { - result.X = (float)Math.Sin(value.X); - result.Y = (float)Math.Sin(value.Y); - result.Z = (float)Math.Sin(value.Z); - result.W = (float)Math.Sin(value.W); - } - - /// - /// Takes the sine of each component in the vector. - /// - /// The vector to take the sine of. - /// A vector that contains the sine of each component in the input vector. - public static Vector4 Sin(Vector4 value) - { - Vector4 temp; - Sin(ref value, out temp); - return temp; - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// When the method completes, contains a vector that contains the cosine of each component in the input vector. - public static void Cos(ref Vector4 value, out Vector4 result) - { - result.X = (float)Math.Cos(value.X); - result.Y = (float)Math.Cos(value.Y); - result.Z = (float)Math.Cos(value.Z); - result.W = (float)Math.Cos(value.W); - } - - /// - /// Takes the cosine of each component in the vector. - /// - /// The vector to take the cosine of. - /// A vector that contains the cosine of each component in the input vector. - public static Vector4 Cos(Vector4 value) - { - Vector4 temp; - Cos(ref value, out temp); - return temp; - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// When the method completes, contains a vector that contains the tangent of each component in the input vector. - public static void Tan(ref Vector4 value, out Vector4 result) - { - result.X = (float)Math.Tan(value.X); - result.Y = (float)Math.Tan(value.Y); - result.Z = (float)Math.Tan(value.Z); - result.W = (float)Math.Tan(value.W); - } - - /// - /// Takes the tangent of each component in the vector. - /// - /// The vector to take the tangent of. - /// A vector that contains the tangent of each component in the input vector. - public static Vector4 Tan(Vector4 value) - { - Vector4 temp; - Tan(ref value, out temp); - return temp; - } - #endregion - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// When the method completes, contains the sum of the two vectors. - public static void Add(ref Vector4 left, ref Vector4 right, out Vector4 result) - { - result = new Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W); - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector4 Add(Vector4 left, Vector4 right) - { - return new Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// When the method completes, contains the difference of the two vectors. - public static void Subtract(ref Vector4 left, ref Vector4 right, out Vector4 result) - { - result = new Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W); - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector4 Subtract(Vector4 left, Vector4 right) - { - return new Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Multiply(ref Vector4 value, float scalar, out Vector4 result) - { - result = new Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector4 Multiply(Vector4 value, float scalar) - { - return new Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// When the method completes, contains the modulated vector. - public static void Modulate(ref Vector4 left, ref Vector4 right, out Vector4 result) - { - result = new Vector4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W); - } - - /// - /// Modulates a vector with another by performing component-wise multiplication. - /// - /// The first vector to modulate. - /// The second vector to modulate. - /// The modulated vector. - public static Vector4 Modulate(Vector4 left, Vector4 right) - { - return new Vector4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// When the method completes, contains the scaled vector. - public static void Divide(ref Vector4 value, float scalar, out Vector4 result) - { - result = new Vector4(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector4 Divide(Vector4 value, float scalar) - { - return new Vector4(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// When the method completes, contains a vector facing in the opposite direction. - public static void Negate(ref Vector4 value, out Vector4 result) - { - result = new Vector4(-value.X, -value.Y, -value.Z, -value.W); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector4 Negate(Vector4 value) - { - return new Vector4(-value.X, -value.Y, -value.Z, -value.W); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// When the method completes, contains a vector that has all positive components. - public static void Abs(ref Vector4 value, out Vector4 result) - { - result = new Vector4(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W)); - } - - /// - /// Takes the absolute value of each component. - /// - /// The vector to take the absolute value of. - /// A vector that has all positive components. - public static Vector4 Abs(Vector4 value) - { - return new Vector4(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W)); - } - - /// - /// Returns a containing the 4D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 4D triangle. - /// - /// A containing the 4D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// When the method completes, contains the 4D Cartesian coordinates of the specified point. - public static void Barycentric(ref Vector4 value1, ref Vector4 value2, ref Vector4 value3, float amount1, float amount2, out Vector4 result) - { - result = new Vector4( - (value1.X + (amount1 * (value2.X - value1.X))) + (amount2 * (value3.X - value1.X)), - (value1.Y + (amount1 * (value2.Y - value1.Y))) + (amount2 * (value3.Y - value1.Y)), - (value1.Z + (amount1 * (value2.Z - value1.Z))) + (amount2 * (value3.Z - value1.Z)), - (value1.W + (amount1 * (value2.W - value1.W))) + (amount2 * (value3.W - value1.W))); - } - - /// - /// Returns a containing the 4D Cartesian coordinates of a point specified in Barycentric coordinates relative to a 4D triangle. - /// - /// A containing the 4D Cartesian coordinates of vertex 1 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 2 of the triangle. - /// A containing the 4D Cartesian coordinates of vertex 3 of the triangle. - /// Barycentric coordinate b2, which expresses the weighting factor toward vertex 2 (specified in ). - /// Barycentric coordinate b3, which expresses the weighting factor toward vertex 3 (specified in ). - /// A new containing the 4D Cartesian coordinates of the specified point. - public static Vector4 Barycentric(Vector4 value1, Vector4 value2, Vector4 value3, float amount1, float amount2) - { - Vector4 result; - Barycentric(ref value1, ref value2, ref value3, amount1, amount2, out result); - return result; - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref Vector4 value, ref Vector4 min, ref Vector4 max, out Vector4 result) - { - float x = value.X; - x = (x > max.X) ? max.X : x; - x = (x < min.X) ? min.X : x; - - float y = value.Y; - y = (y > max.Y) ? max.Y : y; - y = (y < min.Y) ? min.Y : y; - - float z = value.Z; - z = (z > max.Z) ? max.Z : z; - z = (z < min.Z) ? min.Z : z; - - float w = value.W; - w = (w > max.W) ? max.W : w; - w = (w < min.W) ? min.W : w; - - result = new Vector4(x, y, z, w); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Vector4 Clamp(Vector4 value, Vector4 min, Vector4 max) - { - Vector4 result; - Clamp(ref value, ref min, ref max, out result); - return result; - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// When the method completes, contains the distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static void Distance(ref Vector4 value1, ref Vector4 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - float w = value1.W - value2.W; - - result = (float)Math.Sqrt((x * x) + (y * y) + (z * z) + (w * w)); - } - - /// - /// Calculates the distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The distance between the two vectors. - /// - /// may be preferred when only the relative distance is needed - /// and speed is of the essence. - /// - public static float Distance(Vector4 value1, Vector4 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - float w = value1.W - value2.W; - - return (float)Math.Sqrt((x * x) + (y * y) + (z * z) + (w * w)); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// When the method completes, contains the squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static void DistanceSquared(ref Vector4 value1, ref Vector4 value2, out float result) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - float w = value1.W - value2.W; - - result = (x * x) + (y * y) + (z * z) + (w * w); - } - - /// - /// Calculates the squared distance between two vectors. - /// - /// The first vector. - /// The second vector. - /// The squared distance between the two vectors. - /// Distance squared is the value before taking the square root. - /// Distance squared can often be used in place of distance if relative comparisons are being made. - /// For example, consider three points A, B, and C. To determine whether B or C is further from A, - /// compare the distance between A and B to the distance between A and C. Calculating the two distances - /// involves two square roots, which are computationally expensive. However, using distance squared - /// provides the same information and avoids calculating two square roots. - /// - public static float DistanceSquared(Vector4 value1, Vector4 value2) - { - float x = value1.X - value2.X; - float y = value1.Y - value2.Y; - float z = value1.Z - value2.Z; - float w = value1.W - value2.W; - - return (x * x) + (y * y) + (z * z) + (w * w); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector - /// Second source vector. - /// When the method completes, contains the dot product of the two vectors. - 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); - } - - /// - /// Calculates the dot product of two vectors. - /// - /// First source vector. - /// Second source vector. - /// The dot product of the two vectors. - 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); - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// When the method completes, contains the normalized vector. - public static void Normalize(ref Vector4 value, out Vector4 result) - { - Vector4 temp = value; - result = temp; - result.Normalize(); - } - - /// - /// Converts the vector into a unit vector. - /// - /// The vector to normalize. - /// The normalized vector. - public static Vector4 Normalize(Vector4 value) - { - value.Normalize(); - return value; - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static void Lerp(ref Vector4 start, ref Vector4 end, float amount, out Vector4 result) - { - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - result.Z = start.Z + ((end.Z - start.Z) * amount); - result.W = start.W + ((end.W - start.W) * amount); - } - - /// - /// Performs a linear interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The linear interpolation of the two vectors. - /// - /// This method performs the linear interpolation based on the following formula. - /// start + (end - start) * amount - /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. - /// - public static Vector4 Lerp(Vector4 start, Vector4 end, float amount) - { - Vector4 result; - Lerp(ref start, ref end, amount, out result); - return result; - } - - /// - /// Move a point from current to target - /// - /// current point - /// target point - /// distance between - /// distance - public static Vector4 MoveTowards(Vector4 current, Vector4 target, float maxDistanceDelta) - { - float toV_x = target.X - current.X; - float toV_y = target.Y - current.Y; - float toV_z = target.Z - current.Z; - float toV_w = target.W - current.W; - - float sqDistance = toV_x * toV_x + - toV_y * toV_y + - toV_z * toV_z + - toV_w * toV_w; - - if (sqDistance == 0 || (maxDistanceDelta >= 0 && sqDistance <= maxDistanceDelta * maxDistanceDelta)) - return target; - - var distance = (float)Math.Sqrt(sqDistance); - - return new Vector4(current.X + toV_x / distance * maxDistanceDelta, - current.Y + toV_y / distance * maxDistanceDelta, - current.Z + toV_z / distance * maxDistanceDelta, - current.W + toV_w / distance * maxDistanceDelta); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// When the method completes, contains the cubic interpolation of the two vectors. - public static void SmoothStep(ref Vector4 start, ref Vector4 end, float amount, out Vector4 result) - { - amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount); - amount = (amount * amount) * (3.0f - (2.0f * amount)); - - result.X = start.X + ((end.X - start.X) * amount); - result.Y = start.Y + ((end.Y - start.Y) * amount); - result.Z = start.Z + ((end.Z - start.Z) * amount); - result.W = start.W + ((end.W - start.W) * amount); - } - - /// - /// Performs a cubic interpolation between two vectors. - /// - /// Start vector. - /// End vector. - /// Value between 0 and 1 indicating the weight of . - /// The cubic interpolation of the two vectors. - public static Vector4 SmoothStep(Vector4 start, Vector4 end, float amount) - { - Vector4 result; - SmoothStep(ref start, ref end, amount, out result); - return result; - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// When the method completes, contains the result of the Hermite spline interpolation. - public static void Hermite(ref Vector4 value1, ref Vector4 tangent1, ref Vector4 value2, ref Vector4 tangent2, float amount, out Vector4 result) - { - float squared = amount * amount; - float cubed = amount * squared; - float part1 = ((2.0f * cubed) - (3.0f * squared)) + 1.0f; - float part2 = (-2.0f * cubed) + (3.0f * squared); - float part3 = (cubed - (2.0f * squared)) + amount; - float part4 = cubed - squared; - - result = new Vector4( - (((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4), - (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4), - (((value1.Z * part1) + (value2.Z * part2)) + (tangent1.Z * part3)) + (tangent2.Z * part4), - (((value1.W * part1) + (value2.W * part2)) + (tangent1.W * part3)) + (tangent2.W * part4)); - } - - /// - /// Performs a Hermite spline interpolation. - /// - /// First source position vector. - /// First source tangent vector. - /// Second source position vector. - /// Second source tangent vector. - /// Weighting factor. - /// The result of the Hermite spline interpolation. - public static Vector4 Hermite(Vector4 value1, Vector4 tangent1, Vector4 value2, Vector4 tangent2, float amount) - { - Vector4 result; - Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result); - return result; - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// When the method completes, contains the result of the Catmull-Rom interpolation. - public static void CatmullRom(ref Vector4 value1, ref Vector4 value2, ref Vector4 value3, ref Vector4 value4, float amount, out Vector4 result) - { - float squared = amount * amount; - float cubed = amount * squared; - - result.X = 0.5f * ((((2.0f * value2.X) + ((-value1.X + value3.X) * amount)) + - (((((2.0f * value1.X) - (5.0f * value2.X)) + (4.0f * value3.X)) - value4.X) * squared)) + - ((((-value1.X + (3.0f * value2.X)) - (3.0f * value3.X)) + value4.X) * cubed)); - - result.Y = 0.5f * ((((2.0f * value2.Y) + ((-value1.Y + value3.Y) * amount)) + - (((((2.0f * value1.Y) - (5.0f * value2.Y)) + (4.0f * value3.Y)) - value4.Y) * squared)) + - ((((-value1.Y + (3.0f * value2.Y)) - (3.0f * value3.Y)) + value4.Y) * cubed)); - - result.Z = 0.5f * ((((2.0f * value2.Z) + ((-value1.Z + value3.Z) * amount)) + - (((((2.0f * value1.Z) - (5.0f * value2.Z)) + (4.0f * value3.Z)) - value4.Z) * squared)) + - ((((-value1.Z + (3.0f * value2.Z)) - (3.0f * value3.Z)) + value4.Z) * cubed)); - - result.W = 0.5f * ((((2.0f * value2.W) + ((-value1.W + value3.W) * amount)) + - (((((2.0f * value1.W) - (5.0f * value2.W)) + (4.0f * value3.W)) - value4.W) * squared)) + - ((((-value1.W + (3.0f * value2.W)) - (3.0f * value3.W)) + value4.W) * cubed)); - } - - /// - /// Performs a Catmull-Rom interpolation using the specified positions. - /// - /// The first position in the interpolation. - /// The second position in the interpolation. - /// The third position in the interpolation. - /// The fourth position in the interpolation. - /// Weighting factor. - /// A vector that is the result of the Catmull-Rom interpolation. - public static Vector4 CatmullRom(Vector4 value1, Vector4 value2, Vector4 value3, Vector4 value4, float amount) - { - Vector4 result; - CatmullRom(ref value1, ref value2, ref value3, ref value4, amount, out result); - return result; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the largest components of the source vectors. - public static void Max(ref Vector4 value1, ref Vector4 value2, out Vector4 result) - { - result.X = (value1.X > value2.X) ? value1.X : value2.X; - result.Y = (value1.Y > value2.Y) ? value1.Y : value2.Y; - result.Z = (value1.Z > value2.Z) ? value1.Z : value2.Z; - result.W = (value1.W > value2.W) ? value1.W : value2.W; - } - - /// - /// Returns a vector containing the largest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the largest components of the source vectors. - public static Vector4 Max(Vector4 value1, Vector4 value2) - { - Vector4 result; - Max(ref value1, ref value2, out result); - return result; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// When the method completes, contains an new vector composed of the smallest components of the source vectors. - public static void Min(ref Vector4 value1, ref Vector4 value2, out Vector4 result) - { - result.X = (value1.X < value2.X) ? value1.X : value2.X; - result.Y = (value1.Y < value2.Y) ? value1.Y : value2.Y; - result.Z = (value1.Z < value2.Z) ? value1.Z : value2.Z; - result.W = (value1.W < value2.W) ? value1.W : value2.W; - } - - /// - /// Returns a vector containing the smallest components of the specified vectors. - /// - /// The first source vector. - /// The second source vector. - /// A vector containing the smallest components of the source vectors. - public static Vector4 Min(Vector4 value1, Vector4 value2) - { - Vector4 result; - Min(ref value1, ref value2, out result); - return result; - } - - /// - /// Orthogonalizes a list of vectors. - /// - /// The list of orthogonalized vectors. - /// The list of vectors to orthogonalize. - /// - /// Orthogonalization is the process of making all vectors orthogonal to each other. This - /// means that any given vector in the list will be orthogonal to any other given vector in the - /// list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthogonalize(Vector4[] destination, params Vector4[] source) - { - //Uses the modified Gram-Schmidt process. - //q1 = m1 - //q2 = m2 - ((q1 ⋅ m2) / (q1 ⋅ q1)) * q1 - //q3 = m3 - ((q1 ⋅ m3) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m3) / (q2 ⋅ q2)) * q2 - //q4 = m4 - ((q1 ⋅ m4) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m4) / (q2 ⋅ q2)) * q2 - ((q3 ⋅ m4) / (q3 ⋅ q3)) * q3 - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector4 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= (Vector4.Dot(destination[r], newvector) / Vector4.Dot(destination[r], destination[r])) * destination[r]; - } - - destination[i] = newvector; - } - } - - /// - /// Orthonormalizes a list of vectors. - /// - /// The list of orthonormalized vectors. - /// The list of vectors to orthonormalize. - /// - /// Orthonormalization is the process of making all vectors orthogonal to each - /// other and making all vectors of unit length. This means that any given vector will - /// be orthogonal to any other given vector in the list. - /// Because this method uses the modified Gram-Schmidt process, the resulting vectors - /// tend to be numerically unstable. The numeric stability decreases according to the vectors - /// position in the list so that the first vector is the most stable and the last vector is the - /// least stable. - /// - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Orthonormalize(Vector4[] destination, params Vector4[] source) - { - //Uses the modified Gram-Schmidt process. - //Because we are making unit vectors, we can optimize the math for orthogonalization - //and simplify the projection operation to remove the division. - //q1 = m1 / |m1| - //q2 = (m2 - (q1 ⋅ m2) * q1) / |m2 - (q1 ⋅ m2) * q1| - //q3 = (m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2) / |m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2| - //q4 = (m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3) / |m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3| - //q5 = ... - - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Vector4 newvector = source[i]; - - for (int r = 0; r < i; ++r) - { - newvector -= Vector4.Dot(destination[r], newvector) * destination[r]; - } - - newvector.Normalize(); - destination[i] = newvector; - } - } - - /// - /// Transforms a 4D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// When the method completes, contains the transformed . - public static void Transform(ref Vector4 vector, ref Quaternion rotation, out Vector4 result) - { - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wx = rotation.W * x; - float wy = rotation.W * y; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float xz = rotation.X * z; - float yy = rotation.Y * y; - float yz = rotation.Y * z; - float zz = rotation.Z * z; - - float num1 = ((1.0f - yy) - zz); - float num2 = (xy - wz); - float num3 = (xz + wy); - float num4 = (xy + wz); - float num5 = ((1.0f - xx) - zz); - float num6 = (yz - wx); - float num7 = (xz - wy); - float num8 = (yz + wx); - float num9 = ((1.0f - xx) - yy); - - result = new Vector4( - ((vector.X * num1) + (vector.Y * num2)) + (vector.Z * num3), - ((vector.X * num4) + (vector.Y * num5)) + (vector.Z * num6), - ((vector.X * num7) + (vector.Y * num8)) + (vector.Z * num9), - vector.W); - } - - /// - /// Transforms a 4D vector by the given rotation. - /// - /// The vector to rotate. - /// The rotation to apply. - /// The transformed . - public static Vector4 Transform(Vector4 vector, Quaternion rotation) - { - Vector4 result; - Transform(ref vector, ref rotation, out result); - return result; - } - - /// - /// Transforms an array of vectors by the given rotation. - /// - /// The array of vectors to transform. - /// The rotation to apply. - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector4[] source, ref Quaternion rotation, Vector4[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - float x = rotation.X + rotation.X; - float y = rotation.Y + rotation.Y; - float z = rotation.Z + rotation.Z; - float wx = rotation.W * x; - float wy = rotation.W * y; - float wz = rotation.W * z; - float xx = rotation.X * x; - float xy = rotation.X * y; - float xz = rotation.X * z; - float yy = rotation.Y * y; - float yz = rotation.Y * z; - float zz = rotation.Z * z; - - float num1 = ((1.0f - yy) - zz); - float num2 = (xy - wz); - float num3 = (xz + wy); - float num4 = (xy + wz); - float num5 = ((1.0f - xx) - zz); - float num6 = (yz - wx); - float num7 = (xz - wy); - float num8 = (yz + wx); - float num9 = ((1.0f - xx) - yy); - - for (int i = 0; i < source.Length; ++i) - { - destination[i] = new Vector4( - ((source[i].X * num1) + (source[i].Y * num2)) + (source[i].Z * num3), - ((source[i].X * num4) + (source[i].Y * num5)) + (source[i].Z * num6), - ((source[i].X * num7) + (source[i].Y * num8)) + (source[i].Z * num9), - source[i].W); - } - } - - /// - /// Transforms a 4D vector by the given . - /// - /// The source vector. - /// The transformation . - /// When the method completes, contains the transformed . - public static void Transform(ref Vector4 vector, ref Matrix transform, out Vector4 result) - { - result = new Vector4( - (vector.X * transform.M11) + (vector.Y * transform.M21) + (vector.Z * transform.M31) + (vector.W * transform.M41), - (vector.X * transform.M12) + (vector.Y * transform.M22) + (vector.Z * transform.M32) + (vector.W * transform.M42), - (vector.X * transform.M13) + (vector.Y * transform.M23) + (vector.Z * transform.M33) + (vector.W * transform.M43), - (vector.X * transform.M14) + (vector.Y * transform.M24) + (vector.Z * transform.M34) + (vector.W * transform.M44)); - } - - /// - /// Transforms a 4D vector by the given . - /// - /// The source vector. - /// The transformation . - /// The transformed . - public static Vector4 Transform(Vector4 vector, Matrix transform) - { - Vector4 result; - Transform(ref vector, ref transform, out result); - return result; - } - - /// - /// Transforms an array of 4D vectors by the given . - /// - /// The array of vectors to transform. - /// The transformation . - /// The array for which the transformed vectors are stored. - /// This array may be the same array as . - /// Thrown when or is null. - /// Thrown when is shorter in length than . - public static void Transform(Vector4[] source, ref Matrix transform, Vector4[] destination) - { - if (source == null) - throw new ArgumentNullException("source"); - if (destination == null) - throw new ArgumentNullException("destination"); - if (destination.Length < source.Length) - throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); - - for (int i = 0; i < source.Length; ++i) - { - Transform(ref source[i], ref transform, out destination[i]); - } - } - - /// - /// Adds two vectors. - /// - /// The first vector to add. - /// The second vector to add. - /// The sum of the two vectors. - public static Vector4 operator +(Vector4 left, Vector4 right) - { - return new Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W); - } - - /// - /// Assert a vector (return it unchanged). - /// - /// The vector to assert (unchange). - /// The asserted (unchanged) vector. - public static Vector4 operator +(Vector4 value) - { - return value; - } - - /// - /// Subtracts two vectors. - /// - /// The first vector to subtract. - /// The second vector to subtract. - /// The difference of the two vectors. - public static Vector4 operator -(Vector4 left, Vector4 right) - { - return new Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W); - } - - /// - /// Reverses the direction of a given vector. - /// - /// The vector to negate. - /// A vector facing in the opposite direction. - public static Vector4 operator -(Vector4 value) - { - return new Vector4(-value.X, -value.Y, -value.Z, -value.W); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector4 operator *(float scalar, Vector4 value) - { - return new Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector4 operator *(Vector4 value, float scalar) - { - return new Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar); - } - - /// - /// Scales a vector by the given value. - /// - /// The vector to scale. - /// The amount by which to scale the vector. - /// The scaled vector. - public static Vector4 operator /(Vector4 value, float scalar) - { - return new Vector4(value.X / scalar, value.Y / scalar, value.Z / scalar, value.W / scalar); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Vector4 left, Vector4 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Vector4 left, Vector4 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector2(Vector4 value) - { - return new Vector2(value.X, value.Y); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector3(Vector4 value) - { - return new Vector3(value.X, value.Y, value.Z); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - if (format == null) - return ToString(); - - return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, CultureInfo.CurrentCulture), - Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture), W.ToString(format, CultureInfo.CurrentCulture)); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - ToString(formatProvider); - - return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, formatProvider), - Y.ToString(format, formatProvider), Z.ToString(format, formatProvider), W.ToString(format, formatProvider)); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector4 other) - { - return (this.X == other.X) && (this.Y == other.Y) && (this.Z == other.Z) && (this.W == other.W); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// The amount of error allowed. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(Vector4 other, float epsilon) - { - return ((float)Math.Abs(other.X - X) < epsilon && - (float)Math.Abs(other.Y - Y) < epsilon && - (float)Math.Abs(other.Z - Z) < epsilon && - (float)Math.Abs(other.W - W) < epsilon); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - if (obj.GetType() != GetType()) - return false; - - return Equals((Vector4)obj); - } - -#if SlimDX1xInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator SlimDX.Vector4(Vector4 value) - { - return new SlimDX.Vector4(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector4(SlimDX.Vector4 value) - { - return new Vector4(value.X, value.Y, value.Z, value.W); - } -#endif - -#if WPFInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator System.Windows.Media.Media3D.Point4D(Vector4 value) - { - return new System.Windows.Media.Media3D.Point4D(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Vector4(System.Windows.Media.Media3D.Point4D value) - { - return new Vector4((float)value.X, (float)value.Y, (float)value.Z, (float)value.W); - } -#endif - -#if XnaInterop - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Microsoft.Xna.Framework.Vector4(Vector4 value) - { - return new Microsoft.Xna.Framework.Vector4(value.X, value.Y, value.Z, value.W); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator Vector4(Microsoft.Xna.Framework.Vector4 value) - { - return new Vector4(value.X, value.Y, value.Z, value.W); - } -#endif -} diff --git a/source/OrkEngine3D.Networking.Tests/OrkEngine3D.Networking.Tests.csproj b/source/OrkEngine3D.Networking.Tests/OrkEngine3D.Networking.Tests.csproj index 1e743b3..ff9327f 100644 --- a/source/OrkEngine3D.Networking.Tests/OrkEngine3D.Networking.Tests.csproj +++ b/source/OrkEngine3D.Networking.Tests/OrkEngine3D.Networking.Tests.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable diff --git a/source/OrkEngine3D.Networking/OrkEngine3D.Networking.csproj b/source/OrkEngine3D.Networking/OrkEngine3D.Networking.csproj index df548b7..a1714b9 100644 --- a/source/OrkEngine3D.Networking/OrkEngine3D.Networking.csproj +++ b/source/OrkEngine3D.Networking/OrkEngine3D.Networking.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 diff --git a/source/OrkEngine3D.Physics/OrkEngine3D.Physics.csproj b/source/OrkEngine3D.Physics/OrkEngine3D.Physics.csproj index 8aba1df..97a3ab2 100644 --- a/source/OrkEngine3D.Physics/OrkEngine3D.Physics.csproj +++ b/source/OrkEngine3D.Physics/OrkEngine3D.Physics.csproj @@ -2,7 +2,7 @@ Library - net6.0 + net7.0 diff --git a/source/OrkEngine3D.Resources.Tests/OrkEngine3D.Resources.Tests.csproj b/source/OrkEngine3D.Resources.Tests/OrkEngine3D.Resources.Tests.csproj index 635c99b..830817f 100644 --- a/source/OrkEngine3D.Resources.Tests/OrkEngine3D.Resources.Tests.csproj +++ b/source/OrkEngine3D.Resources.Tests/OrkEngine3D.Resources.Tests.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable diff --git a/source/OrkEngine3D.Resources/OrkEngine3D.Resources.csproj b/source/OrkEngine3D.Resources/OrkEngine3D.Resources.csproj index eb2460e..6836c68 100644 --- a/source/OrkEngine3D.Resources/OrkEngine3D.Resources.csproj +++ b/source/OrkEngine3D.Resources/OrkEngine3D.Resources.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/source/OrkEngine3D.sln b/source/OrkEngine3D.sln index d1ee75f..f8ae403 100644 --- a/source/OrkEngine3D.sln +++ b/source/OrkEngine3D.sln @@ -14,8 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Physics", "OrkE EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "10 - OrkCore", "10 - OrkCore", "{A8C5865D-7059-490F-9257-5517658D73A5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Mathematics", "OrkEngine3D.Mathematics\OrkEngine3D.Mathematics.csproj", "{6E28699B-F093-4CB7-A54B-FDCC0FB1E065}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Core", "OrkEngine3D.Core\OrkEngine3D.Core.csproj", "{5908C24E-BC54-4FE3-8698-312E3D38E956}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "20 - OrkUtil", "20 - OrkUtil", "{C5E5E9BB-F254-4260-9F14-CD0A9B206CDD}" @@ -40,8 +38,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Resources", "Or EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Resources.Tests", "OrkEngine3D.Resources.Tests\OrkEngine3D.Resources.Tests.csproj", "{8FA43F24-BA6B-41DE-94B5-5DE61BD1F08D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.Common.Utils", "OrkEngine3D.Common.Utils\OrkEngine3D.Common.Utils.csproj", "{05BAB291-435E-4E4E-A855-191484E2235F}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "50 - Vendor", "50 - Vendor", "{F6D938D0-E901-4CB4-9F85-6833BB2A1D2C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrkEngine3D.BEPU", "vendor\OrkEngine3D.BEPU\source\OrkEngine3D.BEPU\OrkEngine3D.BEPU.csproj", "{52A2EA64-CE6A-4C85-8B27-AB47A479CCA9}" @@ -69,12 +65,6 @@ Global {CA34AB58-BAED-4B40-BF2E-A62BA3009DAF}.Release|Any CPU.Build.0 = Release|Any CPU {CA34AB58-BAED-4B40-BF2E-A62BA3009DAF}.ReleaseNoProfiling|Any CPU.ActiveCfg = Release|Any CPU {CA34AB58-BAED-4B40-BF2E-A62BA3009DAF}.ReleaseNoProfiling|Any CPU.Build.0 = Release|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.Release|Any CPU.Build.0 = Release|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.ReleaseNoProfiling|Any CPU.ActiveCfg = Release|Any CPU - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065}.ReleaseNoProfiling|Any CPU.Build.0 = Release|Any CPU {5908C24E-BC54-4FE3-8698-312E3D38E956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5908C24E-BC54-4FE3-8698-312E3D38E956}.Debug|Any CPU.Build.0 = Debug|Any CPU {5908C24E-BC54-4FE3-8698-312E3D38E956}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -129,12 +119,6 @@ Global {8FA43F24-BA6B-41DE-94B5-5DE61BD1F08D}.Release|Any CPU.Build.0 = Release|Any CPU {8FA43F24-BA6B-41DE-94B5-5DE61BD1F08D}.ReleaseNoProfiling|Any CPU.ActiveCfg = Debug|Any CPU {8FA43F24-BA6B-41DE-94B5-5DE61BD1F08D}.ReleaseNoProfiling|Any CPU.Build.0 = Debug|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.Release|Any CPU.Build.0 = Release|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.ReleaseNoProfiling|Any CPU.ActiveCfg = Release|Any CPU - {05BAB291-435E-4E4E-A855-191484E2235F}.ReleaseNoProfiling|Any CPU.Build.0 = Release|Any CPU {52A2EA64-CE6A-4C85-8B27-AB47A479CCA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {52A2EA64-CE6A-4C85-8B27-AB47A479CCA9}.Debug|Any CPU.Build.0 = Debug|Any CPU {52A2EA64-CE6A-4C85-8B27-AB47A479CCA9}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -160,7 +144,6 @@ Global GlobalSection(NestedProjects) = preSolution {08FAEA51-0D67-4DE6-8645-FD81F5076CE5} = {38B4460E-DD35-4845-95EB-93D07D9D2CC1} {CA34AB58-BAED-4B40-BF2E-A62BA3009DAF} = {38B4460E-DD35-4845-95EB-93D07D9D2CC1} - {6E28699B-F093-4CB7-A54B-FDCC0FB1E065} = {A8C5865D-7059-490F-9257-5517658D73A5} {5908C24E-BC54-4FE3-8698-312E3D38E956} = {A8C5865D-7059-490F-9257-5517658D73A5} {55DC71FE-322F-4B59-8F8E-F5C14ED2B6F4} = {C5E5E9BB-F254-4260-9F14-CD0A9B206CDD} {6580BC72-35F6-4F83-8027-88C870889503} = {C5E5E9BB-F254-4260-9F14-CD0A9B206CDD} @@ -171,7 +154,6 @@ Global {154AC43D-C222-4434-8621-A02EB9644183} = {C5E5E9BB-F254-4260-9F14-CD0A9B206CDD} {FCEF3A2C-78A2-45FD-9E58-1298309176D6} = {154AC43D-C222-4434-8621-A02EB9644183} {8FA43F24-BA6B-41DE-94B5-5DE61BD1F08D} = {A2D7C7B8-4887-41F1-BE4C-AD11AB520927} - {05BAB291-435E-4E4E-A855-191484E2235F} = {C5E5E9BB-F254-4260-9F14-CD0A9B206CDD} {52A2EA64-CE6A-4C85-8B27-AB47A479CCA9} = {F6D938D0-E901-4CB4-9F85-6833BB2A1D2C} {713E256A-5577-4838-B095-113FFF76C410} = {F6D938D0-E901-4CB4-9F85-6833BB2A1D2C} {9987727C-526F-4753-892C-0E4FB611F6BF} = {F6D938D0-E901-4CB4-9F85-6833BB2A1D2C} diff --git a/source/vendor/OrkEngine3D.Mathematics b/source/vendor/OrkEngine3D.Mathematics index 59a5536..e66f0b7 160000 --- a/source/vendor/OrkEngine3D.Mathematics +++ b/source/vendor/OrkEngine3D.Mathematics @@ -1 +1 @@ -Subproject commit 59a5536486e4427ac7c8fbb3815869c2cb26e063 +Subproject commit e66f0b766d11e8f74ebf752bdfa43aa389212cf3