From cdd3afaa4cc6c282f0ca7f736b7b5be315dfb29c Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 23 Jul 2025 01:15:27 +0200 Subject: [PATCH] Remove redundant custom math types (#6078) Vector3, Vector4, Matrix4, and Quaternion are now gone. Use System.Numerics instead. This commit is just replacing usages, cleaning up using declarations, and moving over the (couple) helpers that are actually important. --- .../Animations/AnimationTrackProperty.cs | 6 +- Robust.Client/Audio/Effects/AudioEffect.cs | 1 + Robust.Client/Console/Completions.cs | 2 +- .../Components/Renderable/SpriteComponent.cs | 2 - .../EntitySystems/SpriteSystem.Render.cs | 4 +- .../Graphics/Clyde/Clyde.GridRendering.cs | 1 + Robust.Client/Graphics/Clyde/Clyde.Layout.cs | 1 - .../Graphics/Clyde/Clyde.LightRendering.cs | 1 - .../Graphics/Clyde/Clyde.Rendering.cs | 4 +- Robust.Client/Graphics/Clyde/Clyde.Shaders.cs | 4 +- Robust.Client/Graphics/Clyde/ClydeHeadless.cs | 4 +- .../Clyde/GLObjects/Clyde.ShaderProgram.cs | 12 +- .../Graphics/Shaders/ShaderInstance.cs | 6 +- .../Graphics/Shaders/ShaderPrototype.cs | 4 +- Robust.Client/Placement/Modes/AlignWall.cs | 2 +- .../Placement/Modes/AlignWallProper.cs | 2 +- .../Controls/ColorSelectorSliders.cs | 1 + .../Controls/ColorSelectorStyleBox.cs | 10 +- .../UserInterface/Controls/TextEdit.cs | 1 - Robust.Shared.Maths/Color.cs | 27 +- Robust.Shared.Maths/MathHelper.cs | 13 +- Robust.Shared.Maths/Matrix4.cs | 1239 ----------------- Robust.Shared.Maths/Quaternion.cs | 978 ------------- Robust.Shared.Maths/Vector3.cs | 1235 ---------------- Robust.Shared.Maths/Vector3d.cs | 1 + Robust.Shared.Maths/Vector4.cs | 1022 -------------- Robust.Shared.Maths/Vector4d.cs | 1 + Robust.Shared.Maths/VectorHelpers.cs | 31 + Robust.Shared/Audio/AudioPresetPrototype.cs | 1 + .../Audio/Components/AudioEffectComponent.cs | 3 +- .../Audio/Effects/DummyAudioEffect.cs | 1 + Robust.Shared/Audio/Effects/IAudioEffect.cs | 1 + Robust.Shared/Audio/Effects/ReverbPresets.cs | 1 + .../Audio/Effects/ReverbProperties.cs | 1 + Robust.Shared/ColorNaming/ColorNaming.cs | 1 + .../Systems/MapLoaderSystem.Load.cs | 1 - .../Systems/MapLoaderSystem.LoadMap.cs | 1 - Robust.Shared/Noise/NoiseGenerator.cs | 2 - .../Physics/Dynamics/Joints/PrismaticJoint.cs | 1 - .../Physics/Dynamics/Joints/WeldJoint.cs | 1 - .../Serialization/Matrix3x2Serializer.cs | 56 - .../Serialization/NetMathSerializers.cs | 61 + .../Serialization/RobustSerializer.cs | 3 +- .../Implementations/Vector3Serializer.cs | 3 +- .../Implementations/Vector4Serializer.cs | 3 +- .../Serialization/Vector2Serializer.cs | 49 - .../TypeParsers/Math/Vector3TypeParser.cs | 9 +- .../TypeParsers/Math/Vector4TypeParser.cs | 9 +- Robust.Shared/Utility/YamlHelpers.cs | 36 +- .../Shared/Maths/Matrix3_Test.cs | 1 - .../Prototypes/PrototypeManager_Test.cs | 2 - .../Serialization/NetSerializer_Test.cs | 2 +- .../Toolshed/ToolshedParserTest.Core.cs | 4 +- 53 files changed, 185 insertions(+), 4683 deletions(-) delete mode 100644 Robust.Shared.Maths/Matrix4.cs delete mode 100644 Robust.Shared.Maths/Quaternion.cs delete mode 100644 Robust.Shared.Maths/Vector3.cs delete mode 100644 Robust.Shared.Maths/Vector4.cs create mode 100644 Robust.Shared.Maths/VectorHelpers.cs delete mode 100644 Robust.Shared/Serialization/Matrix3x2Serializer.cs create mode 100644 Robust.Shared/Serialization/NetMathSerializers.cs delete mode 100644 Robust.Shared/Serialization/Vector2Serializer.cs diff --git a/Robust.Client/Animations/AnimationTrackProperty.cs b/Robust.Client/Animations/AnimationTrackProperty.cs index 228fbd62f..658534ce8 100644 --- a/Robust.Client/Animations/AnimationTrackProperty.cs +++ b/Robust.Client/Animations/AnimationTrackProperty.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Numerics; using Robust.Shared.Animations; using Robust.Shared.Maths; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Animations { @@ -122,9 +120,9 @@ namespace Robust.Client.Animations case Vector2 vector2: return Vector2Helpers.InterpolateCubic((Vector2) preA, vector2, (Vector2) b, (Vector2) postB, t); case Vector3 vector3: - return Vector3.InterpolateCubic((Vector3) preA, vector3, (Vector3) b, (Vector3) postB, t); + return VectorHelpers.InterpolateCubic((Vector3) preA, vector3, (Vector3) b, (Vector3) postB, t); case Vector4 vector4: - return Vector4.InterpolateCubic((Vector4) preA, vector4, (Vector4) b, (Vector4) postB, t); + return VectorHelpers.InterpolateCubic((Vector4) preA, vector4, (Vector4) b, (Vector4) postB, t); case float f: return MathHelper.InterpolateCubic((float) preA, f, (float) b, (float) postB, t); case double d: diff --git a/Robust.Client/Audio/Effects/AudioEffect.cs b/Robust.Client/Audio/Effects/AudioEffect.cs index 8e563ddab..55814c160 100644 --- a/Robust.Client/Audio/Effects/AudioEffect.cs +++ b/Robust.Client/Audio/Effects/AudioEffect.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using OpenTK.Audio.OpenAL.Extensions.Creative.EFX; using Robust.Shared.Audio; using Robust.Shared.Audio.Effects; diff --git a/Robust.Client/Console/Completions.cs b/Robust.Client/Console/Completions.cs index 0495455dd..3d9c60a4a 100644 --- a/Robust.Client/Console/Completions.cs +++ b/Robust.Client/Console/Completions.cs @@ -85,7 +85,7 @@ namespace Robust.Client.Console MouseFilter = MouseFilterMode.Stop; Result = result; var compl = new FormattedMessage(); - var dim = Color.FromHsl((0f, 0f, 0.8f, 1f)); + var dim = Color.FromHsl(new Vector4(0f, 0f, 0.8f, 1f)); // warning: ew ahead string basen = "default"; diff --git a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs index 13ad45d73..09bf8a55a 100644 --- a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs +++ b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs @@ -30,8 +30,6 @@ using Robust.Shared.ViewVariables; using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth; using static Robust.Shared.Serialization.TypeSerializers.Implementations.SpriteSpecifierSerializer; using Direction = Robust.Shared.Maths.Direction; -using Vector4 = Robust.Shared.Maths.Vector4; -using SysVec4 = System.Numerics.Vector4; #pragma warning disable CS0618 // Type or member is obsolete namespace Robust.Client.GameObjects diff --git a/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs b/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs index ac37f423b..e630ad932 100644 --- a/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs +++ b/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs @@ -7,8 +7,6 @@ using Robust.Shared.Graphics.RSI; using Robust.Shared.Maths; using Robust.Shared.Utility; using static Robust.Client.GameObjects.SpriteComponent; -using Vector4 = Robust.Shared.Maths.Vector4; -using SysVec4 = System.Numerics.Vector4; namespace Robust.Client.GameObjects; @@ -157,7 +155,7 @@ public sealed partial class SpriteSystem // Negative color modulation values are by the default shader to disable light shading. // Specifically we set colour = - 1 - colour // This is good enough to ensure that non-negative values become negative & is trivially invertible. - layerColor = new(new SysVec4(-1) - layerColor.RGBA); + layerColor = new(new Vector4(-1) - layerColor.RGBA); } drawingHandle.DrawTextureRectRegion(texture, quad, layerColor); diff --git a/Robust.Client/Graphics/Clyde/Clyde.GridRendering.cs b/Robust.Client/Graphics/Clyde/Clyde.GridRendering.cs index 445280adb..1d649db87 100644 --- a/Robust.Client/Graphics/Clyde/Clyde.GridRendering.cs +++ b/Robust.Client/Graphics/Clyde/Clyde.GridRendering.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using OpenToolkit.Graphics.OpenGL4; using Robust.Client.ResourceManagement; using Robust.Shared.Enums; diff --git a/Robust.Client/Graphics/Clyde/Clyde.Layout.cs b/Robust.Client/Graphics/Clyde/Clyde.Layout.cs index 5e7adcfaa..a4f273439 100644 --- a/Robust.Client/Graphics/Clyde/Clyde.Layout.cs +++ b/Robust.Client/Graphics/Clyde/Clyde.Layout.cs @@ -4,7 +4,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using JetBrains.Annotations; using Robust.Shared.Maths; -using Vector3 = Robust.Shared.Maths.Vector3; namespace Robust.Client.Graphics.Clyde { diff --git a/Robust.Client/Graphics/Clyde/Clyde.LightRendering.cs b/Robust.Client/Graphics/Clyde/Clyde.LightRendering.cs index 302e30201..036fee7e5 100644 --- a/Robust.Client/Graphics/Clyde/Clyde.LightRendering.cs +++ b/Robust.Client/Graphics/Clyde/Clyde.LightRendering.cs @@ -18,7 +18,6 @@ using Robust.Shared.Graphics; using static Robust.Shared.GameObjects.OccluderComponent; using Robust.Shared.Utility; using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics.Clyde { diff --git a/Robust.Client/Graphics/Clyde/Clyde.Rendering.cs b/Robust.Client/Graphics/Clyde/Clyde.Rendering.cs index f11b19d9c..f7d419161 100644 --- a/Robust.Client/Graphics/Clyde/Clyde.Rendering.cs +++ b/Robust.Client/Graphics/Clyde/Clyde.Rendering.cs @@ -11,8 +11,6 @@ using Robust.Shared.Graphics; using Robust.Shared.Maths; using Robust.Shared.Utility; using TKStencilOp = OpenToolkit.Graphics.OpenGL4.StencilOp; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics.Clyde { @@ -541,7 +539,7 @@ namespace Robust.Client.Graphics.Clyde case Matrix3x2 matrix3: program.SetUniform(name, matrix3); break; - case Matrix4 matrix4: + case Matrix4x4 matrix4: program.SetUniform(name, matrix4); break; case ClydeTexture clydeTexture: diff --git a/Robust.Client/Graphics/Clyde/Clyde.Shaders.cs b/Robust.Client/Graphics/Clyde/Clyde.Shaders.cs index c3daccd49..fd7d588d1 100644 --- a/Robust.Client/Graphics/Clyde/Clyde.Shaders.cs +++ b/Robust.Client/Graphics/Clyde/Clyde.Shaders.cs @@ -10,8 +10,6 @@ using Robust.Shared.Graphics; using Robust.Shared.Maths; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics.Clyde { @@ -528,7 +526,7 @@ namespace Robust.Client.Graphics.Clyde data.Parameters[name] = value; } - private protected override void SetParameterImpl(string name, in Matrix4 value) + private protected override void SetParameterImpl(string name, in Matrix4x4 value) { var data = Parent._shaderInstances[Handle]; data.ParametersDirty = true; diff --git a/Robust.Client/Graphics/Clyde/ClydeHeadless.cs b/Robust.Client/Graphics/Clyde/ClydeHeadless.cs index ded3683a1..4b5d45c26 100644 --- a/Robust.Client/Graphics/Clyde/ClydeHeadless.cs +++ b/Robust.Client/Graphics/Clyde/ClydeHeadless.cs @@ -17,8 +17,6 @@ using Robust.Shared.Timing; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using Color = Robust.Shared.Maths.Color; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics.Clyde { @@ -398,7 +396,7 @@ namespace Robust.Client.Graphics.Clyde { } - private protected override void SetParameterImpl(string name, in Matrix4 value) + private protected override void SetParameterImpl(string name, in Matrix4x4 value) { } diff --git a/Robust.Client/Graphics/Clyde/GLObjects/Clyde.ShaderProgram.cs b/Robust.Client/Graphics/Clyde/GLObjects/Clyde.ShaderProgram.cs index fba9b0da3..c70ec3734 100644 --- a/Robust.Client/Graphics/Clyde/GLObjects/Clyde.ShaderProgram.cs +++ b/Robust.Client/Graphics/Clyde/GLObjects/Clyde.ShaderProgram.cs @@ -5,8 +5,6 @@ using System.Runtime.CompilerServices; using OpenToolkit.Graphics.OpenGL4; using Robust.Shared.Maths; using Robust.Shared.Utility; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics.Clyde { @@ -277,20 +275,20 @@ namespace Robust.Client.Graphics.Clyde _clyde.CheckGlError(); } - public void SetUniform(string uniformName, in Matrix4 matrix, bool transpose=true) + public void SetUniform(string uniformName, in Matrix4x4 matrix, bool transpose=true) { var uniformId = GetUniform(uniformName); SetUniformDirect(uniformId, matrix, transpose); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe void SetUniformDirect(int uniformId, in Matrix4 value, bool transpose=true) + private unsafe void SetUniformDirect(int uniformId, in Matrix4x4 value, bool transpose=true) { - Matrix4 tmpTranspose = value; + Matrix4x4 tmpTranspose = value; if (transpose) { // transposition not supported on GLES2, & no access to _hasGLES - tmpTranspose.Transpose(); + tmpTranspose = Matrix4x4.Transpose(value); } GL.UniformMatrix4(uniformId, 1, false, (float*) &tmpTranspose); _clyde.CheckGlError(); @@ -551,7 +549,7 @@ namespace Robust.Client.Graphics.Clyde } } - public void SetUniformMaybe(string uniformName, in Matrix4 value, bool transpose=true) + public void SetUniformMaybe(string uniformName, in Matrix4x4 value, bool transpose=true) { if (TryGetUniform(uniformName, out var slot)) { diff --git a/Robust.Client/Graphics/Shaders/ShaderInstance.cs b/Robust.Client/Graphics/Shaders/ShaderInstance.cs index 6ed2f9f57..e79bb9170 100644 --- a/Robust.Client/Graphics/Shaders/ShaderInstance.cs +++ b/Robust.Client/Graphics/Shaders/ShaderInstance.cs @@ -4,8 +4,6 @@ using Robust.Shared.Graphics; using Robust.Shared.Maths; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics { @@ -169,7 +167,7 @@ namespace Robust.Client.Graphics SetParameterImpl(name, value); } - public void SetParameter(string name, in Matrix4 value) + public void SetParameter(string name, in Matrix4x4 value) { EnsureAlive(); EnsureMutable(); @@ -236,7 +234,7 @@ namespace Robust.Client.Graphics private protected abstract void SetParameterImpl(string name, bool value); private protected abstract void SetParameterImpl(string name, bool[] value); private protected abstract void SetParameterImpl(string name, in Matrix3x2 value); - private protected abstract void SetParameterImpl(string name, in Matrix4 value); + private protected abstract void SetParameterImpl(string name, in Matrix4x4 value); private protected abstract void SetParameterImpl(string name, Texture value); private protected abstract void SetStencilImpl(StencilParameters value); } diff --git a/Robust.Client/Graphics/Shaders/ShaderPrototype.cs b/Robust.Client/Graphics/Shaders/ShaderPrototype.cs index 7c0c12751..3377bf519 100644 --- a/Robust.Client/Graphics/Shaders/ShaderPrototype.cs +++ b/Robust.Client/Graphics/Shaders/ShaderPrototype.cs @@ -11,8 +11,6 @@ using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; using YamlDotNet.RepresentationModel; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Client.Graphics { @@ -222,7 +220,7 @@ namespace Robust.Client.Graphics case Matrix3x2 i: instance.SetParameter(key, i); break; - case Matrix4 i: + case Matrix4x4 i: instance.SetParameter(key, i); break; } diff --git a/Robust.Client/Placement/Modes/AlignWall.cs b/Robust.Client/Placement/Modes/AlignWall.cs index bac2ddab1..2ab9909e4 100644 --- a/Robust.Client/Placement/Modes/AlignWall.cs +++ b/Robust.Client/Placement/Modes/AlignWall.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; +using System.Numerics; using Robust.Shared.Map; -using Vector2 = System.Numerics.Vector2; namespace Robust.Client.Placement.Modes { diff --git a/Robust.Client/Placement/Modes/AlignWallProper.cs b/Robust.Client/Placement/Modes/AlignWallProper.cs index 73edb4742..09c5b471d 100644 --- a/Robust.Client/Placement/Modes/AlignWallProper.cs +++ b/Robust.Client/Placement/Modes/AlignWallProper.cs @@ -1,6 +1,6 @@ using System.Linq; +using System.Numerics; using Robust.Shared.Map; -using Vector2 = System.Numerics.Vector2; namespace Robust.Client.Placement.Modes { diff --git a/Robust.Client/UserInterface/Controls/ColorSelectorSliders.cs b/Robust.Client/UserInterface/Controls/ColorSelectorSliders.cs index d80200bf0..f59039c39 100644 --- a/Robust.Client/UserInterface/Controls/ColorSelectorSliders.cs +++ b/Robust.Client/UserInterface/Controls/ColorSelectorSliders.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Numerics; using Robust.Shared.ColorNaming; using Robust.Shared.IoC; using Robust.Shared.Localization; diff --git a/Robust.Client/UserInterface/Controls/ColorSelectorStyleBox.cs b/Robust.Client/UserInterface/Controls/ColorSelectorStyleBox.cs index 209585998..cad34afd9 100644 --- a/Robust.Client/UserInterface/Controls/ColorSelectorStyleBox.cs +++ b/Robust.Client/UserInterface/Controls/ColorSelectorStyleBox.cs @@ -21,19 +21,19 @@ public sealed class ColorSelectorStyleBox : StyleBoxTexture /// /// Base background colour. /// - public Robust.Shared.Maths.Vector4 BaseColor; + public Vector4 BaseColor; /// /// Colour to add to the background colour along the X-axis. /// I.e., from left to right the background colour will vary from (BaseColour) to (BaseColour + XAxis) /// - public Robust.Shared.Maths.Vector4 XAxis; + public Vector4 XAxis; /// /// Colour to add to the background colour along the y-axis. /// I.e., from left to right the background colour will vary from (BaseColour) to (BaseColour + XAxis) /// - public Robust.Shared.Maths.Vector4 YAxis; + public Vector4 YAxis; /// /// If true, then , , and will be interpreted as HSVa @@ -93,14 +93,14 @@ public sealed class ColorSelectorStyleBox : StyleBoxTexture { var colorData = Hsv ? Color.ToHsv(color) - : new Robust.Shared.Maths.Vector4(color.R, color.G, color.B, color.A); + : new Vector4(color.R, color.G, color.B, color.A); SetBaseColor(colorData); } /// /// Helper method that sets the base color by taking in some color and removing the components that are controlled by the x and y axes. /// - public void SetBaseColor(Robust.Shared.Maths.Vector4 colorData) + public void SetBaseColor(Vector4 colorData) { BaseColor = colorData - colorData * XAxis - colorData * YAxis; } diff --git a/Robust.Client/UserInterface/Controls/TextEdit.cs b/Robust.Client/UserInterface/Controls/TextEdit.cs index 9781fa287..4633b995d 100644 --- a/Robust.Client/UserInterface/Controls/TextEdit.cs +++ b/Robust.Client/UserInterface/Controls/TextEdit.cs @@ -13,7 +13,6 @@ using Robust.Shared.Maths; using Robust.Shared.Timing; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; -using Vector2 = System.Numerics.Vector2; namespace Robust.Client.UserInterface.Controls; diff --git a/Robust.Shared.Maths/Color.cs b/Robust.Shared.Maths/Color.cs index 3513dd2c2..96d3d7bff 100644 --- a/Robust.Shared.Maths/Color.cs +++ b/Robust.Shared.Maths/Color.cs @@ -29,12 +29,11 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using JetBrains.Annotations; using Robust.Shared.Utility; -using SysVector3 = System.Numerics.Vector3; -using SysVector4 = System.Numerics.Vector4; namespace Robust.Shared.Maths { @@ -69,7 +68,7 @@ namespace Robust.Shared.Maths /// Vector representation, for easy SIMD operations. /// // ReSharper disable once InconsistentNaming - public readonly SysVector4 RGBA => Unsafe.BitCast(this); + public readonly Vector4 RGBA => Unsafe.BitCast(this); public readonly byte RByte => (byte) (R * byte.MaxValue); public readonly byte GByte => (byte) (G * byte.MaxValue); @@ -94,9 +93,9 @@ namespace Robust.Shared.Maths /// /// Constructs a new Color structure from the components in a . /// - public Color(in SysVector4 vec) + public Color(in Vector4 vec) { - this = Unsafe.BitCast(vec); + this = Unsafe.BitCast(vec); } /// @@ -905,7 +904,7 @@ namespace Robust.Shared.Maths var m = (1 - g - k) / (1 - k); var y = (1 - b - k) / (1 - k); - return (c, m, y, k); + return new Vector4(c, m, y, k); } public static Color FromCmyk(Vector4 cmyk) @@ -932,7 +931,7 @@ namespace Robust.Shared.Maths [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Color InterpolateBetween(Color α, Color β, float λ) { - return new(SysVector4.Lerp(α.RGBA, β.RGBA, λ)); + return new(Vector4.Lerp(α.RGBA, β.RGBA, λ)); } public static Color? TryFromHex(ReadOnlySpan hexColor) @@ -1007,10 +1006,10 @@ namespace Robust.Shared.Maths public static Color Blend(Color dstColor, Color srcColor, BlendFactor dstFactor, BlendFactor srcFactor) { - var dst = new SysVector3(dstColor.R, dstColor.G, dstColor.B); - var src = new SysVector3(srcColor.R, srcColor.G, srcColor.B); + var dst = new Vector3(dstColor.R, dstColor.G, dstColor.B); + var src = new Vector3(srcColor.R, srcColor.G, srcColor.B); - var ret = new SysVector3(); + var ret = new Vector3(); switch (dstFactor) { @@ -1023,13 +1022,13 @@ namespace Robust.Shared.Maths ret = dst * src; break; case BlendFactor.OneMinusSrcColor: - ret = dst * (SysVector3.One - src); + ret = dst * (Vector3.One - src); break; case BlendFactor.DstColor: ret = dst * dst; break; case BlendFactor.OneMinusDstColor: - ret = dst * (SysVector3.One - dst); + ret = dst * (Vector3.One - dst); break; case BlendFactor.SrcAlpha: ret = dst * srcColor.A; @@ -1058,13 +1057,13 @@ namespace Robust.Shared.Maths ret += src * src; break; case BlendFactor.OneMinusSrcColor: - ret += src * (SysVector3.One - src); + ret += src * (Vector3.One - src); break; case BlendFactor.DstColor: ret += src * dst; break; case BlendFactor.OneMinusDstColor: - ret += src * (SysVector3.One - dst); + ret += src * (Vector3.One - dst); break; case BlendFactor.SrcAlpha: ret += src * srcColor.A; diff --git a/Robust.Shared.Maths/MathHelper.cs b/Robust.Shared.Maths/MathHelper.cs index 346060d0d..6d4ae8381 100644 --- a/Robust.Shared.Maths/MathHelper.cs +++ b/Robust.Shared.Maths/MathHelper.cs @@ -15,7 +15,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; -using Vec4 = System.Numerics.Vector4; namespace Robust.Shared.Maths { @@ -530,13 +529,13 @@ namespace Robust.Shared.Maths /// Returns whether two vectors are within of each other /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool CloseToPercent(Vec4 a, Vec4 b, float percentage = .00001f) + public static bool CloseToPercent(Vector4 a, Vector4 b, float percentage = .00001f) { - a = Vec4.Abs(a); - b = Vec4.Abs(b); - var p = new Vec4(percentage); - var epsilon = Vec4.Max(Vec4.Max(a, b) * p, p); - var delta = Vec4.Abs(a - b); + a = Vector4.Abs(a); + b = Vector4.Abs(b); + var p = new Vector4(percentage); + var epsilon = Vector4.Max(Vector4.Max(a, b) * p, p); + var delta = Vector4.Abs(a - b); return delta.X <= epsilon.X && delta.Y <= epsilon.Y && delta.Z <= epsilon.Z && delta.W <= epsilon.W; } diff --git a/Robust.Shared.Maths/Matrix4.cs b/Robust.Shared.Maths/Matrix4.cs deleted file mode 100644 index 6bb39b4ad..000000000 --- a/Robust.Shared.Maths/Matrix4.cs +++ /dev/null @@ -1,1239 +0,0 @@ -#region --- License --- - -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. -Copyright 2013 Xamarin Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ - -#endregion --- License --- - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Robust.Shared.Utility; - -namespace Robust.Shared.Maths -{ - /// - /// Represents a 4x4 Matrix - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix4 : IEquatable, ISpanFormattable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector4 Row0; - - /// - /// 2nd row of the matrix - /// - public Vector4 Row1; - - /// - /// 3rd row of the matrix - /// - public Vector4 Row2; - - /// - /// Bottom row of the matrix - /// - public Vector4 Row3; - - /// - /// The identity matrix - /// - public static readonly Matrix4 Identity = new(Vector4.UnitX, Vector4.UnitY, Vector4.UnitZ, Vector4.UnitW); - - #endregion Fields - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Third row of the matrix - /// Bottom row of the matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Matrix4(Vector4 row0, Vector4 row1, Vector4 row2, Vector4 row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the third row of the matrix. - /// Fourth item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - /// Third item of the fourth row of the matrix. - /// Fourth item of the fourth row of the matrix. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Matrix4( - float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33) - { - Row0 = new Vector4(m00, m01, m02, m03); - Row1 = new Vector4(m10, m11, m12, m13); - Row2 = new Vector4(m20, m21, m22, m23); - Row3 = new Vector4(m30, m31, m32, m33); - } - - #endregion Constructors - - #region Public Members - - #region Properties - - /// - /// The determinant of this matrix - /// - public float Determinant - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row0.X * Row1.Y * Row2.Z * Row3.W - Row0.X * Row1.Y * Row2.W * Row3.Z + Row0.X * Row1.Z * Row2.W * Row3.Y - Row0.X * Row1.Z * Row2.Y * Row3.W - + Row0.X * Row1.W * Row2.Y * Row3.Z - Row0.X * Row1.W * Row2.Z * Row3.Y - Row0.Y * Row1.Z * Row2.W * Row3.X + Row0.Y * Row1.Z * Row2.X * Row3.W - - Row0.Y * Row1.W * Row2.X * Row3.Z + Row0.Y * Row1.W * Row2.Z * Row3.X - Row0.Y * Row1.X * Row2.Z * Row3.W + Row0.Y * Row1.X * Row2.W * Row3.Z - + Row0.Z * Row1.W * Row2.X * Row3.Y - Row0.Z * Row1.W * Row2.Y * Row3.X + Row0.Z * Row1.X * Row2.Y * Row3.W - Row0.Z * Row1.X * Row2.W * Row3.Y - + Row0.Z * Row1.Y * Row2.W * Row3.X - Row0.Z * Row1.Y * Row2.X * Row3.W - Row0.W * Row1.X * Row2.Y * Row3.Z + Row0.W * Row1.X * Row2.Z * Row3.Y - - Row0.W * Row1.Y * Row2.Z * Row3.X + Row0.W * Row1.Y * Row2.X * Row3.Z - Row0.W * Row1.Z * Row2.X * Row3.Y + Row0.W * Row1.Z * Row2.Y * Row3.X; - } - - /// - /// The first column of this matrix - /// - public Vector4 Column0 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(Row0.X, Row1.X, Row2.X, Row3.X); - } - - /// - /// The second column of this matrix - /// - public Vector4 Column1 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(Row0.Y, Row1.Y, Row2.Y, Row3.Y); - } - - /// - /// The third column of this matrix - /// - public Vector4 Column2 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(Row0.Z, Row1.Z, Row2.Z, Row3.Z); - } - - /// - /// The fourth column of this matrix - /// - public Vector4 Column3 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(Row0.W, Row1.W, Row2.W, Row3.W); - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row0.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row0.X = value; - } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row0.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row0.Y = value; - } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row0.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row0.Z = value; - } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public float M14 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row0.W; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row0.W = value; - } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row1.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row1.X = value; - } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row1.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row1.Y = value; - } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row1.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row1.Z = value; - } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public float M24 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row1.W; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row1.W = value; - } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row2.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row2.X = value; - } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row2.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row2.Y = value; - } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public float M33 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row2.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row2.Z = value; - } - - /// - /// Gets or sets the value at row 3, column 4 of this instance. - /// - public float M34 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row2.W; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row2.W = value; - } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public float M41 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row3.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row3.X = value; - } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public float M42 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row3.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row3.Y = value; - } - - /// - /// Gets or sets the value at row 4, column 3 of this instance. - /// - public float M43 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row3.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row3.Z = value; - } - - /// - /// Gets or sets the value at row 4, column 4 of this instance. - /// - public float M44 - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Row3.W; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Row3.W = value; - } - - #endregion Properties - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - /// - public void Invert() - { - Invert(ref this); - } - - #endregion public void Invert() - - #region public void Transpose() - - /// - /// Converts this instance into its transpose. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Transpose() - { - this = Transpose(this); - } - - #endregion public void Transpose() - - #endregion Instance - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4 result) - { - var cos = (float) Math.Cos(-angle); - var sin = (float) Math.Sin(-angle); - var t = 1.0f - cos; - - axis.Normalize(); - - result = new Matrix4(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0.0f, - t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0.0f, - t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0.0f, - 0, 0, 0, 1); - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateFromAxisAngle(Vector3 axis, float angle) - { - CreateFromAxisAngle(axis, angle, out var result); - return result; - } - - #endregion CreateFromAxisAngle - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateRotationX(float angle, out Matrix4 result) - { - var cos = (float) Math.Cos(angle); - var sin = (float) Math.Sin(angle); - - result.Row0 = Vector4.UnitX; - result.Row1 = new Vector4(0.0f, cos, sin, 0.0f); - result.Row2 = new Vector4(0.0f, -sin, cos, 0.0f); - result.Row3 = Vector4.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateRotationX(float angle) - { - CreateRotationX(angle, out var result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateRotationY(float angle, out Matrix4 result) - { - var cos = (float) Math.Cos(angle); - var sin = (float) Math.Sin(angle); - - result.Row0 = new Vector4(cos, 0.0f, -sin, 0.0f); - result.Row1 = Vector4.UnitY; - result.Row2 = new Vector4(sin, 0.0f, cos, 0.0f); - result.Row3 = Vector4.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateRotationY(float angle) - { - CreateRotationY(angle, out var result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateRotationZ(float angle, out Matrix4 result) - { - var cos = (float) Math.Cos(angle); - var sin = (float) Math.Sin(angle); - - result.Row0 = new Vector4(cos, sin, 0.0f, 0.0f); - result.Row1 = new Vector4(-sin, cos, 0.0f, 0.0f); - result.Row2 = Vector4.UnitZ; - result.Row3 = Vector4.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateRotationZ(float angle) - { - CreateRotationZ(angle, out var result); - return result; - } - - #endregion CreateRotation[XYZ] - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateTranslation(float x, float y, float z, out Matrix4 result) - { - result = Identity; - result.Row3 = new Vector4(x, y, z, 1); - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateTranslation(ref Vector3 vector, out Matrix4 result) - { - result = Identity; - result.Row3 = new Vector4(vector.X, vector.Y, vector.Z, 1); - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateTranslation(float x, float y, float z) - { - CreateTranslation(x, y, z, out var result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateTranslation(Vector3 vector) - { - CreateTranslation(vector.X, vector.Y, vector.Z, out var result); - return result; - } - - #endregion CreateTranslation - - #region CreateOrthographic - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateOrthographic(float width, float height, float zNear, float zFar, out Matrix4 result) - { - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result); - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateOrthographic(float width, float height, float zNear, float zFar) - { - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out var result); - return result; - } - - #endregion CreateOrthographic - - #region CreateOrthographicOffCenter - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, out Matrix4 result) - { - result = new Matrix4(); - - var invRL = 1 / (right - left); - var invTB = 1 / (top - bottom); - var invFN = 1 / (zFar - zNear); - - result.M11 = 2 * invRL; - result.M22 = 2 * invTB; - result.M33 = -2 * invFN; - - result.M41 = -(right + left) * invRL; - result.M42 = -(top + bottom) * invTB; - result.M43 = -(zFar + zNear) * invFN; - result.M44 = 1; - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar) - { - CreateOrthographicOffCenter(left, right, bottom, top, zNear, zFar, out var result); - return result; - } - - #endregion CreateOrthographicOffCenter - - #region CreatePerspectiveFieldOfView - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar, out Matrix4 result) - { - if (fovy <= 0 || fovy > Math.PI) - throw new ArgumentOutOfRangeException("fovy"); - if (aspect <= 0) - throw new ArgumentOutOfRangeException("aspect"); - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - - var yMax = zNear * (float) Math.Tan(0.5f * fovy); - var yMin = -yMax; - var xMin = yMin * aspect; - var xMax = yMax * aspect; - - CreatePerspectiveOffCenter(xMin, xMax, yMin, yMax, zNear, zFar, out result); - } - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar) - { - CreatePerspectiveFieldOfView(fovy, aspect, zNear, zFar, out var result); - return result; - } - - #endregion CreatePerspectiveFieldOfView - - #region CreatePerspectiveOffCenter - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, out Matrix4 result) - { - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - if (zNear >= zFar) - throw new ArgumentOutOfRangeException("zNear"); - - var x = 2.0f * zNear / (right - left); - var y = 2.0f * zNear / (top - bottom); - var a = (right + left) / (right - left); - var b = (top + bottom) / (top - bottom); - var c = -(zFar + zNear) / (zFar - zNear); - var d = -(2.0f * zFar * zNear) / (zFar - zNear); - - result = new Matrix4(x, 0, 0, 0, - 0, y, 0, 0, - a, b, c, -1, - 0, 0, d, 0); - } - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar) - { - CreatePerspectiveOffCenter(left, right, bottom, top, zNear, zFar, out var result); - return result; - } - - #endregion CreatePerspectiveOffCenter - - #region Scale Functions - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Scale(float scale) - { - return Scale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Scale(Vector3 scale) - { - return Scale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Scale(float x, float y, float z) - { - Matrix4 result; - result.Row0 = Vector4.UnitX * x; - result.Row1 = Vector4.UnitY * y; - result.Row2 = Vector4.UnitZ * z; - result.Row3 = Vector4.UnitW; - return result; - } - - #endregion Scale Functions - - #region Rotation Functions - - /// - /// Build a rotation matrix from a quaternion - /// - /// the quaternion - /// A rotation matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Rotate(Quaternion q) - { - q.ToAxisAngle(out var axis, out var angle); - return CreateFromAxisAngle(axis, angle); - } - - #endregion Rotation Functions - - #region Camera Helper Functions - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix4 that transforms world space to camera space - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up) - { - var z = Vector3.Normalize(eye - target); - var x = Vector3.Normalize(Vector3.Cross(up, z)); - var y = Vector3.Normalize(Vector3.Cross(z, x)); - - var rot = new Matrix4(new Vector4(x.X, y.X, z.X, 0.0f), - new Vector4(x.Y, y.Y, z.Y, 0.0f), - new Vector4(x.Z, y.Z, z.Z, 0.0f), - Vector4.UnitW); - - var trans = CreateTranslation(-eye); - - return trans * rot; - } - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Target position in world space - /// Target position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix4 that transforms world space to camera space - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 LookAt(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ) - { - return LookAt(new Vector3(eyeX, eyeY, eyeZ), new Vector3(targetX, targetY, targetZ), new Vector3(upX, upY, upZ)); - } - - #endregion Camera Helper Functions - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Mult(Matrix4 left, Matrix4 right) - { - Mult(ref left, ref right, out var result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Mult(ref Matrix4 left, ref Matrix4 right, out Matrix4 result) - { - float lM11 = left.Row0.X, - lM12 = left.Row0.Y, - lM13 = left.Row0.Z, - lM14 = left.Row0.W, - lM21 = left.Row1.X, - lM22 = left.Row1.Y, - lM23 = left.Row1.Z, - lM24 = left.Row1.W, - lM31 = left.Row2.X, - lM32 = left.Row2.Y, - lM33 = left.Row2.Z, - lM34 = left.Row2.W, - lM41 = left.Row3.X, - lM42 = left.Row3.Y, - lM43 = left.Row3.Z, - lM44 = left.Row3.W, - rM11 = right.Row0.X, - rM12 = right.Row0.Y, - rM13 = right.Row0.Z, - rM14 = right.Row0.W, - rM21 = right.Row1.X, - rM22 = right.Row1.Y, - rM23 = right.Row1.Z, - rM24 = right.Row1.W, - rM31 = right.Row2.X, - rM32 = right.Row2.Y, - rM33 = right.Row2.Z, - rM34 = right.Row2.W, - rM41 = right.Row3.X, - rM42 = right.Row3.Y, - rM43 = right.Row3.Z, - rM44 = right.Row3.W; - - result.Row0.X = lM11 * rM11 + lM12 * rM21 + lM13 * rM31 + lM14 * rM41; - result.Row0.Y = lM11 * rM12 + lM12 * rM22 + lM13 * rM32 + lM14 * rM42; - result.Row0.Z = lM11 * rM13 + lM12 * rM23 + lM13 * rM33 + lM14 * rM43; - result.Row0.W = lM11 * rM14 + lM12 * rM24 + lM13 * rM34 + lM14 * rM44; - result.Row1.X = lM21 * rM11 + lM22 * rM21 + lM23 * rM31 + lM24 * rM41; - result.Row1.Y = lM21 * rM12 + lM22 * rM22 + lM23 * rM32 + lM24 * rM42; - result.Row1.Z = lM21 * rM13 + lM22 * rM23 + lM23 * rM33 + lM24 * rM43; - result.Row1.W = lM21 * rM14 + lM22 * rM24 + lM23 * rM34 + lM24 * rM44; - result.Row2.X = lM31 * rM11 + lM32 * rM21 + lM33 * rM31 + lM34 * rM41; - result.Row2.Y = lM31 * rM12 + lM32 * rM22 + lM33 * rM32 + lM34 * rM42; - result.Row2.Z = lM31 * rM13 + lM32 * rM23 + lM33 * rM33 + lM34 * rM43; - result.Row2.W = lM31 * rM14 + lM32 * rM24 + lM33 * rM34 + lM34 * rM44; - result.Row3.X = lM41 * rM11 + lM42 * rM21 + lM43 * rM31 + lM44 * rM41; - result.Row3.Y = lM41 * rM12 + lM42 * rM22 + lM43 * rM32 + lM44 * rM42; - result.Row3.Z = lM41 * rM13 + lM42 * rM23 + lM43 * rM33 + lM44 * rM43; - result.Row3.W = lM41 * rM14 + lM42 * rM24 + lM43 * rM34 + lM44 * rM44; - } - - #endregion Multiply Functions - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Invert(Matrix4 mat) - { - var result = new Matrix4(); - mat.Invert(ref result); - return result; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Invert(ref Matrix4 result) - { - float m41 = Row3.X, m42 = Row3.Y, m43 = Row3.Z, m44 = Row3.W; - if (m41 == 0 && m42 == 0 && m43 == 0 && m44 == 1.0f) - { - InvertAffine(ref result); - return; - } - - var d = Determinant; - if (d == 0.0f) - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - - var d1 = 1 / d; - float m11 = Row0.X, - m12 = Row0.Y, - m13 = Row0.Z, - m14 = Row0.W, - m21 = Row1.X, - m22 = Row1.Y, - m23 = Row1.Z, - m24 = Row1.W, - m31 = Row2.X, - m32 = Row2.Y, - m33 = Row2.Z, - m34 = Row2.W; - - result.Row0.X = d1 * (m22 * m33 * m44 + m23 * m34 * m42 + m24 * m32 * m43 - m22 * m34 * m43 - m23 * m32 * m44 - m24 * m33 * m42); - result.Row0.Y = d1 * (m12 * m34 * m43 + m13 * m32 * m44 + m14 * m33 * m42 - m12 * m33 * m44 - m13 * m34 * m42 - m14 * m32 * m43); - result.Row0.Z = d1 * (m12 * m23 * m44 + m13 * m24 * m42 + m14 * m22 * m43 - m12 * m24 * m43 - m13 * m22 * m44 - m14 * m23 * m42); - result.Row0.W = d1 * (m12 * m24 * m33 + m13 * m22 * m34 + m14 * m23 * m32 - m12 * m23 * m34 - m13 * m24 * m32 - m14 * m22 * m33); - result.Row1.X = d1 * (m21 * m34 * m43 + m23 * m31 * m44 + m24 * m33 * m41 - m21 * m33 * m44 - m23 * m34 * m41 - m24 * m31 * m43); - result.Row1.Y = d1 * (m11 * m33 * m44 + m13 * m34 * m41 + m14 * m31 * m43 - m11 * m34 * m43 - m13 * m31 * m44 - m14 * m33 * m41); - result.Row1.Z = d1 * (m11 * m24 * m43 + m13 * m21 * m44 + m14 * m23 * m41 - m11 * m23 * m44 - m13 * m24 * m41 - m14 * m21 * m43); - result.Row1.W = d1 * (m11 * m23 * m34 + m13 * m24 * m31 + m14 * m21 * m33 - m11 * m24 * m33 - m13 * m21 * m34 - m14 * m23 * m31); - result.Row2.X = d1 * (m21 * m32 * m44 + m22 * m34 * m41 + m24 * m31 * m42 - m21 * m34 * m42 - m22 * m31 * m44 - m24 * m32 * m41); - result.Row2.Y = d1 * (m11 * m34 * m42 + m12 * m31 * m44 + m14 * m32 * m41 - m11 * m32 * m44 - m12 * m34 * m41 - m14 * m31 * m42); - result.Row2.Z = d1 * (m11 * m22 * m44 + m12 * m24 * m41 + m14 * m21 * m42 - m11 * m24 * m42 - m12 * m21 * m44 - m14 * m22 * m41); - result.Row2.W = d1 * (m11 * m24 * m32 + m12 * m21 * m34 + m14 * m22 * m31 - m11 * m22 * m34 - m12 * m24 * m31 - m14 * m21 * m32); - result.Row3.X = d1 * (m21 * m33 * m42 + m22 * m31 * m43 + m23 * m32 * m41 - m21 * m32 * m43 - m22 * m33 * m41 - m23 * m31 * m42); - result.Row3.Y = d1 * (m11 * m32 * m43 + m12 * m33 * m41 + m13 * m31 * m42 - m11 * m33 * m42 - m12 * m31 * m43 - m13 * m32 * m41); - result.Row3.Z = d1 * (m11 * m23 * m42 + m12 * m21 * m43 + m13 * m22 * m41 - m11 * m22 * m43 - m12 * m23 * m41 - m13 * m21 * m42); - result.Row3.W = d1 * (m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 - m11 * m23 * m32 - m12 * m21 * m33 - m13 * m22 * m31); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void InvertAffine(ref Matrix4 result) - { - float m11 = Row0.X, - m12 = Row0.Y, - m13 = Row0.Z, - m14 = Row0.W, - m21 = Row1.X, - m22 = Row1.Y, - m23 = Row1.Z, - m24 = Row1.W, - m31 = Row2.X, - m32 = Row2.Y, - m33 = Row2.Z, - m34 = Row2.W; - - var d = m11 * m22 * m33 + m21 * m32 * m13 + m31 * m12 * m23 - - m11 * m32 * m23 - m31 * m22 * m13 - m21 * m12 * m33; - - if (d == 0.0f) - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - - var d1 = 1 / d; - - // sub 3x3 inv - result.Row0.X = d1 * (m22 * m33 - m23 * m32); - result.Row0.Y = d1 * (m13 * m32 - m12 * m33); - result.Row0.Z = d1 * (m12 * m23 - m13 * m22); - result.Row1.X = d1 * (m23 * m31 - m21 * m33); - result.Row1.Y = d1 * (m11 * m33 - m13 * m31); - result.Row1.Z = d1 * (m13 * m21 - m11 * m23); - result.Row2.X = d1 * (m21 * m32 - m22 * m31); - result.Row2.Y = d1 * (m12 * m31 - m11 * m32); - result.Row2.Z = d1 * (m11 * m22 - m12 * m21); - - // - sub 3x3 inv * b - result.Row0.W = -result.Row0.X * m14 - result.Row0.Y * m24 - result.Row0.Z * m34; - result.Row1.W = -result.Row1.X * m14 - result.Row1.Y * m24 - result.Row1.Z * m34; - result.Row2.W = -result.Row2.X * m14 - result.Row2.Y * m24 - result.Row2.Z * m34; - - // last row remains 0 0 0 1 - result.Row3.X = result.Row3.Y = result.Row3.Z = 0.0f; - result.Row3.W = 1.0f; - } - - #endregion Invert Functions - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 Transpose(Matrix4 mat) - { - return new(mat.Column0, mat.Column1, mat.Column2, mat.Column3); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transpose(ref Matrix4 mat, out Matrix4 result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - result.Row3 = mat.Column3; - } - - #endregion Transpose - - #endregion Static - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix44 which holds the result of the multiplication - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4 operator *(Matrix4 left, Matrix4 right) - { - return Mult(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Matrix4 left, Matrix4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Matrix4 left, Matrix4 right) - { - return !left.Equals(right); - } - - #endregion Operators - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix44. - /// - /// - public readonly override string ToString() - { - return $"{Row0}\n{Row1}\n{Row2}\n{Row3}"; - } - - public readonly string ToString(string? format, IFormatProvider? formatProvider) - { - return ToString(); - } - - public readonly bool TryFormat( - Span destination, - out int charsWritten, - ReadOnlySpan format, - IFormatProvider? provider) - { - return FormatHelpers.TryFormatInto( - destination, - out charsWritten, - $"{Row0}\n{Row1}\n{Row2}\n{Row3}"); - } - - #endregion public override string ToString() - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode(); - } - - #endregion public override int GetHashCode() - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare with this matrix. - /// True if the instances are equal; false otherwise. - public override bool Equals(object? obj) - { - if (!(obj is Matrix4)) - return false; - - return Equals((Matrix4) obj); - } - - #endregion public override bool Equals(object obj) - - #endregion Overrides - - #endregion Public Members - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion IEquatable Members - } -} diff --git a/Robust.Shared.Maths/Quaternion.cs b/Robust.Shared.Maths/Quaternion.cs deleted file mode 100644 index 7037852af..000000000 --- a/Robust.Shared.Maths/Quaternion.cs +++ /dev/null @@ -1,978 +0,0 @@ -#region --- License --- - -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. -Copyright 2013 Xamarin Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ - -#endregion --- License --- - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Xml.Serialization; -using Robust.Shared.Utility; - -namespace Robust.Shared.Maths -{ - /// - /// Represents a Quaternion. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Quaternion : IEquatable, ISpanFormattable - { - #region Fields - - private Vector3 xyz; - private float w; - - #endregion Fields - - #region Constructors - - /// - /// Construct a new Quaternion from vector and w components - /// - /// The vector part - /// The w part - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Quaternion(Vector3 v, float w) - { - xyz = v; - this.w = w; - } - - /// - /// Construct a new Quaternion - /// - /// The x component - /// The y component - /// The z component - /// The w component - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Quaternion(float x, float y, float z, float w) - : this(new Vector3(x, y, z), w) { } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Quaternion(ref Matrix3x2 matrix) - { - var scale = Math.Pow(matrix.GetDeterminant(), 1.0d / 3.0d); - float x, y, z; - - w = (float) (Math.Sqrt(Math.Max(0, scale + matrix[0, 0] + matrix[1, 1] + matrix[2, 2])) / 2); - x = (float) (Math.Sqrt(Math.Max(0, scale + matrix[0, 0] - matrix[1, 1] - matrix[2, 2])) / 2); - y = (float) (Math.Sqrt(Math.Max(0, scale - matrix[0, 0] + matrix[1, 1] - matrix[2, 2])) / 2); - z = (float) (Math.Sqrt(Math.Max(0, scale - matrix[0, 0] - matrix[1, 1] + matrix[2, 2])) / 2); - - xyz = new Vector3(x, y, z); - - if (matrix[2, 1] - matrix[1, 2] < 0) X = -X; - if (matrix[0, 2] - matrix[2, 0] < 0) Y = -Y; - if (matrix[1, 0] - matrix[0, 1] < 0) Z = -Z; - } - - #endregion Constructors - - #region Public Members - - #region Properties - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance. - /// - public Vector3 Xyz - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz = value; - } - - /// - /// Gets or sets the X component of this instance. - /// - [XmlIgnore] - public float X - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.X = value; - } - - /// - /// Gets or sets the Y component of this instance. - /// - [XmlIgnore] - public float Y - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.Y = value; - } - - /// - /// Gets or sets the Z component of this instance. - /// - [XmlIgnore] - public float Z - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.Z = value; - } - - /// - /// Gets or sets the W component of this instance. - /// - public float W - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => w; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => w = value; - } - - public float x - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.X; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.X = value; - } - - public float y - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.Y; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.Y = value; - } - - public float z - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => xyz.Z; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => xyz.Z = value; - } - - #endregion Properties - - #region Instance - - #region ToAxisAngle - - /// - /// Convert the current quaternion to axis angle representation - /// - /// The resultant axis - /// The resultant angle - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToAxisAngle(out Vector3 axis, out float angle) - { - var result = ToAxisAngle(); - axis = result.Xyz; - angle = result.W; - } - - /// - /// Convert this instance to an axis-angle representation. - /// - /// A Vector4 that is the axis-angle representation of this quaternion. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToAxisAngle() - { - var q = this; - if (Math.Abs(q.W) > 1.0f) - q.Normalize(); - - var result = new Vector4(); - - result.W = 2.0f * (float) Math.Acos(q.W); // angle - var den = (float) Math.Sqrt(1.0 - q.W * q.W); - if (den > 0.0001f) - { - result.Xyz = q.Xyz / den; - } - else - { - // This occurs when the angle is zero. - // Not a problem: just set an arbitrary normalized axis. - result.Xyz = Vector3.UnitX; - } - - return result; - } - - #endregion ToAxisAngle - - #region public float Length - - /// - /// Gets the length (magnitude) of the quaternion. - /// - /// - public float Length - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => (float) Math.Sqrt(W * W + Xyz.LengthSquared); - } - - #endregion public float Length - - #region public float LengthSquared - - /// - /// Gets the square of the quaternion length (magnitude). - /// - public float LengthSquared - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => W * W + Xyz.LengthSquared; - } - - #endregion public float LengthSquared - - #region public void Normalize() - - /// - /// Scales the Quaternion to unit length. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Normalize() - { - var scale = 1.0f / Length; - Xyz *= scale; - W *= scale; - } - - #endregion public void Normalize() - - #region public void Conjugate() - - /// - /// Convert this quaternion to its conjugate - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Conjugate() - { - Xyz = -Xyz; - } - - #endregion public void Conjugate() - - #endregion Instance - - #region Static - - #region Fields - - private const float RadToDeg = (float) (180.0 / Math.PI); - private const float DegToRad = (float) (Math.PI / 180.0); - - /// - /// Defines the identity quaternion. - /// - public static readonly Quaternion Identity = new(0, 0, 0, 1); - - #endregion Fields - - #region Add - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Add(Quaternion left, Quaternion right) - { - return new( - left.Xyz + right.Xyz, - left.W + right.W); - } - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - left.Xyz + right.Xyz, - left.W + right.W); - } - - #endregion Add - - #region Sub - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Sub(Quaternion left, Quaternion right) - { - return new( - left.Xyz - right.Xyz, - left.W - right.W); - } - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Sub(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - left.Xyz - right.Xyz, - left.W - right.W); - } - - #endregion Sub - - #region Mult - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Multiply(Quaternion left, Quaternion right) - { - Multiply(ref left, ref right, out var result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Quaternion quaternion, float scale, out Quaternion result) - { - result = new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Multiply(Quaternion quaternion, float scale) - { - return new(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - #endregion Mult - - #region Dot - - /// - /// Calculates the dot product between two Quaternions. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Dot(Quaternion a, Quaternion b) - { - return a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W; - } - - #endregion Dot - - #region Conjugate - - /// - /// Get the conjugate of the given quaternion - /// - /// The quaternion - /// The conjugate of the given quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Conjugate(Quaternion q) - { - return new(-q.Xyz, q.W); - } - - /// - /// Get the conjugate of the given quaternion - /// - /// The quaternion - /// The conjugate of the given quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Conjugate(ref Quaternion q, out Quaternion result) - { - result = new Quaternion(-q.Xyz, q.W); - } - - #endregion Conjugate - - #region Invert - - /// - /// Get the inverse of the given quaternion - /// - /// The quaternion to invert - /// The inverse of the given quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Invert(Quaternion q) - { - Invert(ref q, out var result); - return result; - } - - /// - /// Get the inverse of the given quaternion - /// - /// The quaternion to invert - /// The inverse of the given quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Invert(ref Quaternion q, out Quaternion result) - { - var lengthSq = q.LengthSquared; - if (lengthSq != 0.0) - { - var i = 1.0f / lengthSq; - result = new Quaternion(q.Xyz * -i, q.W * i); - } - else - { - result = q; - } - } - - #endregion Invert - - #region Normalize - - /// - /// Scale the given quaternion to unit length - /// - /// The quaternion to normalize - /// The normalized quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Normalize(Quaternion q) - { - Normalize(ref q, out var result); - return result; - } - - /// - /// Scale the given quaternion to unit length - /// - /// The quaternion to normalize - /// The normalized quaternion - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Normalize(ref Quaternion q, out Quaternion result) - { - var scale = 1.0f / q.Length; - result = new Quaternion(q.Xyz * scale, q.W * scale); - } - - #endregion Normalize - - #region FromAxisAngle - - /// - /// Build a quaternion from the given axis and angle - /// - /// The axis to rotate about - /// The rotation angle in radians - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion FromAxisAngle(Vector3 axis, float angle) - { - if (axis.LengthSquared == 0.0f) - return Identity; - - var result = Identity; - - angle *= 0.5f; - axis.Normalize(); - result.Xyz = axis * (float) Math.Sin(angle); - result.W = (float) Math.Cos(angle); - - return Normalize(result); - } - - #endregion FromAxisAngle - - #region Slerp - - /// - /// Do Spherical linear interpolation between two quaternions - /// - /// The first quaternion - /// The second quaternion - /// The blend factor - /// A smooth blend between the given quaternions - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion Slerp(Quaternion q1, Quaternion q2, float blend) - { - // if either input is zero, return the other. - if (q1.LengthSquared == 0.0f) - { - if (q2.LengthSquared == 0.0f) - { - return Identity; - } - - return q2; - } - - if (q2.LengthSquared == 0.0f) - { - return q1; - } - - var cosHalfAngle = q1.W * q2.W + Vector3.Dot(q1.Xyz, q2.Xyz); - - if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) - { - // angle = 0.0f, so just return one input. - return q1; - } - - if (cosHalfAngle < 0.0f) - { - q2.Xyz = -q2.Xyz; - q2.W = -q2.W; - cosHalfAngle = -cosHalfAngle; - } - - float blendA; - float blendB; - if (cosHalfAngle < 0.99f) - { - // do proper slerp for big angles - var halfAngle = (float) Math.Acos(cosHalfAngle); - var sinHalfAngle = (float) Math.Sin(halfAngle); - var oneOverSinHalfAngle = 1.0f / sinHalfAngle; - blendA = (float) Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle; - blendB = (float) Math.Sin(halfAngle * blend) * oneOverSinHalfAngle; - } - else - { - // do lerp if angle is really small. - blendA = 1.0f - blend; - blendB = blend; - } - - var result = new Quaternion(blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.W + blendB * q2.W); - if (result.LengthSquared > 0.0f) - return Normalize(result); - return Identity; - } - - #endregion Slerp - - #region RotateTowards - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta) - { - var num = Angle(from, to); - if (num == 0f) - { - return to; - } - - var t = MathF.Min(1f, maxDegreesDelta / num); - return Slerp(from, to, t); - } - - #endregion RotateTowards - - #region Angle - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Angle(Quaternion a, Quaternion b) - { - var f = Dot(a, b); - return (float) (Math.Acos(Math.Min(Math.Abs(f), 1f)) * 2f * RadToDeg); - } - - #endregion Angle - - #region LookRotation - - // from http://answers.unity3d.com/questions/467614/what-is-the-source-code-of-quaternionlookrotation.html - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion LookRotation(ref Vector3 forward, ref Vector3 up) - { - forward = Vector3.Normalize(forward); - var right = Vector3.Normalize(Vector3.Cross(up, forward)); - up = Vector3.Cross(forward, right); - var m00 = right.X; - var m01 = right.Y; - var m02 = right.Z; - var m10 = up.X; - var m11 = up.Y; - var m12 = up.Z; - var m20 = forward.X; - var m21 = forward.Y; - var m22 = forward.Z; - - var num8 = m00 + m11 + m22; - var quaternion = new Quaternion(); - if (num8 > 0f) - { - var num = MathF.Sqrt(num8 + 1f); - quaternion.w = num * 0.5f; - num = 0.5f / num; - quaternion.X = (m12 - m21) * num; - quaternion.Y = (m20 - m02) * num; - quaternion.Z = (m01 - m10) * num; - return quaternion; - } - - if (m00 >= m11 && m00 >= m22) - { - var num7 = MathF.Sqrt(1f + m00 - m11 - m22); - var num4 = 0.5f / num7; - quaternion.X = 0.5f * num7; - quaternion.Y = (m01 + m10) * num4; - quaternion.Z = (m02 + m20) * num4; - quaternion.W = (m12 - m21) * num4; - return quaternion; - } - - if (m11 > m22) - { - var num6 = MathF.Sqrt(1f + m11 - m00 - m22); - var num3 = 0.5f / num6; - quaternion.X = (m10 + m01) * num3; - quaternion.Y = 0.5f * num6; - quaternion.Z = (m21 + m12) * num3; - quaternion.W = (m20 - m02) * num3; - return quaternion; - } - - var num5 = MathF.Sqrt(1f + m22 - m00 - m11); - var num2 = 0.5f / num5; - quaternion.X = (m20 + m02) * num2; - quaternion.Y = (m21 + m12) * num2; - quaternion.Z = 0.5f * num5; - quaternion.W = (m01 - m10) * num2; - return quaternion; - } - - #endregion LookRotation - - #region Euler Angles - - // from http://stackoverflow.com/questions/12088610/conversion-between-euler-quaternion-like-in-unity3d-engine - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 ToEulerRad(Quaternion rotation) - { - var sqw = rotation.w * rotation.w; - var sqx = rotation.x * rotation.x; - var sqy = rotation.y * rotation.y; - var sqz = rotation.z * rotation.z; - var unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor - var test = rotation.x * rotation.w - rotation.y * rotation.z; - Vector3 v; - - if (test > 0.4995f * unit) - { - // singularity at north pole - v.Y = 2f * MathF.Atan2(rotation.y, rotation.x); - v.X = (float) (Math.PI / 2); - v.Z = 0; - return NormalizeAngles(v * RadToDeg); - } - - if (test < -0.4995f * unit) - { - // singularity at south pole - v.Y = -2f * MathF.Atan2(rotation.y, rotation.x); - v.X = (float) (-Math.PI / 2); - v.Z = 0; - return NormalizeAngles(v * RadToDeg); - } - - var q = new Quaternion(rotation.w, rotation.z, rotation.x, rotation.y); - v.Y = MathF.Atan2(2f * q.x * q.w + 2f * q.y * q.z, 1 - 2f * (q.z * q.z + q.w * q.w)); // Yaw - v.X = MathF.Asin(2f * (q.x * q.z - q.w * q.y)); // Pitch - v.Z = MathF.Atan2(2f * q.x * q.y + 2f * q.z * q.w, 1 - 2f * (q.y * q.y + q.z * q.z)); // Roll - return NormalizeAngles(v * RadToDeg); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector3 NormalizeAngles(Vector3 angles) - { - angles.X = NormalizeAngle(angles.X); - angles.Y = NormalizeAngle(angles.Y); - angles.Z = NormalizeAngle(angles.Z); - return angles; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static float NormalizeAngle(float angle) - { - /* - while (angle > 360) - angle -= 360; - while (angle < 0) - angle += 360; - return angle; - - asm: - - L0000: vzeroupper - L0003: vucomiss xmm0, [fld 360f] - L000b: jbe short L001f - L000d: vsubss xmm0, xmm0, [fld 360f] - L0015: vucomiss xmm0, [fld 0] - L001d: ja short L000d - L001f: vxorps xmm1, xmm1, xmm1 - L0023: vucomiss xmm1, xmm0 - L0027: jbe short L003b - L0029: vaddss xmm0, xmm0, [fld 360f] - L0031: vxorps xmm1, xmm1, xmm1 - L0035: vucomiss xmm1, xmm0 - L0039: ja short L0029 - L003b: ret - - */ - - return angle - MathF.Floor(angle * (1/360f)) * 360f; - /* asm: - L0000: vzeroupper - L0003: vmovaps xmm1, xmm0 - L0007: vmulss xmm1, xmm1, [fld 1/360f] - L000f: vroundss xmm1, xmm1, xmm1, 9 - L0015: vmulss xmm1, xmm1, [fld 360f] - L001d: vsubss xmm0, xmm0, xmm1 - L0021: ret - */ - } - - #endregion Euler Angles - - #endregion Static - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion operator +(Quaternion left, Quaternion right) - { - left.Xyz += right.Xyz; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion operator -(Quaternion left, Quaternion right) - { - left.Xyz -= right.Xyz; - left.W -= right.W; - return left; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion operator *(Quaternion left, Quaternion right) - { - Multiply(ref left, ref right, out left); - return left; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion operator *(Quaternion quaternion, float scale) - { - Multiply(ref quaternion, scale, out quaternion); - return quaternion; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Quaternion operator *(float scale, Quaternion quaternion) - { - return new(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Quaternion left, Quaternion right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Quaternion left, Quaternion right) - { - return !left.Equals(right); - } - - #endregion Operators - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Quaternion. - /// - /// - public readonly override string ToString() - { - return $"V: {xyz}, W: {w}"; - } - - public readonly string ToString(string? format, IFormatProvider? formatProvider) - { - return ToString(); - } - - public readonly bool TryFormat( - Span destination, - out int charsWritten, - ReadOnlySpan format, - IFormatProvider? provider) - { - return FormatHelpers.TryFormatInto( - destination, - out charsWritten, - $"V: {xyz}, W: {w}"); - } - - #endregion public override string ToString() - - #region public override bool Equals (object o) - - /// - /// Compares this object instance to another object for equality. - /// - /// The other object to be used in the comparison. - /// True if both objects are Quaternions of equal value. Otherwise it returns false. - public override bool Equals(object? obj) - { - if (obj is Quaternion quaternion) return this == quaternion; - return false; - } - - #endregion public override bool Equals (object o) - - #region public override int GetHashCode () - - /// - /// Provides the hash code for this object. - /// - /// A hash code formed from the bitwise XOR of this objects members. - public override int GetHashCode() - { - return Xyz.GetHashCode() ^ W.GetHashCode(); - } - - #endregion public override int GetHashCode () - - #endregion Overrides - - #endregion Public Members - - #region IEquatable Members - - /// - /// Compares this Quaternion instance to another Quaternion for equality. - /// - /// The other Quaternion to be used in the comparison. - /// True if both instances are equal; false otherwise. - public bool Equals(Quaternion other) - { - return Xyz == other.Xyz && W == other.W; - } - - #endregion IEquatable Members - } -} diff --git a/Robust.Shared.Maths/Vector3.cs b/Robust.Shared.Maths/Vector3.cs deleted file mode 100644 index 8e18ee566..000000000 --- a/Robust.Shared.Maths/Vector3.cs +++ /dev/null @@ -1,1235 +0,0 @@ -#region --- License --- - -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. -Copyright 2013 Xamarin Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ - -#endregion - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Xml.Serialization; -using Robust.Shared.Utility; - -namespace Robust.Shared.Maths -{ - /// - /// Represents a 3D vector using three single-precision floating-point numbers. - /// - /// - /// The Vector3 structure is suitable for interoperation with unmanaged code requiring three consecutive floats. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector3 : - IEquatable, - ISpanFormattable, - IAdditionOperators, - ISubtractionOperators, - IMultiplyOperators, - IMultiplyOperators, - IComparisonOperators - { - #region Fields - - /// - /// The X component of the Vector3. - /// - public float X; - - /// - /// The Y component of the Vector3. - /// - public float Y; - - /// - /// The Z component of the Vector3. - /// - public float Z; - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(float value) - { - X = value; - Y = value; - Z = value; - } - - /// - /// Constructs a new Vector3. - /// - /// The x component of the Vector3. - /// The y component of the Vector3. - /// The z component of the Vector3. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(float x, float y, float z) - { - X = x; - Y = y; - Z = z; - } - - /// - /// Constructs a new Vector3 from the given Vector2. - /// - /// The Vector2 to copy components from. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(Vector2 v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - } - - /// - /// Constructs a new Vector3 from the given Vector3. - /// - /// The Vector3 to copy components from. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(Vector3 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - /// - /// Constructs a new Vector3 from the given Vector4. - /// - /// The Vector4 to copy components from. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3(Vector4 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Deconstruct(out float x, out float y, out float z) - { - x = X; - y = Y; - z = Z; - } - - #endregion - - #region Public Members - - #region Instance - - #region public float Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - public float Length - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); - } - #endregion - - #region public float LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - public float LengthSquared - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => X * X + Y * Y + Z * Z; - } - - #endregion - - #region public void Normalize() - - /// - /// Scales the Vector3 to unit length. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Normalize() - { - var scale = 1.0f / Length; - X *= scale; - Y *= scale; - Z *= scale; - } - - #endregion - - #endregion - - #region Static - - #region Fields - - /// - /// Defines a unit-length Vector3 that points towards the X-axis. - /// - public static readonly Vector3 UnitX = new(1, 0, 0); - - /// - /// Defines a unit-length Vector3 that points towards the Y-axis. - /// - public static readonly Vector3 UnitY = new(0, 1, 0); - - /// - /// /// Defines a unit-length Vector3 that points towards the Z-axis. - /// - public static readonly Vector3 UnitZ = new(0, 0, 1); - - /// - /// Defines a zero-length Vector3. - /// - public static readonly Vector3 Zero = new(0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector3 One = new(1, 1, 1); - - /// - /// Defines the size of the Vector3 struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector3()); - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Add(Vector3 a, Vector3 b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result = new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Subtract(Vector3 a, Vector3 b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Subtract(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result = new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Multiply(Vector3 vector, float scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Vector3 vector, float scale, out Vector3 result) - { - result = new Vector3(vector.X * scale, vector.Y * scale, vector.Z * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Multiply(Vector3 vector, Vector3 scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Vector3 vector, ref Vector3 scale, out Vector3 result) - { - result = new Vector3(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Divide(Vector3 vector, float scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Divide(ref Vector3 vector, float scale, out Vector3 result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Divide(Vector3 vector, Vector3 scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Divide(ref Vector3 vector, ref Vector3 scale, out Vector3 result) - { - result = new Vector3(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z); - } - - #endregion - - #region ComponentMin - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 ComponentMin(Vector3 a, Vector3 b) - { - a.X = MathF.Min(a.X, b.X); - a.Y = MathF.Min(a.Y, b.Y); - a.Z = MathF.Min(a.Z, b.Z); - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ComponentMin(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result.X = MathF.Min(a.X, b.X); - result.Y = MathF.Min(a.Y, b.Y); - result.Z = MathF.Min(a.Z, b.Z); - } - - #endregion - - #region ComponentMax - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 ComponentMax(Vector3 a, Vector3 b) - { - a.X = MathF.Max(a.X, b.X); - a.Y = MathF.Max(a.Y, b.Y); - a.Z = MathF.Max(a.Z, b.Z); - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ComponentMax(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result.X = MathF.Max(a.X, b.X); - result.Y = MathF.Max(a.Y, b.Y); - result.Z = MathF.Max(a.Z, b.Z); - } - - #endregion - - #region Min - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Min(Vector3 left, Vector3 right) - { - return left.LengthSquared < right.LengthSquared ? left : right; - } - - #endregion - - #region Max - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Max(Vector3 left, Vector3 right) - { - return left.LengthSquared >= right.LengthSquared ? left : right; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Clamp(Vector3 vec, Vector3 min, Vector3 max) - { - vec.X = MathHelper.Clamp(vec.X, min.X, max.X); - vec.Y = MathHelper.Clamp(vec.Y, min.Y, max.Y); - vec.Z = MathHelper.Clamp(vec.Z, min.Z, max.Z); - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Clamp(ref Vector3 vec, ref Vector3 min, ref Vector3 max, out Vector3 result) - { - result.X = MathHelper.Clamp(vec.X, min.X, max.X); - result.Y = MathHelper.Clamp(vec.Y, min.Y, max.Y); - result.Z = MathHelper.Clamp(vec.Z, min.Z, max.Z); - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Normalize(Vector3 vec) - { - var scale = 1.0f / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Normalize(ref Vector3 vec, out Vector3 result) - { - var scale = 1.0f / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Dot(Vector3 left, Vector3 right) - { - return left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - [MethodImpl(MethodImplOptions.AggressiveInlining)] - 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; - } - - #endregion - - #region Cross - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Cross(Vector3 left, Vector3 right) - { - Cross(ref left, ref right, out var result); - return result; - } - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - /// The cross product of the two inputs - [MethodImpl(MethodImplOptions.AggressiveInlining)] - 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); - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Lerp(Vector3 a, Vector3 b, float blend) - { - a.X = MathHelper.Lerp(a.X, b.X, blend); - a.Y = MathHelper.Lerp(a.Y, b.Y, blend); - a.Z = MathHelper.Lerp(a.Z, b.Z, blend); - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Lerp(ref Vector3 a, ref Vector3 b, float blend, out Vector3 result) - { - result.X = MathHelper.Lerp(a.X, b.X, blend); - result.Y = MathHelper.Lerp(a.Y, b.Y, blend); - result.Z = MathHelper.Lerp(a.Z, b.Z, blend); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 InterpolateCubic(Vector3 preA, Vector3 a, Vector3 b, Vector3 postB, float t) - { - return a + - (b - preA + (preA * 2.0f - a * 5.0f + b * 4.0f - postB + ((a - b) * 3.0f + postB - preA) * t) * t) * - t * 0.5f; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 BaryCentric(Vector3 a, Vector3 b, Vector3 c, float u, float v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void BaryCentric(ref Vector3 a, ref Vector3 b, ref Vector3 c, float u, float v, out Vector3 result) - { - result = a; // copy - - var temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 TransformVector(Vector3 vec, Matrix4 mat) - { - Vector3 v; - v.X = Dot(vec, new Vector3(mat.Column0)); - v.Y = Dot(vec, new Vector3(mat.Column1)); - v.Z = Dot(vec, new Vector3(mat.Column2)); - return v; - } - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void TransformVector(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - result.X = vec.X * mat.Row0.X + - vec.Y * mat.Row1.X + - vec.Z * mat.Row2.X; - - result.Y = vec.X * mat.Row0.Y + - vec.Y * mat.Row1.Y + - vec.Z * mat.Row2.Y; - - result.Z = vec.X * mat.Row0.Z + - vec.Y * mat.Row1.Z + - vec.Z * mat.Row2.Z; - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 TransformNormal(Vector3 norm, Matrix4 mat) - { - mat.Invert(); - return TransformNormalInverse(norm, mat); - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void TransformNormal(ref Vector3 norm, ref Matrix4 mat, out Vector3 result) - { - var inverse = Matrix4.Invert(mat); - TransformNormalInverse(ref norm, ref inverse, out result); - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 TransformNormalInverse(Vector3 norm, Matrix4 invMat) - { - Vector3 n; - n.X = Dot(norm, new Vector3(invMat.Row0)); - n.Y = Dot(norm, new Vector3(invMat.Row1)); - n.Z = Dot(norm, new Vector3(invMat.Row2)); - return n; - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void TransformNormalInverse(ref Vector3 norm, ref Matrix4 invMat, out Vector3 result) - { - result.X = norm.X * invMat.Row0.X + - norm.Y * invMat.Row0.Y + - norm.Z * invMat.Row0.Z; - - result.Y = norm.X * invMat.Row1.X + - norm.Y * invMat.Row1.Y + - norm.Z * invMat.Row1.Z; - - result.Z = norm.X * invMat.Row2.X + - norm.Y * invMat.Row2.Y + - norm.Z * invMat.Row2.Z; - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 TransformPosition(Vector3 pos, Matrix4 mat) - { - Vector3 p; - p.X = Dot(pos, new Vector3(mat.Column0)) + mat.Row3.X; - p.Y = Dot(pos, new Vector3(mat.Column1)) + mat.Row3.Y; - p.Z = Dot(pos, new Vector3(mat.Column2)) + mat.Row3.Z; - return p; - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void TransformPosition(ref Vector3 pos, ref Matrix4 mat, out Vector3 result) - { - result.X = pos.X * mat.Row0.X + - pos.Y * mat.Row1.X + - pos.Z * mat.Row2.X + - mat.Row3.X; - - result.Y = pos.X * mat.Row0.Y + - pos.Y * mat.Row1.Y + - pos.Z * mat.Row2.Y + - mat.Row3.Y; - - result.Z = pos.X * mat.Row0.Z + - pos.Y * mat.Row1.Z + - pos.Z * mat.Row2.Z + - mat.Row3.Z; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Transform(Vector3 vec, Matrix4 mat) - { - Transform(ref vec, ref mat, out Vector3 result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transform(ref Vector3 vec, ref Matrix4 mat, out Vector4 result) - { - var v4 = new Vector4(vec.X, vec.Y, vec.Z, 1.0f); - Vector4.Transform(ref v4, ref mat, out result); - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transform(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - var v4 = new Vector4(vec.X, vec.Y, vec.Z, 1.0f); - Vector4.Transform(ref v4, ref mat, out v4); - result = v4.Xyz; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Transform(Vector3 vec, Quaternion quat) - { - Transform(ref vec, ref quat, out var result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transform(ref Vector3 vec, ref Quaternion quat, out Vector3 result) - { - // Since vec.W == 0, we can optimize quat * vec * quat^-1 as follows: - // vec + 2.0 * cross(quat.xyz, cross(quat.xyz, vec) + quat.w * vec) - var xyz = quat.Xyz; - Cross(ref xyz, ref vec, out var temp); - Multiply(ref vec, quat.W, out var temp2); - Add(ref temp, ref temp2, out temp); - Cross(ref xyz, ref temp, out temp); - Multiply(ref temp, 2, out temp); - Add(ref vec, ref temp, out result); - } - - /// Transform a Vector3 by the given Matrix, and project the resulting Vector4 back to a Vector3 - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 TransformPerspective(Vector3 vec, Matrix4 mat) - { - TransformPerspective(ref vec, ref mat, out var result); - return result; - } - - /// Transform a Vector3 by the given Matrix, and project the resulting Vector4 back to a Vector3 - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void TransformPerspective(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - var v = new Vector4(vec, 1); - Vector4.Transform(ref v, ref mat, out v); - result.X = v.X / v.W; - result.Y = v.Y / v.W; - result.Z = v.Z / v.W; - } - - #endregion - - #region CalculateAngle - - /// - /// Calculates the angle (in radians) between two vectors. - /// - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float CalculateAngle(Vector3 first, Vector3 second) - { - return MathF.Acos(Dot(first, second) / (first.Length * second.Length)); - } - - /// Calculates the angle (in radians) between two vectors. - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CalculateAngle(ref Vector3 first, ref Vector3 second, out float result) - { - Dot(ref first, ref second, out var temp); - result = MathF.Acos(temp / (first.Length * second.Length)); - } - - #endregion - - #endregion - - #region Swizzle - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Xy - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(X, Y); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - X = value.X; - Y = value.Y; - } - } - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator +(Vector3 left, Vector3 right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator -(Vector3 left, Vector3 right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator -(Vector3 vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator *(Vector3 vec, float scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator *(float scale, Vector3 vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Component wise multiply two vectors. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator *(Vector3 a, Vector3 b) - { - return new(a.X * b.X, a.Y * b.Y, a.Z * b.Z); - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 operator /(Vector3 vec, float scale) - { - var mult = 1.0f / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector3 left, Vector3 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equa lright; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Vector3 left, Vector3 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Vector3. - /// - /// - public readonly override string ToString() - { - return $"({X}, {Y}, {Z})"; - } - - public readonly string ToString(string? format, IFormatProvider? formatProvider) - { - return ToString(); - } - - public readonly bool TryFormat( - Span destination, - out int charsWritten, - ReadOnlySpan format, - IFormatProvider? provider) - { - return FormatHelpers.TryFormatInto( - destination, - out charsWritten, - $"({X}, {Y}, {Z})"); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object? obj) - { - if (!(obj is Vector3)) - return false; - - return Equals((Vector3) obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector3 other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z; - } - - #endregion - - public static bool operator >(Vector3 left, Vector3 right) - { - return left.LengthSquared > right.LengthSquared; - } - - public static bool operator >=(Vector3 left, Vector3 right) - { - return left.LengthSquared >= right.LengthSquared; - } - - public static bool operator <(Vector3 left, Vector3 right) - { - return left.LengthSquared < right.LengthSquared; - } - - public static bool operator <=(Vector3 left, Vector3 right) - { - return left.LengthSquared <= right.LengthSquared; - } - } -} diff --git a/Robust.Shared.Maths/Vector3d.cs b/Robust.Shared.Maths/Vector3d.cs index 23f7f1dd1..5d17e7898 100644 --- a/Robust.Shared.Maths/Vector3d.cs +++ b/Robust.Shared.Maths/Vector3d.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using System.Runtime.InteropServices; namespace Robust.Shared.Maths diff --git a/Robust.Shared.Maths/Vector4.cs b/Robust.Shared.Maths/Vector4.cs deleted file mode 100644 index f1efce03c..000000000 --- a/Robust.Shared.Maths/Vector4.cs +++ /dev/null @@ -1,1022 +0,0 @@ -#region --- License --- - -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ - -#endregion --- License --- - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Xml.Serialization; -using Robust.Shared.Utility; -using Vector2 = System.Numerics.Vector2; -using System.Numerics; - -namespace Robust.Shared.Maths -{ - /// Represents a 4D vector using four single-precision floating-point numbers. - /// - /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector4 : - IEquatable, - ISpanFormattable, - IAdditionOperators, - ISubtractionOperators, - IMultiplyOperators, - IComparisonOperators - { - #region Fields - - /// - /// The X component of the Vector4. - /// - public float X; - - /// - /// The Y component of the Vector4. - /// - public float Y; - - /// - /// The Z component of the Vector4. - /// - public float Z; - - /// - /// The W component of the Vector4. - /// - public float W; - - /// - /// Defines a unit-length Vector4 that points towards the X-axis. - /// - public static readonly Vector4 UnitX = new(1, 0, 0, 0); - - /// - /// Defines a unit-length Vector4 that points towards the Y-axis. - /// - public static readonly Vector4 UnitY = new(0, 1, 0, 0); - - /// - /// Defines a unit-length Vector4 that points towards the Z-axis. - /// - public static readonly Vector4 UnitZ = new(0, 0, 1, 0); - - /// - /// Defines a unit-length Vector4 that points towards the W-axis. - /// - public static readonly Vector4 UnitW = new(0, 0, 0, 1); - - /// - /// Defines a zero-length Vector4. - /// - public static readonly Vector4 Zero = new(0, 0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector4 One = new(1, 1, 1, 1); - - /// - /// Defines the size of the Vector4 struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4()); - - #endregion Fields - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(float value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Constructs a new Vector4. - /// - /// The x component of the Vector4. - /// The y component of the Vector4. - /// The z component of the Vector4. - /// The w component of the Vector4. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - /// - /// Constructs a new Vector4 from the given Vector2. - /// - /// The Vector2 to copy components from. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(Vector2 v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - W = 0.0f; - } - - /// - /// Constructs a new Vector4 from the given Vector3. - /// The w component is initialized to 0. - /// - /// The Vector3 to copy components from. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(Vector3 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = 0.0f; - } - - /// - /// Constructs a new Vector4 from the specified Vector3 and w component. - /// - /// The Vector3 to copy components from. - /// The w component of the new Vector4. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(Vector3 v, float w) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = w; - } - - /// - /// Constructs a new Vector4 from the given Vector4. - /// - /// The Vector4 to copy components from. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4(Vector4 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = v.W; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Deconstruct(out float x, out float y, out float z, out float w) - { - x = X; - y = Y; - z = Z; - w = W; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector4((float x, float y, float z, float w) tuple) - { - var (x, y, z, w) = tuple; - return new Vector4(x, y, z, w); - } - - #endregion Constructors - - #region Public Members - - #region Instance - - #region public float Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - public float Length - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); - } - - #endregion public float Length - - #region public float LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - public float LengthSquared - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => X * X + Y * Y + Z * Z + W * W; - } - - #endregion public float LengthSquared - - #region public void Normalize() - - /// - /// Scales the Vector4 to unit length. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Normalize() - { - var scale = 1.0f / Length; - X *= scale; - Y *= scale; - Z *= scale; - W *= scale; - } - - #endregion public void Normalize() - - #endregion Instance - - #region Static - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Add(Vector4 a, Vector4 b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result = new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); - } - - #endregion Add - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Subtract(Vector4 a, Vector4 b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result = new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); - } - - #endregion Subtract - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Multiply(Vector4 vector, float scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Vector4 vector, float scale, out Vector4 result) - { - result = new Vector4(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Multiply(Vector4 vector, Vector4 scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result) - { - result = new Vector4(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W); - } - - #endregion Multiply - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Divide(Vector4 vector, float scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Divide(ref Vector4 vector, float scale, out Vector4 result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Divide(Vector4 vector, Vector4 scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result) - { - result = new Vector4(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W); - } - - #endregion Divide - - #region Min - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Min(Vector4 a, Vector4 b) - { - a.X = MathF.Min(a.X, b.X); - a.Y = MathF.Min(a.Y, b.Y); - a.Z = MathF.Min(a.Z, b.Z); - a.W = MathF.Min(a.W, b.W); - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result.X = MathF.Min(a.X, b.X); - result.Y = MathF.Min(a.Y, b.Y); - result.Z = MathF.Min(a.Z, b.Z); - result.W = MathF.Min(a.W, b.W); - } - - #endregion Min - - #region Max - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Max(Vector4 a, Vector4 b) - { - a.X = MathF.Max(a.X, b.X); - a.Y = MathF.Max(a.Y, b.Y); - a.Z = MathF.Max(a.Z, b.Z); - a.W = MathF.Max(a.W, b.W); - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result.X = MathF.Max(a.X, b.X); - result.Y = MathF.Max(a.Y, b.Y); - result.Z = MathF.Max(a.Z, b.Z); - result.W = MathF.Max(a.W, b.W); - } - - #endregion Max - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max) - { - vec.X = MathHelper.Clamp( vec.X, min.X, max.X ); - vec.Y = MathHelper.Clamp( vec.Y, min.Y, max.Y ); - vec.Z = MathHelper.Clamp( vec.Z, min.Z, max.Z ); - vec.W = MathHelper.Clamp( vec.W, min.W, max.W ); - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result) - { - result.X = MathHelper.Clamp( vec.X, min.X, max.X ); - result.Y = MathHelper.Clamp( vec.Y, min.Y, max.Y ); - result.Z = MathHelper.Clamp( vec.Z, min.Z, max.Z ); - result.W = MathHelper.Clamp( vec.W, min.W, max.W ); - } - - #endregion Clamp - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Normalize(Vector4 vec) - { - var scale = 1.0f / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Normalize(ref Vector4 vec, out Vector4 result) - { - var scale = 1.0f / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - result.W = vec.W * scale; - } - - #endregion Normalize - - #region Dot - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - [MethodImpl(MethodImplOptions.AggressiveInlining)] - 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; - } - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector4 left, ref Vector4 right, out float result) - { - result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W; - } - - #endregion Dot - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Lerp(Vector4 a, Vector4 b, float blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - a.Z = blend * (b.Z - a.Z) + a.Z; - a.W = blend * (b.W - a.W) + a.W; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result) - { - result.X = MathHelper.Lerp(a.X, b.X, blend); - result.Y = MathHelper.Lerp(a.Y, b.Y, blend); - result.Z = MathHelper.Lerp(a.Z, b.Z, blend); - result.W = MathHelper.Lerp(a.W, b.W, blend); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 InterpolateCubic(Vector4 preA, Vector4 a, Vector4 b, Vector4 postB, float t) - { - return a + - (b - preA + (preA * 2.0f - a * 5.0f + b * 4.0f - postB + ((a - b) * 3.0f + postB - preA) * t) * t) * - t * 0.5f; - } - - #endregion Lerp - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result) - { - result = a; // copy - - var temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion Barycentric - - #region Transform - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Transform(Vector4 vec, Matrix4 mat) - { - Transform(ref vec, ref mat, out var result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result) - { - result = new Vector4( - vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X, - vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y, - vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z, - vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W); - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 Transform(Vector4 vec, Quaternion quat) - { - Transform(ref vec, ref quat, out var result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result) - { - var v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W); - Quaternion.Invert(ref quat, out var i); - Quaternion.Multiply(ref quat, ref v, out var t); - Quaternion.Multiply(ref t, ref i, out v); - - result = new Vector4(v.X, v.Y, v.Z, v.W); - } - - #endregion Transform - - #endregion Static - - #region Swizzle - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Xy - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(X, Y); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - X = value.X; - Y = value.Y; - } - } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Xyz - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(X, Y, Z); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - X = value.X; - Y = value.Y; - Z = value.Z; - } - } - - #endregion Swizzle - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator +(Vector4 left, Vector4 right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator -(Vector4 left, Vector4 right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - left.W -= right.W; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator -(Vector4 vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - vec.W = -vec.W; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator *(Vector4 vec, float scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator *(float scale, Vector4 vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector4 operator /(Vector4 vec, float scale) - { - var mult = 1.0f / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - vec.W *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector4 left, Vector4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Vector4 left, Vector4 right) - { - return !left.Equals(right); - } - - #endregion Operators - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Vector4. - /// - /// - public readonly override string ToString() - { - return $"({X}, {Y}, {Z}, {W})"; - } - - public readonly string ToString(string? format, IFormatProvider? formatProvider) - { - return ToString(); - } - - public readonly bool TryFormat( - Span destination, - out int charsWritten, - ReadOnlySpan format, - IFormatProvider? provider) - { - return FormatHelpers.TryFormatInto( - destination, - out charsWritten, - $"({X}, {Y}, {Z}, {W})"); - } - - #endregion public override string ToString() - - #region public override int GetHashCode() - - /// - /// Returns the hash code for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); - } - - #endregion public override int GetHashCode() - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object? obj) - { - if (!(obj is Vector4)) - return false; - - return Equals((Vector4) obj); - } - - #endregion public override bool Equals(object obj) - - #endregion Overrides - - #endregion Public Members - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector4 other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z && - W == other.W; - } - - #endregion IEquatable Members - - public static Vector4 operator *(Vector4 left, Vector4 right) - { - return new(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W); - } - - public static bool operator >(Vector4 left, Vector4 right) - { - return left.LengthSquared > right.LengthSquared; - } - - public static bool operator >=(Vector4 left, Vector4 right) - { - return left.LengthSquared >= right.LengthSquared; - } - - public static bool operator <(Vector4 left, Vector4 right) - { - return left.LengthSquared < right.LengthSquared; - } - - public static bool operator <=(Vector4 left, Vector4 right) - { - return left.LengthSquared <= right.LengthSquared; - } - } -} diff --git a/Robust.Shared.Maths/Vector4d.cs b/Robust.Shared.Maths/Vector4d.cs index 246d4e297..cb1ff7c86 100644 --- a/Robust.Shared.Maths/Vector4d.cs +++ b/Robust.Shared.Maths/Vector4d.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using System.Runtime.InteropServices; namespace Robust.Shared.Maths diff --git a/Robust.Shared.Maths/VectorHelpers.cs b/Robust.Shared.Maths/VectorHelpers.cs new file mode 100644 index 000000000..77bf349a6 --- /dev/null +++ b/Robust.Shared.Maths/VectorHelpers.cs @@ -0,0 +1,31 @@ +using System.Numerics; + +namespace Robust.Shared.Maths; + +public static class VectorHelpers +{ + public static Vector3 InterpolateCubic(Vector3 preA, Vector3 a, Vector3 b, Vector3 postB, float t) + { + return a + (b - preA + (preA * 2.0f - a * 5.0f + b * 4.0f - postB + ((a - b) * 3.0f + postB - preA) * t) * t) * t * 0.5f; + } + + public static Vector4 InterpolateCubic(Vector4 preA, Vector4 a, Vector4 b, Vector4 postB, float t) + { + return a + (b - preA + (preA * 2.0f - a * 5.0f + b * 4.0f - postB + ((a - b) * 3.0f + postB - preA) * t) * t) * t * 0.5f; + } + + public static void Deconstruct(this Vector3 vector, out float x, out float y, out float z) + { + x = vector.X; + y = vector.Y; + z = vector.Z; + } + + public static void Deconstruct(this Vector4 vector, out float x, out float y, out float z, out float w) + { + x = vector.X; + y = vector.Y; + z = vector.Z; + w = vector.W; + } +} diff --git a/Robust.Shared/Audio/AudioPresetPrototype.cs b/Robust.Shared/Audio/AudioPresetPrototype.cs index 092b1b11c..5a6d85882 100644 --- a/Robust.Shared/Audio/AudioPresetPrototype.cs +++ b/Robust.Shared/Audio/AudioPresetPrototype.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; diff --git a/Robust.Shared/Audio/Components/AudioEffectComponent.cs b/Robust.Shared/Audio/Components/AudioEffectComponent.cs index 4ce5bf716..e64d09e5e 100644 --- a/Robust.Shared/Audio/Components/AudioEffectComponent.cs +++ b/Robust.Shared/Audio/Components/AudioEffectComponent.cs @@ -1,9 +1,8 @@ -using System; +using System.Numerics; using Robust.Shared.Audio.Effects; using Robust.Shared.Audio.Systems; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; -using Robust.Shared.Maths; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; diff --git a/Robust.Shared/Audio/Effects/DummyAudioEffect.cs b/Robust.Shared/Audio/Effects/DummyAudioEffect.cs index 1c90d3c32..d6970ac6a 100644 --- a/Robust.Shared/Audio/Effects/DummyAudioEffect.cs +++ b/Robust.Shared/Audio/Effects/DummyAudioEffect.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Shared.Audio.Components; using Robust.Shared.Maths; diff --git a/Robust.Shared/Audio/Effects/IAudioEffect.cs b/Robust.Shared/Audio/Effects/IAudioEffect.cs index 556bf33ce..4b5cdcaba 100644 --- a/Robust.Shared/Audio/Effects/IAudioEffect.cs +++ b/Robust.Shared/Audio/Effects/IAudioEffect.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using Robust.Shared.Maths; namespace Robust.Shared.Audio.Effects; diff --git a/Robust.Shared/Audio/Effects/ReverbPresets.cs b/Robust.Shared/Audio/Effects/ReverbPresets.cs index c94eedb1f..649ec99bb 100644 --- a/Robust.Shared/Audio/Effects/ReverbPresets.cs +++ b/Robust.Shared/Audio/Effects/ReverbPresets.cs @@ -8,6 +8,7 @@ // +using System.Numerics; using Robust.Shared.Maths; namespace Robust.Shared.Audio.Effects; diff --git a/Robust.Shared/Audio/Effects/ReverbProperties.cs b/Robust.Shared/Audio/Effects/ReverbProperties.cs index 508cf1893..217de7ddd 100644 --- a/Robust.Shared/Audio/Effects/ReverbProperties.cs +++ b/Robust.Shared/Audio/Effects/ReverbProperties.cs @@ -7,6 +7,7 @@ // of the MIT license. See the LICENSE file for details. // +using System.Numerics; using Robust.Shared.Maths; namespace Robust.Shared.Audio.Effects; diff --git a/Robust.Shared/ColorNaming/ColorNaming.cs b/Robust.Shared/ColorNaming/ColorNaming.cs index 27da31a7e..210709798 100644 --- a/Robust.Shared/ColorNaming/ColorNaming.cs +++ b/Robust.Shared/ColorNaming/ColorNaming.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using Robust.Shared.Localization; using Robust.Shared.Maths; diff --git a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Load.cs b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Load.cs index 7bfd34b80..f62000e4c 100644 --- a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Load.cs +++ b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.Load.cs @@ -13,7 +13,6 @@ using Robust.Shared.Maths; using Robust.Shared.Serialization.Markdown; using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Utility; -using Vector2 = System.Numerics.Vector2; namespace Robust.Shared.EntitySerialization.Systems; diff --git a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.LoadMap.cs b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.LoadMap.cs index 83cbfb407..53a029d4e 100644 --- a/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.LoadMap.cs +++ b/Robust.Shared/EntitySerialization/Systems/MapLoaderSystem.LoadMap.cs @@ -8,7 +8,6 @@ using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Maths; using Robust.Shared.Utility; -using Vector2 = System.Numerics.Vector2; namespace Robust.Shared.EntitySerialization.Systems; diff --git a/Robust.Shared/Noise/NoiseGenerator.cs b/Robust.Shared/Noise/NoiseGenerator.cs index b3175e47d..bfc534fe9 100644 --- a/Robust.Shared/Noise/NoiseGenerator.cs +++ b/Robust.Shared/Noise/NoiseGenerator.cs @@ -1,8 +1,6 @@ using System; using System.Numerics; using JetBrains.Annotations; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Shared.Noise { diff --git a/Robust.Shared/Physics/Dynamics/Joints/PrismaticJoint.cs b/Robust.Shared/Physics/Dynamics/Joints/PrismaticJoint.cs index 0ac75770a..c7e4c4ac8 100644 --- a/Robust.Shared/Physics/Dynamics/Joints/PrismaticJoint.cs +++ b/Robust.Shared/Physics/Dynamics/Joints/PrismaticJoint.cs @@ -30,7 +30,6 @@ using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; -using Vector3 = Robust.Shared.Maths.Vector3; namespace Robust.Shared.Physics.Dynamics.Joints; // Linear constraint (point-to-line) diff --git a/Robust.Shared/Physics/Dynamics/Joints/WeldJoint.cs b/Robust.Shared/Physics/Dynamics/Joints/WeldJoint.cs index cdda94af9..027f9b8e1 100644 --- a/Robust.Shared/Physics/Dynamics/Joints/WeldJoint.cs +++ b/Robust.Shared/Physics/Dynamics/Joints/WeldJoint.cs @@ -6,7 +6,6 @@ using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; -using Vector3 = Robust.Shared.Maths.Vector3; namespace Robust.Shared.Physics.Dynamics.Joints; diff --git a/Robust.Shared/Serialization/Matrix3x2Serializer.cs b/Robust.Shared/Serialization/Matrix3x2Serializer.cs deleted file mode 100644 index 3f84dd3a2..000000000 --- a/Robust.Shared/Serialization/Matrix3x2Serializer.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Numerics; -using System.Reflection; -using System.Reflection.Emit; -using NetSerializer; - -namespace Robust.Shared.Serialization; - -internal sealed class Matrix3x2Serializer : IStaticTypeSerializer -{ - public bool Handles(Type type) - { - return type == typeof(Matrix3x2); - } - - public IEnumerable GetSubtypes(Type type) - { - return Type.EmptyTypes; - } - - public MethodInfo GetStaticWriter(Type type) - { - return typeof(Matrix3x2Serializer).GetMethod("WritePrimitive", - BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, - new Type[] { typeof(Stream), type }, null)!; - } - - public MethodInfo GetStaticReader(Type type) - { - return typeof(Matrix3x2Serializer).GetMethod("ReadPrimitive", - BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, - new Type[] { typeof(Stream), type.MakeByRefType() }, null)!; - } - - public static void WritePrimitive(Stream stream, Matrix3x2 value) - { - Primitives.WritePrimitive(stream, value.M11); - Primitives.WritePrimitive(stream, value.M12); - Primitives.WritePrimitive(stream, value.M21); - Primitives.WritePrimitive(stream, value.M22); - Primitives.WritePrimitive(stream, value.M31); - Primitives.WritePrimitive(stream, value.M32); - } - - public static void ReadPrimitive(Stream stream, out Matrix3x2 value) - { - Span buf = stackalloc float[6]; - for (int i = 0; i < 6; i++) - { - Primitives.ReadPrimitive(stream, out buf[i]); - } - value = new Matrix3x2(buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - } -} diff --git a/Robust.Shared/Serialization/NetMathSerializers.cs b/Robust.Shared/Serialization/NetMathSerializers.cs new file mode 100644 index 000000000..046fc4fb0 --- /dev/null +++ b/Robust.Shared/Serialization/NetMathSerializers.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Numerics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using NetSerializer; + +namespace Robust.Shared.Serialization; + +internal sealed class NetMathSerializer : IStaticTypeSerializer +{ + public bool Handles(Type type) + { + return type == typeof(Vector2) + || type == typeof(Vector3) + || type == typeof(Vector4) + || type == typeof(Quaternion) + || type == typeof(Matrix4x4) + || type == typeof(Matrix3x2); + } + + public IEnumerable GetSubtypes(Type type) + { + return Type.EmptyTypes; + } + + public MethodInfo GetStaticWriter(Type type) + { + return typeof(NetMathSerializer) + .GetMethod(nameof(WriteFloatObject), BindingFlags.Static | BindingFlags.Public)! + .MakeGenericMethod(type); + } + + public MethodInfo GetStaticReader(Type type) + { + return typeof(NetMathSerializer) + .GetMethod(nameof(ReadFloatObject), BindingFlags.Static | BindingFlags.Public)! + .MakeGenericMethod(type); + } + + public static void WriteFloatObject(Stream stream, T value) where T : unmanaged + { + var floatSpan = MemoryMarshal.Cast(new Span(ref value)); + foreach (var f in floatSpan) + { + Primitives.WritePrimitive(stream, f); + } + } + + public static void ReadFloatObject(Stream stream, out T value) where T : unmanaged + { + Unsafe.SkipInit(out value); + var floatSpan = MemoryMarshal.Cast(new Span(ref value)); + for (var i = 0; i < floatSpan.Length; i++) + { + Primitives.ReadPrimitive(stream, out floatSpan[i]); + } + } +} diff --git a/Robust.Shared/Serialization/RobustSerializer.cs b/Robust.Shared/Serialization/RobustSerializer.cs index 860a9fb38..893096dc7 100644 --- a/Robust.Shared/Serialization/RobustSerializer.cs +++ b/Robust.Shared/Serialization/RobustSerializer.cs @@ -89,8 +89,7 @@ namespace Robust.Shared.Serialization CustomTypeSerializers = new[] { MappedStringSerializer.TypeSerializer, - new Vector2Serializer(), - new Matrix3x2Serializer(), + new NetMathSerializer() } }; _serializer = new Serializer(types, settings); diff --git a/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector3Serializer.cs b/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector3Serializer.cs index 05eb3dc5f..dc19ad6aa 100644 --- a/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector3Serializer.cs +++ b/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector3Serializer.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Numerics; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Serialization.Manager; @@ -59,7 +60,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations public Vector3 CreateCopy(ISerializationManager serializationManager, Vector3 source, IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null) { - return new(source); + return source; } } } diff --git a/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector4Serializer.cs b/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector4Serializer.cs index da7eb3e85..c727803db 100644 --- a/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector4Serializer.cs +++ b/Robust.Shared/Serialization/TypeSerializers/Implementations/Vector4Serializer.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.Numerics; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Serialization.Manager; @@ -63,7 +64,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations public Vector4 CreateCopy(ISerializationManager serializationManager, Vector4 source, IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null) { - return new(source); + return source; } } } diff --git a/Robust.Shared/Serialization/Vector2Serializer.cs b/Robust.Shared/Serialization/Vector2Serializer.cs deleted file mode 100644 index c06f494f1..000000000 --- a/Robust.Shared/Serialization/Vector2Serializer.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Numerics; -using System.Reflection; -using System.Reflection.Emit; -using NetSerializer; - -namespace Robust.Shared.Serialization; - -internal sealed class Vector2Serializer : IStaticTypeSerializer -{ - public bool Handles(Type type) - { - return type == typeof(Vector2); - } - - public IEnumerable GetSubtypes(Type type) - { - return Type.EmptyTypes; - } - - public MethodInfo GetStaticWriter(Type type) - { - return typeof(Vector2Serializer).GetMethod("WritePrimitive", - BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, - new Type[] { typeof(Stream), type }, null)!; - } - - public MethodInfo GetStaticReader(Type type) - { - return typeof(Vector2Serializer).GetMethod("ReadPrimitive", - BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, - new Type[] { typeof(Stream), type.MakeByRefType() }, null)!; - } - - public static void WritePrimitive(Stream stream, Vector2 value) - { - Primitives.WritePrimitive(stream, value.X); - Primitives.WritePrimitive(stream, value.Y); - } - - public static void ReadPrimitive(Stream stream, out Vector2 value) - { - Primitives.ReadPrimitive(stream, out float x); - Primitives.ReadPrimitive(stream, out float y); - value = new Vector2(x, y); - } -} diff --git a/Robust.Shared/Toolshed/TypeParsers/Math/Vector3TypeParser.cs b/Robust.Shared/Toolshed/TypeParsers/Math/Vector3TypeParser.cs index 619f5aca4..5bc3f9f13 100644 --- a/Robust.Shared/Toolshed/TypeParsers/Math/Vector3TypeParser.cs +++ b/Robust.Shared/Toolshed/TypeParsers/Math/Vector3TypeParser.cs @@ -1,12 +1,13 @@ using System; +using System.Numerics; namespace Robust.Shared.Toolshed.TypeParsers.Math; -internal sealed class Vector3TypeParser : SpanLikeTypeParser +internal sealed class Vector3TypeParser : SpanLikeTypeParser { public override int Elements => 3; - public override Maths.Vector3 Create(Span elements) + public override Vector3 Create(Span elements) { - return new Maths.Vector3(elements[0], elements[1], elements[2]); + return new Vector3(elements[0], elements[1], elements[2]); } -} \ No newline at end of file +} diff --git a/Robust.Shared/Toolshed/TypeParsers/Math/Vector4TypeParser.cs b/Robust.Shared/Toolshed/TypeParsers/Math/Vector4TypeParser.cs index 2e6f9ef8e..831c99cfd 100644 --- a/Robust.Shared/Toolshed/TypeParsers/Math/Vector4TypeParser.cs +++ b/Robust.Shared/Toolshed/TypeParsers/Math/Vector4TypeParser.cs @@ -1,12 +1,13 @@ using System; +using System.Numerics; namespace Robust.Shared.Toolshed.TypeParsers.Math; -internal sealed class Vector4TypeParser : SpanLikeTypeParser +internal sealed class Vector4TypeParser : SpanLikeTypeParser { public override int Elements => 4; - public override Maths.Vector4 Create(Span elements) + public override Vector4 Create(Span elements) { - return new Maths.Vector4(elements[0], elements[1], elements[2], elements[4]); + return new Vector4(elements[0], elements[1], elements[2], elements[4]); } -} \ No newline at end of file +} diff --git a/Robust.Shared/Utility/YamlHelpers.cs b/Robust.Shared/Utility/YamlHelpers.cs index da11dc5bd..40d678dbf 100644 --- a/Robust.Shared/Utility/YamlHelpers.cs +++ b/Robust.Shared/Utility/YamlHelpers.cs @@ -8,8 +8,6 @@ using System.Linq; using System.Numerics; using System.Threading; using YamlDotNet.RepresentationModel; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.Shared.Utility { @@ -123,25 +121,35 @@ namespace Robust.Shared.Utility } [Pure] - public static Matrix4 AsMatrix4(this YamlNode node) + public static Matrix4x4 AsMatrix4(this YamlNode node) { string raw = AsString(node); string[] args = raw.Split(','); if (args.Length != 16) { - throw new ArgumentException(string.Format("Could not parse {0}: '{1}'", nameof(Matrix4), raw)); - } - Vector4[] vectorBlocks = new Vector4[4]; - for(var i = 0; i < 16; i += 4) { - vectorBlocks.Append(new Vector4( - float.Parse(args[0 + i], CultureInfo.InvariantCulture), - float.Parse(args[1 + i], CultureInfo.InvariantCulture), - float.Parse(args[2 + i], CultureInfo.InvariantCulture), - float.Parse(args[3 + i], CultureInfo.InvariantCulture) - )); + throw new ArgumentException(string.Format("Could not parse {0}: '{1}'", nameof(Matrix4x4), raw)); } - return new Matrix4(vectorBlocks[0],vectorBlocks[1],vectorBlocks[2],vectorBlocks[3]); + // What, you know a better way to do this? + + var m11 = Parse.Float(args[0]); + var m12 = Parse.Float(args[1]); + var m13 = Parse.Float(args[2]); + var m14 = Parse.Float(args[3]); + var m21 = Parse.Float(args[4]); + var m22 = Parse.Float(args[5]); + var m23 = Parse.Float(args[6]); + var m24 = Parse.Float(args[7]); + var m31 = Parse.Float(args[8]); + var m32 = Parse.Float(args[9]); + var m33 = Parse.Float(args[10]); + var m34 = Parse.Float(args[11]); + var m41 = Parse.Float(args[12]); + var m42 = Parse.Float(args[13]); + var m43 = Parse.Float(args[14]); + var m44 = Parse.Float(args[15]); + + return new Matrix4x4(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); } [Pure] diff --git a/Robust.UnitTesting/Shared/Maths/Matrix3_Test.cs b/Robust.UnitTesting/Shared/Maths/Matrix3_Test.cs index ff668753b..a6016f3a6 100644 --- a/Robust.UnitTesting/Shared/Maths/Matrix3_Test.cs +++ b/Robust.UnitTesting/Shared/Maths/Matrix3_Test.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Numerics; using NUnit.Framework; using Robust.Shared.Maths; -using Vector3 = Robust.Shared.Maths.Vector3; namespace Robust.UnitTesting.Shared.Maths { diff --git a/Robust.UnitTesting/Shared/Prototypes/PrototypeManager_Test.cs b/Robust.UnitTesting/Shared/Prototypes/PrototypeManager_Test.cs index c0b65be7a..7d16de150 100644 --- a/Robust.UnitTesting/Shared/Prototypes/PrototypeManager_Test.cs +++ b/Robust.UnitTesting/Shared/Prototypes/PrototypeManager_Test.cs @@ -10,8 +10,6 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; -using Vector3 = Robust.Shared.Maths.Vector3; -using Vector4 = Robust.Shared.Maths.Vector4; namespace Robust.UnitTesting.Shared.Prototypes { diff --git a/Robust.UnitTesting/Shared/Serialization/NetSerializer_Test.cs b/Robust.UnitTesting/Shared/Serialization/NetSerializer_Test.cs index 5d2c15b18..35dfaec62 100644 --- a/Robust.UnitTesting/Shared/Serialization/NetSerializer_Test.cs +++ b/Robust.UnitTesting/Shared/Serialization/NetSerializer_Test.cs @@ -111,7 +111,7 @@ namespace Robust.UnitTesting.Shared.Serialization { CustomTypeSerializers = new ITypeSerializer[] { - new Vector2Serializer(), + new NetMathSerializer(), } }); var stream = new MemoryStream(); diff --git a/Robust.UnitTesting/Shared/Toolshed/ToolshedParserTest.Core.cs b/Robust.UnitTesting/Shared/Toolshed/ToolshedParserTest.Core.cs index 824c82730..0364c0d40 100644 --- a/Robust.UnitTesting/Shared/Toolshed/ToolshedParserTest.Core.cs +++ b/Robust.UnitTesting/Shared/Toolshed/ToolshedParserTest.Core.cs @@ -44,8 +44,8 @@ public sealed partial class ToolshedParserTest // maff AssertParseable(); AssertParseable(); - AssertParseable(); - AssertParseable(); + AssertParseable(); + AssertParseable(); AssertParseable(); AssertParseable(); AssertParseable();