Use CannyFastMath & Update Some Packages (#1130)

update a bunch of packages and use JetBrains.Annotations as private asset as needed

mark some hot math methods agg inline to benefit from loop opts

use FMA for interp

use canny min/max/clamp

make Quaternion NormalizeAngle fixed time and faster

clean up YamlDotNet references
This commit is contained in:
Tyler Young
2020-06-17 20:25:36 -04:00
committed by GitHub
parent af249f80c8
commit 9cbdd1058c
39 changed files with 816 additions and 215 deletions

View File

@@ -20,6 +20,8 @@ using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Client.GameStates
{

View File

@@ -4,6 +4,8 @@ using Robust.Client.Graphics.Drawing;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Client.Placement.Modes
{
@@ -28,8 +30,8 @@ namespace Robust.Client.Placement.Modes
var position = pManager.eyeManager.ScreenToMap(Vector2.Zero);
var gridstartx = (float) Math.Round(position.X / snapSize, MidpointRounding.AwayFromZero) * snapSize;
var gridstarty = (float) Math.Round(position.Y / snapSize, MidpointRounding.AwayFromZero) * snapSize;
var gridstartx = (float) MathF.Round(position.X / snapSize, MidpointRounding.AwayFromZero) * snapSize;
var gridstarty = (float) MathF.Round(position.Y / snapSize, MidpointRounding.AwayFromZero) * snapSize;
var gridstart = pManager.eyeManager.WorldToScreen(
new Vector2( //Find snap grid closest to screen origin and convert back to screen coords
gridstartx,
@@ -64,8 +66,8 @@ namespace Robust.Client.Placement.Modes
onGrid = true;
var mouselocal = new Vector2( //Round local coordinates onto the snap grid
(float) Math.Round(MouseCoords.X / (double) snapSize, MidpointRounding.AwayFromZero) * snapSize,
(float) Math.Round(MouseCoords.Y / (double) snapSize, MidpointRounding.AwayFromZero) * snapSize);
(float) MathF.Round(MouseCoords.X / snapSize, MidpointRounding.AwayFromZero) * snapSize,
(float) MathF.Round(MouseCoords.Y / snapSize, MidpointRounding.AwayFromZero) * snapSize);
//Convert back to original world and screen coordinates after applying offset
MouseCoords =

View File

@@ -25,8 +25,8 @@ namespace Robust.Client.Placement.Modes
var position = pManager.eyeManager.ScreenToMap(Vector2.Zero);
var gridstart = pManager.eyeManager.WorldToScreen(new Vector2( //Find snap grid closest to screen origin and convert back to screen coords
(float)(Math.Round(position.X / snapSize - 0.5f, MidpointRounding.AwayFromZero) + 0.5f) * snapSize,
(float)(Math.Round(position.Y / snapSize - 0.5f, MidpointRounding.AwayFromZero) + 0.5f) * snapSize));
(float)(MathF.Round(position.X / snapSize - 0.5f, MidpointRounding.AwayFromZero) + 0.5f) * snapSize,
(float)(MathF.Round(position.Y / snapSize - 0.5f, MidpointRounding.AwayFromZero) + 0.5f) * snapSize));
for (var a = gridstart.X; a < viewportSize.X; a += snapSize * 32) //Iterate through screen creating gridlines
{
var from = ScreenToWorld(new Vector2(a, 0));
@@ -54,8 +54,8 @@ namespace Robust.Client.Placement.Modes
onGrid = true;
var mouseLocal = new Vector2( //Round local coordinates onto the snap grid
(float)(Math.Round((MouseCoords.Position.X / (double)snapSize - 0.5f), MidpointRounding.AwayFromZero) + 0.5) * snapSize,
(float)(Math.Round((MouseCoords.Position.Y / (double)snapSize - 0.5f), MidpointRounding.AwayFromZero) + 0.5) * snapSize);
(float)(MathF.Round((MouseCoords.Position.X / snapSize - 0.5f), MidpointRounding.AwayFromZero) + 0.5) * snapSize,
(float)(MathF.Round((MouseCoords.Position.Y / snapSize - 0.5f), MidpointRounding.AwayFromZero) + 0.5) * snapSize);
//Adjust mouseCoords to new calculated position
MouseCoords = new GridCoordinates(mouseLocal + new Vector2(pManager.PlacementOffset.X, pManager.PlacementOffset.Y), MouseCoords.GridID);

View File

@@ -14,21 +14,20 @@
</PropertyGroup>
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Include="DiscordRichPresence" Version="1.0.147" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
<PackageReference Include="nfluidsynth" Version="0.3.0" />
<PackageReference Include="NVorbis" Version="0.9.1" />
<PackageReference Include="NVorbis" Version="0.10.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NJsonSchema" Version="10.1.4" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-rc0002" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0009" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Memory" Version="4.5.3" />
<PackageReference Include="YamlDotNet" Version="8.1.0" />
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" />
<PackageReference Include="OpenToolkit.OpenAL" Version="4.0.0-pre9.1" />
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" />
<PackageReference Include="Fody" Version="*" PrivateAssets="All" />
<PackageReference Include="InlineIL.Fody" Version="*" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.2.0" PrivateAssets="All" />
<PackageReference Include="InlineIL.Fody" Version="1.4.1" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition="'$(EnableClientScripting)' == 'True'">
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="3.5.0" />

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Robust.Shared.Maths;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Client.UserInterface.Controls
{
@@ -191,7 +193,7 @@ namespace Robust.Client.UserInterface.Controls
first = false;
minWidth = Math.Max(minWidth, childWidth);
minWidth = MathF.Max(minWidth, childWidth);
}
else
{
@@ -203,7 +205,7 @@ namespace Robust.Client.UserInterface.Controls
first = false;
minHeight = Math.Max(minHeight, childHeight);
minHeight = MathF.Max(minHeight, childHeight);
}
}

View File

@@ -79,7 +79,7 @@ namespace Robust.Client.UserInterface.Controls
if (Vertical)
{
var width = Math.Max(firstSizeX, secondSizeX);
var width = MathF.Max(firstSizeX, secondSizeX);
var height = firstSizeY + Separation + secondSizeY;
return (width, height);
@@ -87,7 +87,7 @@ namespace Robust.Client.UserInterface.Controls
else
{
var width = firstSizeX + Separation + secondSizeX;
var height = Math.Max(firstSizeY, secondSizeY);
var height = MathF.Max(firstSizeY, secondSizeY);
return (width, height);
}

View File

@@ -5,6 +5,8 @@ using Robust.Client.Graphics.Drawing;
using Robust.Shared.Input;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Client.UserInterface.Controls
{
@@ -342,7 +344,7 @@ namespace Robust.Client.UserInterface.Controls
var activeSize = active?.MinimumSize ?? Vector2.Zero;
var inactiveSize = inactive?.MinimumSize ?? Vector2.Zero;
headerSize = (int) Math.Max(activeSize.Y, inactiveSize.Y);
headerSize = (int) MathF.Max(activeSize.Y, inactiveSize.Y);
headerSize += font.GetHeight(UIScale);
}

View File

@@ -12,12 +12,11 @@
</PropertyGroup>
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Core" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" Version="2.2.1" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="3.1.1" />
<PackageReference Include="prometheus-net" Version="3.5.0" />
<PackageReference Include="YamlDotNet" Version="8.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />

View File

@@ -1,5 +1,7 @@
using System;
using JetBrains.Annotations;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.CompilerServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -30,14 +32,53 @@ namespace Robust.Shared.Maths
/// </summary>
public readonly float Bottom;
public Vector2 BottomRight => new Vector2(Right, Bottom);
public Vector2 TopLeft => new Vector2(Left, Top);
public Vector2 TopRight => new Vector2(Right, Top);
public Vector2 BottomLeft => new Vector2(Left, Bottom);
public float Width => Math.Abs(Right - Left);
public float Height => Math.Abs(Bottom - Top);
public Vector2 Size => new Vector2(Width, Height);
public Vector2 Center => BottomLeft + Size / 2;
public Vector2 BottomRight
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(Right, Bottom);
}
public Vector2 TopLeft
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(Left, Top);
}
public Vector2 TopRight
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(Right, Top);
}
public Vector2 BottomLeft
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(Left, Bottom);
}
public float Width
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MathF.Abs(Right - Left);
}
public float Height
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MathF.Abs(Bottom - Top);
}
public Vector2 Size
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(Width, Height);
}
public Vector2 Center
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => BottomLeft + Size * .5f;
}
/// <summary>
/// A 1x1 unit box with the origin centered.
@@ -56,21 +97,25 @@ namespace Robust.Shared.Maths
Bottom = bottom;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Box2 FromDimensions(float left, float bottom, float width, float height)
{
return new Box2(left, bottom, left + width, bottom + height);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Box2 FromDimensions(Vector2 bottomLeft, Vector2 size)
{
return FromDimensions(bottomLeft.X, bottomLeft.Y, size.X, size.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Box2 CenteredAround(Vector2 center, Vector2 size)
{
return FromDimensions(center - size / 2, size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Intersects(in Box2 other)
{
return other.Bottom <= this.Top && other.Top >= this.Bottom && other.Right >= this.Left &&
@@ -86,12 +131,13 @@ namespace Robust.Shared.Maths
/// <summary>
/// Returns the intersection box created when two Boxes overlap.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Box2 Intersect(in Box2 other)
{
var left = Math.Max(Left, other.Left);
var right = Math.Min(Right, other.Right);
var bottom = Math.Max(Bottom, other.Bottom);
var top = Math.Min(Top, other.Top);
var left = MathF.Max(Left, other.Left);
var right = MathF.Min(Right, other.Right);
var bottom = MathF.Max(Bottom, other.Bottom);
var top = MathF.Min(Top, other.Top);
if (left <= right && bottom <= top)
return new Box2(left, bottom, right, top);
@@ -105,10 +151,10 @@ namespace Robust.Shared.Maths
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Box2 Union(in Box2 other)
{
var left = Math.Min(Left, other.Left);
var right = Math.Max(Right, other.Right);
var bottom = Math.Min(Bottom, other.Bottom);
var top = Math.Max(Top, other.Top);
var left = MathF.Min(Left, other.Left);
var right = MathF.Max(Right, other.Right);
var bottom = MathF.Min(Bottom, other.Bottom);
var top = MathF.Max(Top, other.Top);
if (left <= right && bottom <= top)
return new Box2(left, bottom, right, top);
@@ -161,6 +207,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="scalar">Value to scale the box by.</param>
/// <returns>Scaled box.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Box2 Scale(float scalar)
{
if (scalar < 0)
@@ -176,23 +223,27 @@ namespace Robust.Shared.Maths
}
/// <summary>Returns a Box2 translated by the given amount.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Box2 Translated(Vector2 point)
{
return new Box2(Left + point.X, Bottom + point.Y, Right + point.X, Top + point.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Box2 other)
{
return Left.Equals(other.Left) && Right.Equals(other.Right) && Top.Equals(other.Top) &&
Bottom.Equals(other.Bottom);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj)
{
if (obj is null) return false;
return obj is Box2 box2 && Equals(box2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
{
unchecked
@@ -208,6 +259,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Compares two objects for equality by value.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Box2 a, Box2 b)
{
return FloatMath.CloseTo(a.Bottom, b.Bottom) &&
@@ -216,6 +268,7 @@ namespace Robust.Shared.Maths
FloatMath.CloseTo(a.Left, b.Left);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Box2 a, Box2 b)
{
return !(a == b);
@@ -246,15 +299,16 @@ namespace Robust.Shared.Maths
/// <summary>
/// Returns this box enlarged to also contain the specified position.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Box2 ExtendToContain(Vector2 vec)
{
var (x, y) = vec;
return new Box2(
Math.Min(x, Left),
Math.Min(y, Bottom),
Math.Max(x, Right),
Math.Max(y, Top));
MathF.Min(x, Left),
MathF.Min(y, Bottom),
MathF.Max(x, Right),
MathF.Max(y, Top));
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -36,6 +36,8 @@ using SysVector4 = System.Numerics.Vector4;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -387,10 +389,10 @@ namespace Robust.Shared.Maths
var saturation = hsl.Y;
var lightness = hsl.Z;
var c = (1.0f - Math.Abs(2.0f * lightness - 1.0f)) * saturation;
var c = (1.0f - MathF.Abs(2.0f * lightness - 1.0f)) * saturation;
var h = hue / 60.0f;
var X = c * (1.0f - Math.Abs(h % 2.0f - 1.0f));
var X = c * (1.0f - MathF.Abs(h % 2.0f - 1.0f));
float r, g, b;
if (0.0f <= h && h < 1.0f)
@@ -452,8 +454,8 @@ namespace Robust.Shared.Maths
/// <param name="rgb">Color value to convert.</param>
public static Vector4 ToHsl(Color rgb)
{
var max = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B));
var min = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B));
var max = MathF.Max(rgb.R, MathF.Max(rgb.G, rgb.B));
var min = MathF.Min(rgb.R, MathF.Min(rgb.G, rgb.B));
var c = max - min;
var h = 0.0f;
@@ -472,7 +474,7 @@ namespace Robust.Shared.Maths
var saturation = 0.0f;
if (0.0f != lightness && lightness != 1.0f)
saturation = c / (1.0f - Math.Abs(2.0f * lightness - 1.0f));
saturation = c / (1.0f - MathF.Abs(2.0f * lightness - 1.0f));
return new Vector4(hue, saturation, lightness, rgb.A);
}
@@ -498,7 +500,7 @@ namespace Robust.Shared.Maths
var c = value * saturation;
var h = hue / 60.0f;
var x = c * (1.0f - Math.Abs(h % 2.0f - 1.0f));
var x = c * (1.0f - MathF.Abs(h % 2.0f - 1.0f));
float r, g, b;
if (0.0f <= h && h < 1.0f)
@@ -560,8 +562,8 @@ namespace Robust.Shared.Maths
/// <param name="rgb">Color value to convert.</param>
public static Vector4 ToHsv(Color rgb)
{
var max = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B));
var min = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B));
var max = MathF.Max(rgb.R, MathF.Max(rgb.G, rgb.B));
var min = MathF.Min(rgb.R, MathF.Min(rgb.G, rgb.B));
var c = max - min;
var h = 0.0f;
@@ -679,7 +681,7 @@ namespace Robust.Shared.Maths
var luminance = hcy.Z;
var h = hue / 60.0f;
var x = c * (1.0f - Math.Abs(h % 2.0f - 1.0f));
var x = c * (1.0f - MathF.Abs(h % 2.0f - 1.0f));
float r, g, b;
if (0.0f <= h && h < 1.0f)
@@ -741,8 +743,8 @@ namespace Robust.Shared.Maths
/// <param name="rgb">Color value to convert.</param>
public static Vector4 ToHcy(Color rgb)
{
var max = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B));
var min = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B));
var max = MathF.Max(rgb.R, MathF.Max(rgb.G, rgb.B));
var min = MathF.Min(rgb.R, MathF.Min(rgb.G, rgb.B));
var c = max - min;
var h = 0.0f;
@@ -764,7 +766,7 @@ namespace Robust.Shared.Maths
public static Vector4 ToCmyk(Color rgb)
{
var (r, g, b) = rgb;
var k = 1 - Math.Max(r, Math.Max(g, b));
var k = 1 - MathF.Max(r, MathF.Max(g, b));
var c = (1 - r - k) / (1 - k);
var m = (1 - g - k) / (1 - k);
var y = (1 - b - k) / (1 - k);
@@ -959,7 +961,7 @@ namespace Robust.Shared.Maths
throw new NotImplementedException();
}
return new Color(ret.X, ret.Y, ret.Z, Math.Min(1, dstColor.A + dstColor.A * srcColor.A));
return new Color(ret.X, ret.Y, ret.Z, MathF.Min(1, dstColor.A + dstColor.A * srcColor.A));
}
/// <summary>

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,4 +1,7 @@
using System;
using System.Runtime.CompilerServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -11,11 +14,14 @@ namespace Robust.Shared.Maths
/// Returns the largest integer smaller to or equal to f.
/// </summary>
#if NETCOREAPP
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Floor(float f) => MathF.Floor(f);
#else
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Floor(float f) => (float)Math.Floor(f);
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Clamp<T>(this T val, T min, T max)
where T : IComparable<T>
{
@@ -24,6 +30,19 @@ namespace Robust.Shared.Maths
return val;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Clamp(this float val, float min, float max)
{
return MathF.Clamp(val, min, max);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Clamp(this double val, double min, double max)
{
return Math.Clamp(val, min, max);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CloseTo(float a, float b, double tolerance = .00001)
{
var epsilon =
@@ -32,6 +51,7 @@ namespace Robust.Shared.Maths
return Math.Abs(a - b) <= epsilon;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CloseTo(float a, double b, double tolerance = .00001)
{
var epsilon =
@@ -40,6 +60,7 @@ namespace Robust.Shared.Maths
return Math.Abs(a - b) <= epsilon;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CloseTo(double a, float b, double tolerance = .00001)
{
var epsilon =
@@ -48,6 +69,7 @@ namespace Robust.Shared.Maths
return Math.Abs(a - b) <= epsilon;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CloseTo(double a, double b, double tolerance = .00001)
{
var epsilon =
@@ -59,34 +81,42 @@ namespace Robust.Shared.Maths
/// <summary>
/// <c>blend</c> 0 means <c>a</c>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Lerp(double a, double b, double blend)
{
return a + (b - a) * blend;
//return a + (b - a) * blend;
return Math.Interpolate(a, b, blend);
}
/// <summary>
/// <c>blend</c> 0 means <c>a</c>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Lerp(float a, float b, float blend)
{
return a + (b - a) * blend;
//return a + (b - a) * blend;
return MathF.Interpolate(a, b, blend);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float InterpolateCubic(float preA, float a, float b, float postB, float t)
{
return a + 0.5f * t *
(b - preA + t * (2.0f * preA - 5.0f * a + 4.0f * b - postB + t * (3.0f * (a - b) + postB - preA)));
//return a + 0.5f * t * (b - preA + t * (2.0f * preA - 5.0f * a + 4.0f * b - postB + t * (3.0f * (a - b) + postB - preA)));
return MathF.CubicInterpolate(preA,a, b, postB, t);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double InterpolateCubic(double preA, double a, double b, double postB, double t)
{
return a + 0.5 * t *
(b - preA + t * (2.0 * preA - 5.0 * a + 4.0 * b - postB + t * (3.0 * (a - b) + postB - preA)));
//return a + 0.5 * t * (b - preA + t * (2.0 * preA - 5.0 * a + 4.0 * b - postB + t * (3.0 * (a - b) + postB - preA)));
return Math.CubicInterpolate(preA,a, b, postB, t);
}
// Clamps value between 0 and 1 and returns value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Clamp01(float value)
{
/*
if (value < 0F)
return 0F;
@@ -94,9 +124,13 @@ namespace Robust.Shared.Maths
return 1F;
return value;
*/
return MathF.Clamp(value, 0, 1);
}
// Loops the value t, so that it is never larger than length and never smaller than 0.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Repeat(float t, float length)
{
return Clamp(t - Floor(t / length) * length, 0.0f, length);

View File

@@ -12,6 +12,9 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -83,6 +86,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long NextPowerOfTwo(long n)
{
if (n <= 0) throw new ArgumentOutOfRangeException(nameof(n), "Must be positive.");
@@ -94,6 +98,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int NextPowerOfTwo(int n)
{
if (n <= 0) throw new ArgumentOutOfRangeException(nameof(n), "Must be positive.");
@@ -105,6 +110,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float NextPowerOfTwo(float n)
{
if (float.IsNaN(n) || float.IsInfinity(n)) throw new ArgumentOutOfRangeException(nameof(n), "Must be a number.");
@@ -117,6 +123,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="n">The specified number.</param>
/// <returns>The next power of two.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double NextPowerOfTwo(double n)
{
if (double.IsNaN(n) || double.IsInfinity(n)) throw new ArgumentOutOfRangeException(nameof(n), "Must be a number.");
@@ -136,6 +143,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="n">The number.</param>
/// <returns>n!</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Factorial(int n)
{
long result = 1;
@@ -156,6 +164,7 @@ namespace Robust.Shared.Maths
/// <param name="n">The n.</param>
/// <param name="k">The k.</param>
/// <returns>n! / (k! * (n - k)!)</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long BinomialCoefficient(int n, int k)
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
@@ -170,6 +179,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="degrees">An angle in degrees</param>
/// <returns>The angle expressed in radians</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float DegreesToRadians(float degrees)
{
const float degToRad = (float) Math.PI / 180.0f;
@@ -181,6 +191,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="radians">An angle in radians</param>
/// <returns>The angle expressed in degrees</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float RadiansToDegrees(float radians)
{
const float radToDeg = 180.0f / (float) Math.PI;
@@ -192,6 +203,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="degrees">An angle in degrees</param>
/// <returns>The angle expressed in radians</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double DegreesToRadians(double degrees)
{
const double degToRad = Math.PI / 180.0;
@@ -203,6 +215,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="radians">An angle in radians</param>
/// <returns>The angle expressed in degrees</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double RadiansToDegrees(double radians)
{
const double radToDeg = 180.0 / Math.PI;
@@ -218,6 +231,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="a">The first value.</param>
/// <param name="b">The second value.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap(ref double a, ref double b)
{
var temp = a;
@@ -230,6 +244,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="a">The first value.</param>
/// <param name="b">The second value.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap(ref float a, ref float b)
{
var temp = a;
@@ -241,23 +256,26 @@ namespace Robust.Shared.Maths
#region MinMax
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Min(float a, float b, float c, float d)
{
return Math.Min(a, Math.Min(b, Math.Min(c, d)));
return MathF.Min(a, MathF.Min(b, MathF.Min(c, d)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Max(float a, float b, float c, float d)
{
return Math.Max(a, Math.Max(b, Math.Max(c, d)));
return MathF.Max(a, MathF.Max(b, MathF.Max(c, d)));
}
/// <summary>
/// Returns the median value out of a, b and c.
/// </summary>
/// <returns>THe median.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Median(float a, float b, float c)
{
return Math.Max(Math.Min(a, b), Math.Min(Math.Max(a, b), c));
return MathF.Max(MathF.Min(a, b), MathF.Min(MathF.Max(a, b), c));
}
#endregion MinMax
@@ -270,6 +288,7 @@ namespace Robust.Shared.Maths
/// <param name="d">The divisor.</param>
/// <returns>The remainder.</returns>
[DebuggerStepThrough]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Mod(double n, double d)
{
return n - Math.Floor(n / d) * d;
@@ -283,6 +302,7 @@ namespace Robust.Shared.Maths
/// <param name="d">The divisor.</param>
/// <returns>The remainder.</returns>
[DebuggerStepThrough]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Mod(int n, int d)
{
var r = n % d;

View File

@@ -25,7 +25,10 @@ SOFTWARE.
#endregion --- License ---
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -68,6 +71,7 @@ namespace Robust.Shared.Maths
/// <returns>The component at the given row and column in the matrix.</returns>
public float this[int row, int column]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
switch (row)
@@ -105,6 +109,7 @@ namespace Robust.Shared.Maths
throw new IndexOutOfRangeException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
switch (row)
@@ -167,6 +172,7 @@ namespace Robust.Shared.Maths
/// <returns>The component at the given index into the matrix.</returns>
public float this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
switch (index)
@@ -183,6 +189,7 @@ namespace Robust.Shared.Maths
default: throw new IndexOutOfRangeException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
switch (index)
@@ -222,6 +229,7 @@ namespace Robust.Shared.Maths
/// <summary>Converts the matrix into an array of floats.</summary>
/// <param name="matrix">The matrix to convert.</param>
/// <returns>An array of floats for the matrix.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator float[](Matrix3 matrix)
{
return new[]
@@ -244,6 +252,7 @@ namespace Robust.Shared.Maths
/// <summary>Constructs left matrix with the same components as the given matrix.</summary>
/// <param name="matrix">The matrix whose components to copy.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix3(ref Matrix3 matrix)
{
R0C0 = matrix.R0C0;
@@ -267,6 +276,7 @@ namespace Robust.Shared.Maths
/// <param name="r2c0">The value for row 2 column 0.</param>
/// <param name="r2c1">The value for row 2 column 1.</param>
/// <param name="r2c2">The value for row 2 column 2.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix3
(
float r0c0,
@@ -293,6 +303,7 @@ namespace Robust.Shared.Maths
/// <summary>Constructs left matrix from the given array of float-precision floating-point numbers.</summary>
/// <param name="floatArray">The array of floats for the components of the matrix.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix3(float[] floatArray)
{
if (floatArray == null || floatArray.GetLength(0) < 9) throw new MissingFieldException();
@@ -312,6 +323,7 @@ namespace Robust.Shared.Maths
/// Constructs a new instance.
/// </summary>
/// <param name="matrix">A Matrix4 to take the upper-left 3x3 from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix3(Matrix4 matrix)
{
R0C0 = matrix.Row0.X;
@@ -327,6 +339,7 @@ namespace Robust.Shared.Maths
R2C2 = matrix.Row2.Z;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateTranslation(float x, float y)
{
var result = Identity;
@@ -341,16 +354,19 @@ namespace Robust.Shared.Maths
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateTranslation(Vector2 vector)
{
return CreateTranslation(vector.X, vector.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateRotation(float angle)
{
return CreateRotation(new Angle(angle));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateRotation(Angle angle)
{
var cos = (float) Math.Cos(angle);
@@ -370,6 +386,7 @@ namespace Robust.Shared.Maths
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateScale(float x, float y)
{
var result = Identity;
@@ -384,6 +401,7 @@ namespace Robust.Shared.Maths
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 CreateScale(in Vector2 scale)
{
return CreateScale(scale.X, scale.Y);
@@ -445,11 +463,13 @@ namespace Robust.Shared.Maths
left.R2C2 == right.R2C2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EqualsApprox(Matrix3 other)
{
return EqualsApprox(ref other, 1.0E-6f);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EqualsApprox(Matrix3 other, double tolerance)
{
return EqualsApprox(ref other, (float) tolerance);
@@ -498,6 +518,7 @@ namespace Robust.Shared.Maths
/// <summary>Add left matrix to this matrix.</summary>
/// <param name="matrix">The matrix to add.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(ref Matrix3 matrix)
{
R0C0 = R0C0 + matrix.R0C0;
@@ -514,6 +535,7 @@ namespace Robust.Shared.Maths
/// <summary>Add left matrix to this matrix.</summary>
/// <param name="matrix">The matrix to add.</param>
/// <param name="result">The resulting matrix of the addition.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(ref Matrix3 matrix, out Matrix3 result)
{
result.R0C0 = R0C0 + matrix.R0C0;
@@ -531,6 +553,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
/// <param name="right">The matrix on the right side of the equation</param>
/// <param name="result">The resulting matrix of the addition.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Add(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
{
result.R0C0 = left.R0C0 + right.R0C0;
@@ -546,6 +569,7 @@ namespace Robust.Shared.Maths
/// <summary>Subtract matrix from this matrix.</summary>
/// <param name="matrix">The matrix to subtract.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Subtract(ref Matrix3 matrix)
{
R0C0 = R0C0 - matrix.R0C0;
@@ -562,6 +586,7 @@ namespace Robust.Shared.Maths
/// <summary>Subtract matrix from this matrix.</summary>
/// <param name="matrix">The matrix to subtract.</param>
/// <param name="result">The resulting matrix of the subtraction.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Subtract(ref Matrix3 matrix, out Matrix3 result)
{
result.R0C0 = R0C0 - matrix.R0C0;
@@ -579,6 +604,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The matrix on the matrix side of the equation.</param>
/// <param name="right">The matrix on the right side of the equation</param>
/// <param name="result">The resulting matrix of the subtraction.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Subtract(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
{
result.R0C0 = left.R0C0 - right.R0C0;
@@ -594,6 +620,7 @@ namespace Robust.Shared.Maths
/// <summary>Multiply left matrix times this matrix.</summary>
/// <param name="matrix">The matrix to multiply.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Multiply(in Matrix3 matrix)
{
var r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
@@ -620,6 +647,7 @@ namespace Robust.Shared.Maths
/// <summary>Multiply matrix times this matrix.</summary>
/// <param name="matrix">The matrix to multiply.</param>
/// <param name="result">The resulting matrix of the multiplication.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Multiply(ref Matrix3 matrix, out Matrix3 result)
{
result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
@@ -637,6 +665,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The matrix on the matrix side of the equation.</param>
/// <param name="right">The matrix on the right side of the equation</param>
/// <param name="result">The resulting matrix of the multiplication.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Multiply(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
{
result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0;
@@ -652,6 +681,7 @@ namespace Robust.Shared.Maths
/// <summary>Multiply matrix times this scalar.</summary>
/// <param name="scalar">The scalar to multiply.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Multiply(float scalar)
{
R0C0 = scalar * R0C0;
@@ -668,6 +698,7 @@ namespace Robust.Shared.Maths
/// <summary>Multiply matrix times this matrix.</summary>
/// <param name="scalar">The scalar to multiply.</param>
/// <param name="result">The resulting matrix of the multiplication.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Multiply(float scalar, out Matrix3 result)
{
result.R0C0 = scalar * R0C0;
@@ -685,6 +716,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
/// <param name="scalar">The scalar on the right side of the equation</param>
/// <param name="result">The resulting matrix of the multiplication.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Multiply(ref Matrix3 matrix, float scalar, out Matrix3 result)
{
result.R0C0 = scalar * matrix.R0C0;
@@ -702,8 +734,13 @@ namespace Robust.Shared.Maths
#region Functions
public float Determinant => R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0;
public float Determinant
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Transpose()
{
MathHelper.Swap(ref R0C1, ref R1C0);
@@ -711,6 +748,7 @@ namespace Robust.Shared.Maths
MathHelper.Swap(ref R1C2, ref R2C1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Transpose(out Matrix3 result)
{
result.R0C0 = R0C0;
@@ -724,6 +762,7 @@ namespace Robust.Shared.Maths
result.R2C2 = R2C2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transpose(ref Matrix3 matrix, out Matrix3 result)
{
result.R0C0 = matrix.R0C0;
@@ -743,6 +782,7 @@ namespace Robust.Shared.Maths
/// <param name="mat">The matrix to invert</param>
/// <returns>The inverse of the given matrix if it has one, or the input if it is singular</returns>
/// <exception cref="InvalidOperationException">Thrown if the Matrix4 is singular.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 Invert(Matrix3 mat)
{
var result = new Matrix3();
@@ -750,6 +790,7 @@ namespace Robust.Shared.Maths
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Invert(ref Matrix3 minv)
{
//Credit: https://stackoverflow.com/a/18504573
@@ -782,6 +823,7 @@ namespace Robust.Shared.Maths
#region Transformation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Transform(ref Vector3 vector)
{
var x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
@@ -791,6 +833,7 @@ namespace Robust.Shared.Maths
vector.Y = y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Matrix3 matrix, ref Vector3 vector)
{
var x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
@@ -800,6 +843,7 @@ namespace Robust.Shared.Maths
vector.Y = y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Matrix3 matrix, ref Vector2 vector)
{
var vec3 = new Vector3(vector.X, vector.Y, 1);
@@ -807,11 +851,13 @@ namespace Robust.Shared.Maths
vector = vec3.Xy;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector2 Transform(Vector2 vector)
{
return Transform(this, vector);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Transform(in Matrix3 matrix, Vector2 vector)
{
var x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2;
@@ -820,6 +866,7 @@ namespace Robust.Shared.Maths
return new Vector2(x, y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Transform(ref Vector3 vector, out Vector3 result)
{
result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
@@ -833,6 +880,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <param name="result">Transformed vector.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Matrix3 matrix, in Vector3 vector, out Vector3 result)
{
var x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
@@ -848,6 +896,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <param name="result">Transformed vector.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Matrix3 matrix, in Vector2 vector, out Vector2 result)
{
var x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2;
@@ -861,6 +910,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <param name="result">Transformed vector.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Vector3 vector, in Matrix3 matrix, out Vector3 result)
{
var x = (vector.X * matrix.R0C0) + (vector.Y * matrix.R1C0) + (vector.Z * matrix.R2C0);
@@ -876,6 +926,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <param name="result">Transformed vector.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(in Vector2 vector, in Matrix3 matrix, out Vector2 result)
{
var x = (vector.X * matrix.R0C0) + (vector.Y * matrix.R1C0) + (matrix.R2C0);
@@ -883,6 +934,7 @@ namespace Robust.Shared.Maths
result = new Vector2(x, y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Rotate(float angle)
{
var angleRadians = MathHelper.DegreesToRadians(angle);
@@ -902,6 +954,7 @@ namespace Robust.Shared.Maths
R0C2 = r0c2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Rotate(Angle angle)
{
var sin = (float) Math.Sin(angle);
@@ -920,6 +973,7 @@ namespace Robust.Shared.Maths
R0C2 = r0c2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Rotate(float angle, out Matrix3 result)
{
var angleRadians = MathHelper.DegreesToRadians(angle);
@@ -937,6 +991,7 @@ namespace Robust.Shared.Maths
result.R2C2 = R2C2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Rotate(ref Matrix3 matrix, float angle, out Matrix3 result)
{
var angleRadians = MathHelper.DegreesToRadians(angle);
@@ -954,6 +1009,7 @@ namespace Robust.Shared.Maths
result.R2C2 = matrix.R2C2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RotateMatrix(float angle, out Matrix3 result)
{
var angleRadians = MathHelper.DegreesToRadians(angle);
@@ -981,6 +1037,7 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <returns>Transformed vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator *(in Matrix3 matrix, in Vector3 vector)
{
Transform(in matrix, in vector, out var result);
@@ -994,18 +1051,21 @@ namespace Robust.Shared.Maths
/// <param name="matrix">Matrix containing the transformation.</param>
/// <param name="vector">Input vector to transform.</param>
/// <returns>Transformed vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator *(in Matrix3 matrix, in Vector2 vector)
{
Transform(in matrix, in vector, out var result);
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator *(in Vector3 vector, in Matrix3 matrix)
{
Transform(in vector, in matrix, out var result);
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator *(in Vector2 vector, in Matrix3 matrix)
{
Transform(in vector, in matrix, out var result);
@@ -1016,6 +1076,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The matrix on the matrix side of the equation.</param>
/// <param name="right">The matrix on the right side of the equation</param>
/// <returns>The resulting matrix of the multiplication.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix3 operator *(Matrix3 left, Matrix3 right)
{
Multiply(ref left, ref right, out var result);

View File

@@ -26,7 +26,10 @@ SOFTWARE.
#endregion --- License ---
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -75,6 +78,7 @@ namespace Robust.Shared.Maths
/// <param name="row1">Second row of the matrix</param>
/// <param name="row2">Third row of the matrix</param>
/// <param name="row3">Bottom row of the matrix</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix4(Vector4 row0, Vector4 row1, Vector4 row2, Vector4 row3)
{
Row0 = row0;
@@ -102,6 +106,7 @@ namespace Robust.Shared.Maths
/// <param name="m31">Second item of the fourth row of the matrix.</param>
/// <param name="m32">Third item of the fourth row of the matrix.</param>
/// <param name="m33">Fourth item of the fourth row of the matrix.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Matrix4(
float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
@@ -123,39 +128,61 @@ namespace Robust.Shared.Maths
/// <summary>
/// The determinant of this matrix
/// </summary>
public float Determinant => 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;
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;
}
/// <summary>
/// The first column of this matrix
/// </summary>
public Vector4 Column0 => new Vector4(Row0.X, Row1.X, Row2.X, Row3.X);
public Vector4 Column0
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector4(Row0.X, Row1.X, Row2.X, Row3.X);
}
/// <summary>
/// The second column of this matrix
/// </summary>
public Vector4 Column1 => new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y);
public Vector4 Column1
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y);
}
/// <summary>
/// The third column of this matrix
/// </summary>
public Vector4 Column2 => new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.Z);
public Vector4 Column2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.Z);
}
/// <summary>
/// The fourth column of this matrix
/// </summary>
public Vector4 Column3 => new Vector4(Row0.W, Row1.W, Row2.W, Row3.W);
public Vector4 Column3
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector4(Row0.W, Row1.W, Row2.W, Row3.W);
}
/// <summary>
/// Gets or sets the value at row 1, column 1 of this instance.
/// </summary>
public float M11
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row0.X;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row0.X = value;
}
@@ -164,7 +191,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M12
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row0.Y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row0.Y = value;
}
@@ -173,7 +202,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M13
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row0.Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row0.Z = value;
}
@@ -182,7 +213,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M14
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row0.W;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row0.W = value;
}
@@ -191,7 +224,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M21
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row1.X;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row1.X = value;
}
@@ -200,7 +235,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M22
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row1.Y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row1.Y = value;
}
@@ -209,7 +246,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M23
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row1.Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row1.Z = value;
}
@@ -218,7 +257,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M24
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row1.W;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row1.W = value;
}
@@ -227,7 +268,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M31
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row2.X;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row2.X = value;
}
@@ -236,7 +279,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M32
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row2.Y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row2.Y = value;
}
@@ -245,7 +290,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M33
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row2.Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row2.Z = value;
}
@@ -254,7 +301,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M34
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row2.W;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row2.W = value;
}
@@ -263,7 +312,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M41
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row3.X;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row3.X = value;
}
@@ -272,7 +323,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M42
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row3.Y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row3.Y = value;
}
@@ -281,7 +334,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M43
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row3.Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row3.Z = value;
}
@@ -290,7 +345,9 @@ namespace Robust.Shared.Maths
/// </summary>
public float M44
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Row3.W;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Row3.W = value;
}
@@ -302,6 +359,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Converts this instance into its inverse.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
/// </summary>
public void Invert()
{
@@ -315,6 +373,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Converts this instance into its transpose.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Transpose()
{
this = Transpose(this);
@@ -334,6 +393,7 @@ namespace Robust.Shared.Maths
/// <param name="axis">The axis to rotate about.</param>
/// <param name="angle">Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).</param>
/// <param name="result">A matrix instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4 result)
{
var cos = (float) Math.Cos(-angle);
@@ -354,6 +414,7 @@ namespace Robust.Shared.Maths
/// <param name="axis">The axis to rotate about.</param>
/// <param name="angle">Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).</param>
/// <returns>A matrix instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateFromAxisAngle(Vector3 axis, float angle)
{
CreateFromAxisAngle(axis, angle, out var result);
@@ -369,6 +430,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateRotationX(float angle, out Matrix4 result)
{
var cos = (float) Math.Cos(angle);
@@ -385,6 +447,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateRotationX(float angle)
{
CreateRotationX(angle, out var result);
@@ -396,6 +459,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateRotationY(float angle, out Matrix4 result)
{
var cos = (float) Math.Cos(angle);
@@ -412,6 +476,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateRotationY(float angle)
{
CreateRotationY(angle, out var result);
@@ -423,6 +488,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateRotationZ(float angle, out Matrix4 result)
{
var cos = (float) Math.Cos(angle);
@@ -439,6 +505,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="angle">The counter-clockwise angle in radians.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateRotationZ(float angle)
{
CreateRotationZ(angle, out var result);
@@ -456,6 +523,7 @@ namespace Robust.Shared.Maths
/// <param name="y">Y translation.</param>
/// <param name="z">Z translation.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateTranslation(float x, float y, float z, out Matrix4 result)
{
result = Identity;
@@ -467,6 +535,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vector">The translation vector.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateTranslation(ref Vector3 vector, out Matrix4 result)
{
result = Identity;
@@ -480,6 +549,7 @@ namespace Robust.Shared.Maths
/// <param name="y">Y translation.</param>
/// <param name="z">Z translation.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateTranslation(float x, float y, float z)
{
CreateTranslation(x, y, z, out var result);
@@ -491,6 +561,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vector">The translation vector.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreateTranslation(Vector3 vector)
{
CreateTranslation(vector.X, vector.Y, vector.Z, out var result);
@@ -509,6 +580,7 @@ namespace Robust.Shared.Maths
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[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);
@@ -522,6 +594,7 @@ namespace Robust.Shared.Maths
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <rereturns>The resulting Matrix4 instance.</rereturns>
[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);
@@ -542,6 +615,7 @@ namespace Robust.Shared.Maths
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
[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();
@@ -570,6 +644,7 @@ namespace Robust.Shared.Maths
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <returns>The resulting Matrix4 instance.</returns>
[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);
@@ -598,6 +673,7 @@ namespace Robust.Shared.Maths
/// <item>zNear is larger than zFar</item>
/// </list>
/// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar, out Matrix4 result)
{
if (fovy <= 0 || fovy > Math.PI)
@@ -635,6 +711,7 @@ namespace Robust.Shared.Maths
/// <item>zNear is larger than zFar</item>
/// </list>
/// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar)
{
CreatePerspectiveFieldOfView(fovy, aspect, zNear, zFar, out var result);
@@ -663,6 +740,7 @@ namespace Robust.Shared.Maths
/// <item>zNear is larger than zFar</item>
/// </list>
/// </exception>
[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)
@@ -703,6 +781,7 @@ namespace Robust.Shared.Maths
/// <item>zNear is larger than zFar</item>
/// </list>
/// </exception>
[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);
@@ -718,6 +797,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="scale">Single scale factor for x,y and z axes</param>
/// <returns>A scaling matrix</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Scale(float scale)
{
return Scale(scale, scale, scale);
@@ -728,6 +808,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="scale">Scale factors for x,y and z axes</param>
/// <returns>A scaling matrix</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Scale(Vector3 scale)
{
return Scale(scale.X, scale.Y, scale.Z);
@@ -740,6 +821,7 @@ namespace Robust.Shared.Maths
/// <param name="y">Scale factor for y-axis</param>
/// <param name="z">Scale factor for z-axis</param>
/// <returns>A scaling matrix</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Scale(float x, float y, float z)
{
Matrix4 result;
@@ -759,6 +841,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">the quaternion</param>
/// <returns>A rotation matrix</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Rotate(Quaternion q)
{
q.ToAxisAngle(out var axis, out var angle);
@@ -776,6 +859,7 @@ namespace Robust.Shared.Maths
/// <param name="target">Target position in world space</param>
/// <param name="up">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
/// <returns>A Matrix4 that transforms world space to camera space</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up)
{
var z = Vector3.Normalize(eye - target);
@@ -805,6 +889,7 @@ namespace Robust.Shared.Maths
/// <param name="upY">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
/// <param name="upZ">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param>
/// <returns>A Matrix4 that transforms world space to camera space</returns>
[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));
@@ -820,6 +905,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The left operand of the multiplication.</param>
/// <param name="right">The right operand of the multiplication.</param>
/// <returns>A new instance that is the result of the multiplication</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Mult(Matrix4 left, Matrix4 right)
{
Mult(ref left, ref right, out var result);
@@ -832,6 +918,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The left operand of the multiplication.</param>
/// <param name="right">The right operand of the multiplication.</param>
/// <param name="result">A new instance that is the result of the multiplication</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Mult(ref Matrix4 left, ref Matrix4 right, out Matrix4 result)
{
float lM11 = left.Row0.X,
@@ -895,6 +982,7 @@ namespace Robust.Shared.Maths
/// <param name="mat">The matrix to invert</param>
/// <returns>The inverse of the given matrix if it has one, or the input if it is singular</returns>
/// <exception cref="InvalidOperationException">Thrown if the Matrix4 is singular.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Invert(Matrix4 mat)
{
var result = new Matrix4();
@@ -902,6 +990,7 @@ namespace Robust.Shared.Maths
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Invert(ref Matrix4 result)
{
float m41 = Row3.X, m42 = Row3.Y, m43 = Row3.Z, m44 = Row3.W;
@@ -947,6 +1036,7 @@ namespace Robust.Shared.Maths
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,
@@ -1000,6 +1090,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="mat">The matrix to transpose</param>
/// <returns>The transpose of the given matrix</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 Transpose(Matrix4 mat)
{
return new Matrix4(mat.Column0, mat.Column1, mat.Column2, mat.Column3);
@@ -1010,6 +1101,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="mat">The matrix to transpose</param>
/// <param name="result">The result of the calculation</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transpose(ref Matrix4 mat, out Matrix4 result)
{
result.Row0 = mat.Column0;
@@ -1030,6 +1122,7 @@ namespace Robust.Shared.Maths
/// <param name="left">left-hand operand</param>
/// <param name="right">right-hand operand</param>
/// <returns>A new Matrix44 which holds the result of the multiplication</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix4 operator *(Matrix4 left, Matrix4 right)
{
return Mult(left, right);
@@ -1041,6 +1134,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left equals right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Matrix4 left, Matrix4 right)
{
return left.Equals(right);
@@ -1052,6 +1146,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left does not equal right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Matrix4 left, Matrix4 right)
{
return !left.Equals(right);
@@ -1080,6 +1175,7 @@ namespace Robust.Shared.Maths
/// Returns the hashcode for this instance.
/// </summary>
/// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
{
return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode();

View File

@@ -26,8 +26,11 @@ SOFTWARE.
#endregion --- License ---
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -52,6 +55,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="v">The vector part</param>
/// <param name="w">The w part</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Quaternion(Vector3 v, float w)
{
xyz = v;
@@ -65,9 +69,11 @@ namespace Robust.Shared.Maths
/// <param name="y">The y component</param>
/// <param name="z">The z component</param>
/// <param name="w">The w component</param>
[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 Matrix3 matrix)
{
var scale = Math.Pow(matrix.Determinant, 1.0d / 3.0d);
@@ -96,7 +102,9 @@ namespace Robust.Shared.Maths
/// </summary>
public Vector3 Xyz
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => xyz;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => xyz = value;
}
@@ -106,7 +114,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public float X
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => xyz.X;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => xyz.X = value;
}
@@ -116,7 +126,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public float Y
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => xyz.Y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => xyz.Y = value;
}
@@ -126,7 +138,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public float Z
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => xyz.Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => xyz.Z = value;
}
@@ -135,25 +149,33 @@ namespace Robust.Shared.Maths
/// </summary>
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;
}
@@ -168,6 +190,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="axis">The resultant axis</param>
/// <param name="angle">The resultant angle</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToAxisAngle(out Vector3 axis, out float angle)
{
var result = ToAxisAngle();
@@ -179,6 +202,7 @@ namespace Robust.Shared.Maths
/// Convert this instance to an axis-angle representation.
/// </summary>
/// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToAxisAngle()
{
var q = this;
@@ -211,7 +235,11 @@ namespace Robust.Shared.Maths
/// Gets the length (magnitude) of the quaternion.
/// </summary>
/// <seealso cref="LengthSquared"/>
public float Length => (float) Math.Sqrt(W * W + Xyz.LengthSquared);
public float Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (float) Math.Sqrt(W * W + Xyz.LengthSquared);
}
#endregion public float Length
@@ -220,7 +248,11 @@ namespace Robust.Shared.Maths
/// <summary>
/// Gets the square of the quaternion length (magnitude).
/// </summary>
public float LengthSquared => W * W + Xyz.LengthSquared;
public float LengthSquared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => W * W + Xyz.LengthSquared;
}
#endregion public float LengthSquared
@@ -229,6 +261,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Scales the Quaternion to unit length.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Normalize()
{
var scale = 1.0f / Length;
@@ -243,6 +276,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Convert this quaternion to its conjugate
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Conjugate()
{
Xyz = -Xyz;
@@ -274,6 +308,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first operand</param>
/// <param name="right">The second operand</param>
/// <returns>The result of the addition</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Add(Quaternion left, Quaternion right)
{
return new Quaternion(
@@ -287,6 +322,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first operand</param>
/// <param name="right">The second operand</param>
/// <param name="result">The result of the addition</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result)
{
result = new Quaternion(
@@ -304,6 +340,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The left instance.</param>
/// <param name="right">The right instance.</param>
/// <returns>The result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Sub(Quaternion left, Quaternion right)
{
return new Quaternion(
@@ -317,6 +354,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The left instance.</param>
/// <param name="right">The right instance.</param>
/// <param name="result">The result of the operation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sub(ref Quaternion left, ref Quaternion right, out Quaternion result)
{
result = new Quaternion(
@@ -334,6 +372,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>A new instance containing the result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Multiply(Quaternion left, Quaternion right)
{
Multiply(ref left, ref right, out var result);
@@ -346,6 +385,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <param name="result">A new instance containing the result of the calculation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result)
{
result = new Quaternion(
@@ -359,6 +399,7 @@ namespace Robust.Shared.Maths
/// <param name="quaternion">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <param name="result">A new instance containing the result of the calculation.</param>
[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);
@@ -370,6 +411,7 @@ namespace Robust.Shared.Maths
/// <param name="quaternion">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>A new instance containing the result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Multiply(Quaternion quaternion, float scale)
{
return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
@@ -382,6 +424,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Calculates the dot product between two Quaternions.
/// </summary>
[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;
@@ -396,6 +439,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion</param>
/// <returns>The conjugate of the given quaternion</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Conjugate(Quaternion q)
{
return new Quaternion(-q.Xyz, q.W);
@@ -406,6 +450,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion</param>
/// <param name="result">The conjugate of the given quaternion</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Conjugate(ref Quaternion q, out Quaternion result)
{
result = new Quaternion(-q.Xyz, q.W);
@@ -420,6 +465,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion to invert</param>
/// <returns>The inverse of the given quaternion</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Invert(Quaternion q)
{
Invert(ref q, out var result);
@@ -431,6 +477,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion to invert</param>
/// <param name="result">The inverse of the given quaternion</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Invert(ref Quaternion q, out Quaternion result)
{
var lengthSq = q.LengthSquared;
@@ -454,6 +501,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion to normalize</param>
/// <returns>The normalized quaternion</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Normalize(Quaternion q)
{
Normalize(ref q, out var result);
@@ -465,6 +513,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="q">The quaternion to normalize</param>
/// <param name="result">The normalized quaternion</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Normalize(ref Quaternion q, out Quaternion result)
{
var scale = 1.0f / q.Length;
@@ -481,6 +530,7 @@ namespace Robust.Shared.Maths
/// <param name="axis">The axis to rotate about</param>
/// <param name="angle">The rotation angle in radians</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion FromAxisAngle(Vector3 axis, float angle)
{
if (axis.LengthSquared == 0.0f)
@@ -507,6 +557,7 @@ namespace Robust.Shared.Maths
/// <param name="q2">The second quaternion</param>
/// <param name="blend">The blend factor</param>
/// <returns>A smooth blend between the given quaternions</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion Slerp(Quaternion q1, Quaternion q2, float blend)
{
// if either input is zero, return the other.
@@ -568,6 +619,7 @@ namespace Robust.Shared.Maths
#region RotateTowards
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta)
{
var num = Angle(from, to);
@@ -576,7 +628,7 @@ namespace Robust.Shared.Maths
return to;
}
var t = Math.Min(1f, maxDegreesDelta / num);
var t = MathF.Min(1f, maxDegreesDelta / num);
return Slerp(from, to, t);
}
@@ -584,6 +636,7 @@ namespace Robust.Shared.Maths
#region Angle
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Angle(Quaternion a, Quaternion b)
{
var f = Dot(a, b);
@@ -595,6 +648,7 @@ namespace Robust.Shared.Maths
#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);
@@ -614,7 +668,7 @@ namespace Robust.Shared.Maths
var quaternion = new Quaternion();
if (num8 > 0f)
{
var num = (float) Math.Sqrt(num8 + 1f);
var num = (float) MathF.Sqrt(num8 + 1f);
quaternion.w = num * 0.5f;
num = 0.5f / num;
quaternion.X = (m12 - m21) * num;
@@ -625,7 +679,7 @@ namespace Robust.Shared.Maths
if (m00 >= m11 && m00 >= m22)
{
var num7 = (float) Math.Sqrt(1f + m00 - m11 - m22);
var num7 = (float) MathF.Sqrt(1f + m00 - m11 - m22);
var num4 = 0.5f / num7;
quaternion.X = 0.5f * num7;
quaternion.Y = (m01 + m10) * num4;
@@ -636,7 +690,7 @@ namespace Robust.Shared.Maths
if (m11 > m22)
{
var num6 = (float) Math.Sqrt(1f + m11 - m00 - m22);
var num6 = (float) MathF.Sqrt(1f + m11 - m00 - m22);
var num3 = 0.5f / num6;
quaternion.X = (m10 + m01) * num3;
quaternion.Y = 0.5f * num6;
@@ -645,7 +699,7 @@ namespace Robust.Shared.Maths
return quaternion;
}
var num5 = (float) Math.Sqrt(1f + m22 - m00 - m11);
var num5 = (float) MathF.Sqrt(1f + m22 - m00 - m11);
var num2 = 0.5f / num5;
quaternion.X = (m20 + m02) * num2;
quaternion.Y = (m21 + m12) * num2;
@@ -659,6 +713,7 @@ namespace Robust.Shared.Maths
#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;
@@ -672,7 +727,7 @@ namespace Robust.Shared.Maths
if (test > 0.4995f * unit)
{
// singularity at north pole
v.Y = (float) (2f * Math.Atan2(rotation.y, rotation.x));
v.Y = (float) (2f * MathF.Atan2(rotation.y, rotation.x));
v.X = (float) (Math.PI / 2);
v.Z = 0;
return NormalizeAngles(v * RadToDeg);
@@ -681,19 +736,20 @@ namespace Robust.Shared.Maths
if (test < -0.4995f * unit)
{
// singularity at south pole
v.Y = (float) (-2f * Math.Atan2(rotation.y, rotation.x));
v.Y = (float) (-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 = (float) Math.Atan2(2f * q.x * q.w + 2f * q.y * q.z, 1 - 2f * (q.z * q.z + q.w * q.w)); // Yaw
v.X = (float) Math.Asin(2f * (q.x * q.z - q.w * q.y)); // Pitch
v.Z = (float) Math.Atan2(2f * q.x * q.y + 2f * q.z * q.w, 1 - 2f * (q.y * q.y + q.z * q.z)); // Roll
v.Y = (float) 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 = (float) MathF.Asin(2f * (q.x * q.z - q.w * q.y)); // Pitch
v.Z = (float) 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);
@@ -702,13 +758,45 @@ namespace Robust.Shared.Maths
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
@@ -723,6 +811,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion operator +(Quaternion left, Quaternion right)
{
left.Xyz += right.Xyz;
@@ -736,6 +825,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion operator -(Quaternion left, Quaternion right)
{
left.Xyz -= right.Xyz;
@@ -749,6 +839,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion operator *(Quaternion left, Quaternion right)
{
Multiply(ref left, ref right, out left);
@@ -761,6 +852,7 @@ namespace Robust.Shared.Maths
/// <param name="quaternion">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>A new instance containing the result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion operator *(Quaternion quaternion, float scale)
{
Multiply(ref quaternion, scale, out quaternion);
@@ -773,6 +865,7 @@ namespace Robust.Shared.Maths
/// <param name="quaternion">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>A new instance containing the result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Quaternion operator *(float scale, Quaternion quaternion)
{
return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
@@ -784,6 +877,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left equals right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Quaternion left, Quaternion right)
{
return left.Equals(right);
@@ -795,6 +889,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left does not equal right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Quaternion left, Quaternion right)
{
return !left.Equals(right);

View File

@@ -13,8 +13,9 @@
</PropertyGroup>
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
<PackageReference Include="CannyFastMath" Version="1.2.2" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -33,8 +35,8 @@ namespace Robust.Shared.Maths
public Vector2 TopLeft => new Vector2(Left, Top);
public Vector2 TopRight => new Vector2(Right, Top);
public Vector2 BottomLeft => new Vector2(Left, Bottom);
public float Width => Math.Abs(Right - Left);
public float Height => Math.Abs(Top - Bottom);
public float Width => MathF.Abs(Right - Left);
public float Height => MathF.Abs(Top - Bottom);
public Vector2 Size => new Vector2(Width, Height);
public Vector2 Center => TopLeft + Size / 2;

View File

@@ -1,4 +1,6 @@
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,5 +1,8 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -45,6 +48,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector2(float x, float y)
{
X = x;
@@ -54,16 +58,20 @@ namespace Robust.Shared.Maths
/// <summary>
/// Gets the length (magnitude) of the vector.
/// </summary>
#if NETCOREAPP
public float Length => MathF.Sqrt(LengthSquared);
#else
public float Length => (float) Math.Sqrt(LengthSquared);
#endif
public float Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MathF.Sqrt(LengthSquared);
}
/// <summary>
/// Gets the squared length of the vector.
/// </summary>
public float LengthSquared => X * X + Y * Y;
public float LengthSquared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => X * X + Y * Y;
}
/// <summary>
/// Returns a new, normalized, vector.
@@ -71,6 +79,7 @@ namespace Robust.Shared.Maths
/// <returns></returns>
public Vector2 Normalized
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
var length = Length;
@@ -78,9 +87,10 @@ namespace Robust.Shared.Maths
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector2 Rounded()
{
return new Vector2((float) Math.Round(X), (float) Math.Round(Y));
return new Vector2((float) MathF.Round(X), (float) MathF.Round(Y));
}
/// <summary>
@@ -88,6 +98,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="a">Vector to subtract from.</param>
/// <param name="b">Vector to subtract with.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator -(Vector2 a, Vector2 b)
{
return new Vector2(a.X - b.X, a.Y - b.Y);
@@ -98,6 +109,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="a">Vector to subtract from.</param>
/// <param name="b">Scalar to subtract with.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator -(Vector2 a, float b)
{
return new Vector2(a.X - b, a.Y - b);
@@ -106,6 +118,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Negates a vector.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator -(Vector2 vec)
{
return new Vector2(-vec.X, -vec.Y);
@@ -114,6 +127,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Adds two vectors together, returning a new vector with the components of each added together.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator +(Vector2 a, Vector2 b)
{
return new Vector2(a.X + b.X, a.Y + b.Y);
@@ -122,6 +136,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Adds a scalar to each component of a vector, returning a new vector.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator +(Vector2 a, float b)
{
return new Vector2(a.X + b, a.Y + b);
@@ -133,6 +148,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to multiply.</param>
/// <param name="scale">The scale to multiply with.</param>
/// <returns>A new vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator *(Vector2 vec, float scale)
{
return new Vector2(vec.X * scale, vec.Y * scale);
@@ -141,6 +157,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Multiplies a vector's components corresponding to a vector scale.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator *(Vector2 vec, Vector2 scale)
{
return new Vector2(vec.X * scale.X, vec.Y * scale.Y);
@@ -152,6 +169,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to divide.</param>
/// <param name="scale">The scale to divide by.</param>
/// <returns>A new vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator /(Vector2 vec, float scale)
{
return new Vector2(vec.X / scale, vec.Y / scale);
@@ -160,6 +178,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Divides a vector's components corresponding to a vector scale.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 operator /(Vector2 vec, Vector2 scale)
{
return new Vector2(vec.X / scale.X, vec.Y / scale.Y);
@@ -168,28 +187,31 @@ namespace Robust.Shared.Maths
/// <summary>
/// Return a vector made up of the smallest components of the provided vectors.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 ComponentMin(Vector2 a, Vector2 b)
{
return new Vector2(
a.X < b.X ? a.X : b.X,
a.Y < b.Y ? a.Y : b.Y
MathF.Min(a.X, b.X),
MathF.Min(a.Y, b.Y)
);
}
/// <summary>
/// Return a vector made up of the largest components of the provided vectors.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 ComponentMax(Vector2 a, Vector2 b)
{
return new Vector2(
a.X > b.X ? a.X : b.X,
a.Y > b.Y ? a.Y : b.Y
MathF.Max(a.X, b.X),
MathF.Max(a.Y, b.Y)
);
}
/// <summary>
/// Returns the vector with the smallest magnitude. If both have equal magnitude, <paramref name="b" /> is selected.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 MagnitudeMin(Vector2 a, Vector2 b)
{
return a.LengthSquared < b.LengthSquared ? a : b;
@@ -198,6 +220,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Returns the vector with the largest magnitude. If both have equal magnitude, <paramref name="a" /> is selected.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 MagnitudeMax(Vector2 a, Vector2 b)
{
return a.LengthSquared >= b.LengthSquared ? a : b;
@@ -209,6 +232,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">The vector to clamp.</param>
/// <param name="min">The lower bound vector.</param>
/// <param name="max">The upper bound vector.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Clamp(Vector2 vector, Vector2 min, Vector2 max)
{
return new Vector2(
@@ -220,6 +244,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Calculates the dot product of two vectors.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Dot(Vector2 a, Vector2 b)
{
return a.X * b.X + a.Y * b.Y;
@@ -231,14 +256,18 @@ namespace Robust.Shared.Maths
/// <returns>
/// a when factor=0, b when factor=1, a linear interpolation between the two otherwise.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Lerp(Vector2 a, Vector2 b, float factor)
{
return new Vector2(
factor * (b.X - a.X) + a.X,
factor * (b.Y - a.Y) + a.Y
//factor * (b.X - a.X) + a.X,
MathF.Interpolate(a.X, b.X, factor),
//factor * (b.Y - a.Y) + a.Y
MathF.Interpolate(a.Y, b.Y, factor)
);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 LerpClamped(in Vector2 a, in Vector2 b, float factor)
{
if (factor <= 0)
@@ -250,19 +279,20 @@ namespace Robust.Shared.Maths
return Lerp(a, b, factor);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 InterpolateCubic(Vector2 preA, Vector2 a, Vector2 b, Vector2 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;
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;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Deconstruct(out float x, out float y)
{
x = X;
y = Y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vector2((float x, float y) tuple)
{
var (x, y) = tuple;
@@ -277,11 +307,13 @@ namespace Robust.Shared.Maths
return $"({X}, {Y})";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector2 a, Vector2 b)
{
return a.Equals(b);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector2 a, Vector2 b)
{
return !a.Equals(b);
@@ -292,9 +324,12 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="other">Other vector to check.</param>
/// <returns>True if the two vectors are equal.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Vector2 other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return X == other.X && Y == other.Y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
@@ -302,6 +337,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="obj">Other object to check.</param>
/// <returns>True if Object and vector are equal.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj)
{
return obj is Vector2 vec && Equals(vec);
@@ -311,6 +347,7 @@ namespace Robust.Shared.Maths
/// Returns the hash code for this instance.
/// </summary>
/// <returns>A unique hash code for this instance.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
{
unchecked
@@ -319,11 +356,13 @@ namespace Robust.Shared.Maths
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EqualsApprox(Vector2 other)
{
return FloatMath.CloseTo(X, other.X) && FloatMath.CloseTo(Y, other.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EqualsApprox(Vector2 other, double tolerance)
{
return FloatMath.CloseTo(X, other.X, tolerance) && FloatMath.CloseTo(Y, other.Y, tolerance);

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,6 +1,8 @@
using System;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -1,6 +1,8 @@
using System;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -26,8 +26,11 @@ SOFTWARE.
#endregion
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -66,6 +69,7 @@ namespace Robust.Shared.Maths
/// Constructs a new instance.
/// </summary>
/// <param name="value">The value that will initialize this instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3(float value)
{
X = value;
@@ -79,6 +83,7 @@ namespace Robust.Shared.Maths
/// <param name="x">The x component of the Vector3.</param>
/// <param name="y">The y component of the Vector3.</param>
/// <param name="z">The z component of the Vector3.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3(float x, float y, float z)
{
X = x;
@@ -90,6 +95,7 @@ namespace Robust.Shared.Maths
/// Constructs a new Vector3 from the given Vector2.
/// </summary>
/// <param name="v">The Vector2 to copy components from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3(Vector2 v)
{
X = v.X;
@@ -101,6 +107,7 @@ namespace Robust.Shared.Maths
/// Constructs a new Vector3 from the given Vector3.
/// </summary>
/// <param name="v">The Vector3 to copy components from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3(Vector3 v)
{
X = v.X;
@@ -112,6 +119,7 @@ namespace Robust.Shared.Maths
/// Constructs a new Vector3 from the given Vector4.
/// </summary>
/// <param name="v">The Vector4 to copy components from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3(Vector4 v)
{
X = v.X;
@@ -119,6 +127,7 @@ namespace Robust.Shared.Maths
Z = v.Z;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Deconstruct(out float x, out float y, out float z)
{
x = X;
@@ -138,11 +147,11 @@ namespace Robust.Shared.Maths
/// Gets the length (magnitude) of the vector.
/// </summary>
/// <seealso cref="LengthSquared"/>
#if NETCOREAPP
public float Length => MathF.Sqrt(LengthSquared);
#else
public float Length => (float) Math.Sqrt(LengthSquared);
#endif
public float Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MathF.Sqrt(LengthSquared);
}
#endregion
#region public float LengthSquared
@@ -155,7 +164,11 @@ namespace Robust.Shared.Maths
/// for comparisons.
/// </remarks>
/// <see cref="Length"/>
public float LengthSquared => X * X + Y * Y + Z * Z;
public float LengthSquared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => X * X + Y * Y + Z * Z;
}
#endregion
@@ -164,6 +177,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Scales the Vector3 to unit length.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Normalize()
{
var scale = 1.0f / Length;
@@ -220,6 +234,7 @@ namespace Robust.Shared.Maths
/// <param name="a">Left operand.</param>
/// <param name="b">Right operand.</param>
/// <returns>Result of operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Add(Vector3 a, Vector3 b)
{
Add(ref a, ref b, out a);
@@ -232,6 +247,7 @@ namespace Robust.Shared.Maths
/// <param name="a">Left operand.</param>
/// <param name="b">Right operand.</param>
/// <param name="result">Result of operation.</param>
[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);
@@ -247,6 +263,7 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>Result of subtraction</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Subtract(Vector3 a, Vector3 b)
{
Subtract(ref a, ref b, out a);
@@ -259,6 +276,7 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">Result of subtraction</param>
[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);
@@ -274,6 +292,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Multiply(Vector3 vector, float scale)
{
Multiply(ref vector, scale, out vector);
@@ -286,6 +305,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -297,6 +317,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Multiply(Vector3 vector, Vector3 scale)
{
Multiply(ref vector, ref scale, out vector);
@@ -309,6 +330,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -324,6 +346,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Divide(Vector3 vector, float scale)
{
Divide(ref vector, scale, out vector);
@@ -336,6 +359,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Divide(ref Vector3 vector, float scale, out Vector3 result)
{
Multiply(ref vector, 1 / scale, out result);
@@ -347,6 +371,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Divide(Vector3 vector, Vector3 scale)
{
Divide(ref vector, ref scale, out vector);
@@ -359,6 +384,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -374,11 +400,12 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>The component-wise minimum</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 ComponentMin(Vector3 a, Vector3 b)
{
a.X = a.X < b.X ? a.X : b.X;
a.Y = a.Y < b.Y ? a.Y : b.Y;
a.Z = a.Z < b.Z ? a.Z : b.Z;
a.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;
}
@@ -388,11 +415,12 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">The component-wise minimum</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ComponentMin(ref Vector3 a, ref Vector3 b, out Vector3 result)
{
result.X = a.X < b.X ? a.X : b.X;
result.Y = a.Y < b.Y ? a.Y : b.Y;
result.Z = a.Z < b.Z ? a.Z : b.Z;
result.X = MathF.Min(a.X, b.X);
result.Y = MathF.Min(a.Y, b.Y);
result.Z = MathF.Min(a.Z, b.Z);
}
#endregion
@@ -405,11 +433,12 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>The component-wise maximum</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 ComponentMax(Vector3 a, Vector3 b)
{
a.X = a.X > b.X ? a.X : b.X;
a.Y = a.Y > b.Y ? a.Y : b.Y;
a.Z = a.Z > b.Z ? a.Z : b.Z;
a.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;
}
@@ -419,11 +448,12 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">The component-wise maximum</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ComponentMax(ref Vector3 a, ref Vector3 b, out Vector3 result)
{
result.X = a.X > b.X ? a.X : b.X;
result.Y = a.Y > b.Y ? a.Y : b.Y;
result.Z = a.Z > b.Z ? a.Z : b.Z;
result.X = MathF.Max(a.X, b.X);
result.Y = MathF.Max(a.Y, b.Y);
result.Z = MathF.Max(a.Z, b.Z);
}
#endregion
@@ -436,6 +466,7 @@ namespace Robust.Shared.Maths
/// <param name="left">Left operand</param>
/// <param name="right">Right operand</param>
/// <returns>The minimum Vector3</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Min(Vector3 left, Vector3 right)
{
return left.LengthSquared < right.LengthSquared ? left : right;
@@ -451,6 +482,7 @@ namespace Robust.Shared.Maths
/// <param name="left">Left operand</param>
/// <param name="right">Right operand</param>
/// <returns>The minimum Vector3</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Max(Vector3 left, Vector3 right)
{
return left.LengthSquared >= right.LengthSquared ? left : right;
@@ -467,11 +499,12 @@ namespace Robust.Shared.Maths
/// <param name="min">Minimum vector</param>
/// <param name="max">Maximum vector</param>
/// <returns>The clamped vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Clamp(Vector3 vec, Vector3 min, Vector3 max)
{
vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
vec.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
vec.X = MathF.Clamp(vec.X, min.X, max.X);
vec.Y = MathF.Clamp(vec.Y, min.Y, max.Y);
vec.Z = MathF.Clamp(vec.Z, min.Z, max.Z);
return vec;
}
@@ -482,11 +515,12 @@ namespace Robust.Shared.Maths
/// <param name="min">Minimum vector</param>
/// <param name="max">Maximum vector</param>
/// <param name="result">The clamped vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Clamp(ref Vector3 vec, ref Vector3 min, ref Vector3 max, out Vector3 result)
{
result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
result.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
result.X = MathF.Clamp(vec.X, min.X, max.X);
result.Y = MathF.Clamp(vec.Y, min.Y, max.Y);
result.Z = MathF.Clamp(vec.Z, min.Z, max.Z);
}
#endregion
@@ -498,6 +532,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The input vector</param>
/// <returns>The normalized vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Normalize(Vector3 vec)
{
var scale = 1.0f / vec.Length;
@@ -512,6 +547,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The input vector</param>
/// <param name="result">The normalized vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Normalize(ref Vector3 vec, out Vector3 result)
{
var scale = 1.0f / vec.Length;
@@ -530,6 +566,7 @@ namespace Robust.Shared.Maths
/// <param name="left">First operand</param>
/// <param name="right">Second operand</param>
/// <returns>The dot product of the two inputs</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Dot(Vector3 left, Vector3 right)
{
return left.X * right.X + left.Y * right.Y + left.Z * right.Z;
@@ -541,6 +578,7 @@ namespace Robust.Shared.Maths
/// <param name="left">First operand</param>
/// <param name="right">Second operand</param>
/// <param name="result">The dot product of the two inputs</param>
[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;
@@ -556,6 +594,7 @@ namespace Robust.Shared.Maths
/// <param name="left">First operand</param>
/// <param name="right">Second operand</param>
/// <returns>The cross product of the two inputs</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Cross(Vector3 left, Vector3 right)
{
Cross(ref left, ref right, out var result);
@@ -569,6 +608,7 @@ namespace Robust.Shared.Maths
/// <param name="right">Second operand</param>
/// <returns>The cross product of the two inputs</returns>
/// <param name="result">The cross product of the two inputs</param>
[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,
@@ -587,11 +627,12 @@ namespace Robust.Shared.Maths
/// <param name="b">Second input vector</param>
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
/// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Lerp(Vector3 a, Vector3 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.X = MathF.Interpolate(a.X, b.X, blend);
a.Y = MathF.Interpolate(a.Y, b.Y, blend);
a.Z = MathF.Interpolate(a.Z, b.Z, blend);
return a;
}
@@ -602,13 +643,15 @@ namespace Robust.Shared.Maths
/// <param name="b">Second input vector</param>
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
/// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Lerp(ref Vector3 a, ref Vector3 b, float blend, out Vector3 result)
{
result.X = blend * (b.X - a.X) + a.X;
result.Y = blend * (b.Y - a.Y) + a.Y;
result.Z = blend * (b.Z - a.Z) + a.Z;
result.X = MathF.Interpolate(a.X, b.X, blend);
result.Y = MathF.Interpolate(a.Y, b.Y, blend);
result.Z = MathF.Interpolate(a.Z, b.Z, blend);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 InterpolateCubic(Vector3 preA, Vector3 a, Vector3 b, Vector3 postB, float t)
{
return a +
@@ -629,6 +672,7 @@ namespace Robust.Shared.Maths
/// <param name="u">First Barycentric Coordinate</param>
/// <param name="v">Second Barycentric Coordinate</param>
/// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
[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);
@@ -641,6 +685,7 @@ namespace Robust.Shared.Maths
/// <param name="u">First Barycentric Coordinate.</param>
/// <param name="v">Second Barycentric Coordinate.</param>
/// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
[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
@@ -666,6 +711,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 TransformVector(Vector3 vec, Matrix4 mat)
{
Vector3 v;
@@ -681,6 +727,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void TransformVector(ref Vector3 vec, ref Matrix4 mat, out Vector3 result)
{
result.X = vec.X * mat.Row0.X +
@@ -704,6 +751,7 @@ namespace Robust.Shared.Maths
/// <param name="norm">The normal to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed normal</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 TransformNormal(Vector3 norm, Matrix4 mat)
{
mat.Invert();
@@ -718,6 +766,7 @@ namespace Robust.Shared.Maths
/// <param name="norm">The normal to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed normal</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void TransformNormal(ref Vector3 norm, ref Matrix4 mat, out Vector3 result)
{
var inverse = Matrix4.Invert(mat);
@@ -732,6 +781,7 @@ namespace Robust.Shared.Maths
/// <param name="norm">The normal to transform</param>
/// <param name="invMat">The inverse of the desired transformation</param>
/// <returns>The transformed normal</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 TransformNormalInverse(Vector3 norm, Matrix4 invMat)
{
Vector3 n;
@@ -749,6 +799,7 @@ namespace Robust.Shared.Maths
/// <param name="norm">The normal to transform</param>
/// <param name="invMat">The inverse of the desired transformation</param>
/// <param name="result">The transformed normal</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void TransformNormalInverse(ref Vector3 norm, ref Matrix4 invMat, out Vector3 result)
{
result.X = norm.X * invMat.Row0.X +
@@ -768,6 +819,7 @@ namespace Robust.Shared.Maths
/// <param name="pos">The position to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed position</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 TransformPosition(Vector3 pos, Matrix4 mat)
{
Vector3 p;
@@ -781,6 +833,7 @@ namespace Robust.Shared.Maths
/// <param name="pos">The position to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed position</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void TransformPosition(ref Vector3 pos, ref Matrix4 mat, out Vector3 result)
{
result.X = pos.X * mat.Row0.X +
@@ -803,6 +856,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Transform(Vector3 vec, Matrix4 mat)
{
Transform(ref vec, ref mat, out Vector3 result);
@@ -813,6 +867,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed vector</param>
[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);
@@ -823,6 +878,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed vector</param>
[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);
@@ -836,6 +892,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform.</param>
/// <param name="quat">The quaternion to rotate the vector by.</param>
/// <returns>The result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Transform(Vector3 vec, Quaternion quat)
{
Transform(ref vec, ref quat, out var result);
@@ -848,6 +905,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform.</param>
/// <param name="quat">The quaternion to rotate the vector by.</param>
/// <param name="result">The result of the operation.</param>
[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:
@@ -865,6 +923,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 TransformPerspective(Vector3 vec, Matrix4 mat)
{
TransformPerspective(ref vec, ref mat, out var result);
@@ -875,6 +934,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void TransformPerspective(ref Vector3 vec, ref Matrix4 mat, out Vector3 result)
{
var v = new Vector4(vec, 1);
@@ -895,9 +955,10 @@ namespace Robust.Shared.Maths
/// <param name="second">The second vector.</param>
/// <returns>Angle (in radians) between the vectors.</returns>
/// <remarks>Note that the returned angle is never bigger than the constant Pi.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float CalculateAngle(Vector3 first, Vector3 second)
{
return (float) Math.Acos(Dot(first, second) / (first.Length * second.Length));
return (float) MathF.Acos(Dot(first, second) / (first.Length * second.Length));
}
/// <summary>Calculates the angle (in radians) between two vectors.</summary>
@@ -905,10 +966,11 @@ namespace Robust.Shared.Maths
/// <param name="second">The second vector.</param>
/// <param name="result">Angle (in radians) between the vectors.</param>
/// <remarks>Note that the returned angle is never bigger than the constant Pi.</remarks>
[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 = (float) Math.Acos(temp / (first.Length * second.Length));
result = (float) MathF.Acos(temp / (first.Length * second.Length));
}
#endregion
@@ -923,7 +985,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public Vector2 Xy
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(X, Y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
X = value.X;
@@ -941,6 +1005,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator +(Vector3 left, Vector3 right)
{
left.X += right.X;
@@ -955,6 +1020,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator -(Vector3 left, Vector3 right)
{
left.X -= right.X;
@@ -968,6 +1034,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator -(Vector3 vec)
{
vec.X = -vec.X;
@@ -982,6 +1049,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator *(Vector3 vec, float scale)
{
vec.X *= scale;
@@ -996,6 +1064,7 @@ namespace Robust.Shared.Maths
/// <param name="scale">The scalar.</param>
/// <param name="vec">The instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator *(float scale, Vector3 vec)
{
vec.X *= scale;
@@ -1007,6 +1076,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Component wise multiply two vectors.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator *(Vector3 a, Vector3 b)
{
return new Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
@@ -1018,6 +1088,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 operator /(Vector3 vec, float scale)
{
var mult = 1.0f / scale;
@@ -1033,6 +1104,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left equals right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector3 left, Vector3 right)
{
return left.Equals(right);
@@ -1044,6 +1116,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left does not equa lright; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector3 left, Vector3 right)
{
return !left.Equals(right);

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -25,8 +25,11 @@ SOFTWARE.
#endregion --- License ---
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -103,6 +106,7 @@ namespace Robust.Shared.Maths
/// Constructs a new instance.
/// </summary>
/// <param name="value">The value that will initialize this instance.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(float value)
{
X = value;
@@ -118,6 +122,7 @@ namespace Robust.Shared.Maths
/// <param name="y">The y component of the Vector4.</param>
/// <param name="z">The z component of the Vector4.</param>
/// <param name="w">The w component of the Vector4.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(float x, float y, float z, float w)
{
X = x;
@@ -130,6 +135,7 @@ namespace Robust.Shared.Maths
/// Constructs a new Vector4 from the given Vector2.
/// </summary>
/// <param name="v">The Vector2 to copy components from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(Vector2 v)
{
X = v.X;
@@ -144,6 +150,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="v">The Vector3 to copy components from.</param>
/// <remarks><seealso cref="Vector4(Vector3, float)"/></remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(Vector3 v)
{
X = v.X;
@@ -157,6 +164,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="v">The Vector3 to copy components from.</param>
/// <param name="w">The w component of the new Vector4.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(Vector3 v, float w)
{
X = v.X;
@@ -169,6 +177,7 @@ namespace Robust.Shared.Maths
/// Constructs a new Vector4 from the given Vector4.
/// </summary>
/// <param name="v">The Vector4 to copy components from.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4(Vector4 v)
{
X = v.X;
@@ -177,6 +186,7 @@ namespace Robust.Shared.Maths
W = v.W;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Deconstruct(out float x, out float y, out float z, out float w)
{
x = X;
@@ -185,6 +195,7 @@ namespace Robust.Shared.Maths
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;
@@ -203,11 +214,11 @@ namespace Robust.Shared.Maths
/// Gets the length (magnitude) of the vector.
/// </summary>
/// <seealso cref="LengthSquared"/>
#if NETCOREAPP
public float Length => MathF.Sqrt(LengthSquared);
#else
public float Length => (float) Math.Sqrt(LengthSquared);
#endif
public float Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MathF.Sqrt(LengthSquared);
}
#endregion public float Length
@@ -221,7 +232,11 @@ namespace Robust.Shared.Maths
/// for comparisons.
/// </remarks>
/// <see cref="Length"/>
public float LengthSquared => X * X + Y * Y + Z * Z + W * W;
public float LengthSquared
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => X * X + Y * Y + Z * Z + W * W;
}
#endregion public float LengthSquared
@@ -230,6 +245,7 @@ namespace Robust.Shared.Maths
/// <summary>
/// Scales the Vector4 to unit length.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Normalize()
{
var scale = 1.0f / Length;
@@ -253,6 +269,7 @@ namespace Robust.Shared.Maths
/// <param name="a">Left operand.</param>
/// <param name="b">Right operand.</param>
/// <returns>Result of operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Add(Vector4 a, Vector4 b)
{
Add(ref a, ref b, out a);
@@ -265,6 +282,7 @@ namespace Robust.Shared.Maths
/// <param name="a">Left operand.</param>
/// <param name="b">Right operand.</param>
/// <param name="result">Result of operation.</param>
[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);
@@ -280,6 +298,7 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>Result of subtraction</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Subtract(Vector4 a, Vector4 b)
{
Subtract(ref a, ref b, out a);
@@ -292,6 +311,7 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">Result of subtraction</param>
[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);
@@ -307,6 +327,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Multiply(Vector4 vector, float scale)
{
Multiply(ref vector, scale, out vector);
@@ -319,6 +340,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -330,6 +352,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Multiply(Vector4 vector, Vector4 scale)
{
Multiply(ref vector, ref scale, out vector);
@@ -342,6 +365,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -357,6 +381,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Divide(Vector4 vector, float scale)
{
Divide(ref vector, scale, out vector);
@@ -369,6 +394,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Divide(ref Vector4 vector, float scale, out Vector4 result)
{
Multiply(ref vector, 1 / scale, out result);
@@ -380,6 +406,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <returns>Result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Divide(Vector4 vector, Vector4 scale)
{
Divide(ref vector, ref scale, out vector);
@@ -392,6 +419,7 @@ namespace Robust.Shared.Maths
/// <param name="vector">Left operand.</param>
/// <param name="scale">Right operand.</param>
/// <param name="result">Result of the operation.</param>
[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);
@@ -407,12 +435,13 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>The component-wise minimum</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Min(Vector4 a, Vector4 b)
{
a.X = a.X < b.X ? a.X : b.X;
a.Y = a.Y < b.Y ? a.Y : b.Y;
a.Z = a.Z < b.Z ? a.Z : b.Z;
a.W = a.W < b.W ? a.W : b.W;
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;
}
@@ -422,12 +451,13 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">The component-wise minimum</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
{
result.X = a.X < b.X ? a.X : b.X;
result.Y = a.Y < b.Y ? a.Y : b.Y;
result.Z = a.Z < b.Z ? a.Z : b.Z;
result.W = a.W < b.W ? a.W : b.W;
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
@@ -440,12 +470,13 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <returns>The component-wise maximum</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Max(Vector4 a, Vector4 b)
{
a.X = a.X > b.X ? a.X : b.X;
a.Y = a.Y > b.Y ? a.Y : b.Y;
a.Z = a.Z > b.Z ? a.Z : b.Z;
a.W = a.W > b.W ? a.W : b.W;
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;
}
@@ -455,12 +486,13 @@ namespace Robust.Shared.Maths
/// <param name="a">First operand</param>
/// <param name="b">Second operand</param>
/// <param name="result">The component-wise maximum</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
{
result.X = a.X > b.X ? a.X : b.X;
result.Y = a.Y > b.Y ? a.Y : b.Y;
result.Z = a.Z > b.Z ? a.Z : b.Z;
result.W = a.W > b.W ? a.W : b.W;
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
@@ -474,12 +506,13 @@ namespace Robust.Shared.Maths
/// <param name="min">Minimum vector</param>
/// <param name="max">Maximum vector</param>
/// <returns>The clamped vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
{
vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
vec.X = MathF.Clamp( vec.X, min.X, max.X );
vec.Y = MathF.Clamp( vec.Y, min.Y, max.Y );
vec.Z = MathF.Clamp( vec.Z, min.Z, max.Z );
vec.W = MathF.Clamp( vec.W, min.W, max.W );
return vec;
}
@@ -490,12 +523,13 @@ namespace Robust.Shared.Maths
/// <param name="min">Minimum vector</param>
/// <param name="max">Maximum vector</param>
/// <param name="result">The clamped vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
{
result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
result.X = MathF.Clamp( vec.X, min.X, max.X );
result.Y = MathF.Clamp( vec.Y, min.Y, max.Y );
result.Z = MathF.Clamp( vec.Z, min.Z, max.Z );
result.W = MathF.Clamp( vec.W, min.W, max.W );
}
#endregion Clamp
@@ -507,6 +541,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The input vector</param>
/// <returns>The normalized vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Normalize(Vector4 vec)
{
var scale = 1.0f / vec.Length;
@@ -522,6 +557,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The input vector</param>
/// <param name="result">The normalized vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Normalize(ref Vector4 vec, out Vector4 result)
{
var scale = 1.0f / vec.Length;
@@ -541,6 +577,7 @@ namespace Robust.Shared.Maths
/// <param name="left">First operand</param>
/// <param name="right">Second operand</param>
/// <returns>The dot product of the two inputs</returns>
[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;
@@ -568,6 +605,7 @@ namespace Robust.Shared.Maths
/// <param name="b">Second input vector</param>
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
/// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
{
a.X = blend * (b.X - a.X) + a.X;
@@ -584,14 +622,16 @@ namespace Robust.Shared.Maths
/// <param name="b">Second input vector</param>
/// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
/// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result)
{
result.X = blend * (b.X - a.X) + a.X;
result.Y = blend * (b.Y - a.Y) + a.Y;
result.Z = blend * (b.Z - a.Z) + a.Z;
result.W = blend * (b.W - a.W) + a.W;
result.X = MathF.Interpolate(a.X, b.X, blend);
result.Y = MathF.Interpolate(a.Y, b.Y, blend);
result.Z = MathF.Interpolate(a.Z, b.Z, blend);
result.W = MathF.Interpolate(a.W, b.W, blend);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 InterpolateCubic(Vector4 preA, Vector4 a, Vector4 b, Vector4 postB, float t)
{
return a +
@@ -612,6 +652,7 @@ namespace Robust.Shared.Maths
/// <param name="u">First Barycentric Coordinate</param>
/// <param name="v">Second Barycentric Coordinate</param>
/// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
[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);
@@ -624,6 +665,7 @@ namespace Robust.Shared.Maths
/// <param name="u">First Barycentric Coordinate.</param>
/// <param name="v">Second Barycentric Coordinate.</param>
/// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
[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
@@ -647,6 +689,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <returns>The transformed vector</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Transform(Vector4 vec, Matrix4 mat)
{
Transform(ref vec, ref mat, out var result);
@@ -657,6 +700,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform</param>
/// <param name="mat">The desired transformation</param>
/// <param name="result">The transformed vector</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result)
{
result = new Vector4(
@@ -672,6 +716,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform.</param>
/// <param name="quat">The quaternion to rotate the vector by.</param>
/// <returns>The result of the operation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Transform(Vector4 vec, Quaternion quat)
{
Transform(ref vec, ref quat, out var result);
@@ -684,6 +729,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The vector to transform.</param>
/// <param name="quat">The quaternion to rotate the vector by.</param>
/// <param name="result">The result of the operation.</param>
[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);
@@ -706,7 +752,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public Vector2 Xy
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector2(X, Y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
X = value.X;
@@ -720,7 +768,9 @@ namespace Robust.Shared.Maths
[XmlIgnore]
public Vector3 Xyz
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vector3(X, Y, Z);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
X = value.X;
@@ -739,6 +789,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator +(Vector4 left, Vector4 right)
{
left.X += right.X;
@@ -754,6 +805,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator -(Vector4 left, Vector4 right)
{
left.X -= right.X;
@@ -768,6 +820,7 @@ namespace Robust.Shared.Maths
/// </summary>
/// <param name="vec">The instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator -(Vector4 vec)
{
vec.X = -vec.X;
@@ -783,6 +836,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator *(Vector4 vec, float scale)
{
vec.X *= scale;
@@ -798,6 +852,7 @@ namespace Robust.Shared.Maths
/// <param name="scale">The scalar.</param>
/// <param name="vec">The instance.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator *(float scale, Vector4 vec)
{
vec.X *= scale;
@@ -813,6 +868,7 @@ namespace Robust.Shared.Maths
/// <param name="vec">The instance.</param>
/// <param name="scale">The scalar.</param>
/// <returns>The result of the calculation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator /(Vector4 vec, float scale)
{
var mult = 1.0f / scale;
@@ -829,6 +885,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left equals right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector4 left, Vector4 right)
{
return left.Equals(right);
@@ -840,6 +897,7 @@ namespace Robust.Shared.Maths
/// <param name="left">The first instance.</param>
/// <param name="right">The second instance.</param>
/// <returns>True, if left does not equal right; false otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector4 left, Vector4 right)
{
return !left.Equals(right);

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.InteropServices;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{

View File

@@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="3.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.5.0" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>

View File

@@ -38,6 +38,8 @@ using FN_DECIMAL = System.Single;
#endif
using System;
using System.Runtime.CompilerServices;
using MathI = CannyFastMath.Math;
using Math = CannyFastMath.MathF;
namespace Robust.Shared.Noise
{
@@ -218,11 +220,11 @@ namespace Robust.Shared.Noise
// Both indicies must be >= 0, index1 must be < 4
public void SetCellularDistance2Indicies(int cellularDistanceIndex0, int cellularDistanceIndex1)
{
m_cellularDistanceIndex0 = Math.Min(cellularDistanceIndex0, cellularDistanceIndex1);
m_cellularDistanceIndex1 = Math.Max(cellularDistanceIndex0, cellularDistanceIndex1);
m_cellularDistanceIndex0 = MathI.Min(cellularDistanceIndex0, cellularDistanceIndex1);
m_cellularDistanceIndex1 = MathI.Max(cellularDistanceIndex0, cellularDistanceIndex1);
m_cellularDistanceIndex0 = Math.Min(Math.Max(m_cellularDistanceIndex0, 0), FN_CELLULAR_INDEX_MAX);
m_cellularDistanceIndex1 = Math.Min(Math.Max(m_cellularDistanceIndex1, 0), FN_CELLULAR_INDEX_MAX);
m_cellularDistanceIndex0 = MathI.Min(MathI.Max(m_cellularDistanceIndex0, 0), FN_CELLULAR_INDEX_MAX);
m_cellularDistanceIndex1 = MathI.Min(MathI.Max(m_cellularDistanceIndex1, 0), FN_CELLULAR_INDEX_MAX);
}
// Sets the maximum distance a cellular point can move from it's grid position

View File

@@ -1,6 +1,8 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Maths;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Noise
{
@@ -91,7 +93,7 @@ namespace Robust.Shared.Noise
const float dx = x2 - x1;
const float dy = y2 - y1;
const float tau = (float)Math.PI * 2;
const float tau = (float) Math.TAU; //(float)Math.PI * 2;
const float dxTau = dx / tau;
const float dyTau = dy / tau;

View File

@@ -26,6 +26,8 @@ using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Physics
{

View File

@@ -1,6 +1,8 @@
using Robust.Shared.Map;
using Robust.Shared.Utility;
using System;
using Math = CannyFastMath.Math;
using MathF = CannyFastMath.MathF;
namespace Robust.Shared.Maths
{
@@ -50,10 +52,10 @@ namespace Robust.Shared.Maths
// X axis slab
{
if (Math.Abs(_direction.X) < epsilon)
if (MathF.Abs(_direction.X) < epsilon)
{
// ray is parallel to this slab, it will never hit unless ray is inside box
if (_position.X < Math.Min(box.Left, box.Right) || _position.X > Math.Max(box.Left, box.Right))
if (_position.X < MathF.Min(box.Left, box.Right) || _position.X > MathF.Max(box.Left, box.Right))
{
return false;
}
@@ -61,16 +63,16 @@ namespace Robust.Shared.Maths
// calculate intersection t value of ray with near and far plane of slab
var ood = 1.0f / _direction.X;
var t1 = (Math.Min(box.Left, box.Right) - _position.X) * ood;
var t2 = (Math.Max(box.Left, box.Right) - _position.X) * ood;
var t1 = (MathF.Min(box.Left, box.Right) - _position.X) * ood;
var t2 = (MathF.Max(box.Left, box.Right) - _position.X) * ood;
// Make t1 be the intersection with near plane, t2 with far plane
if (t1 > t2)
MathHelper.Swap(ref t1, ref t2);
// Compute the intersection of slab intersection intervals
tmin = Math.Max(t1, tmin);
tmax = Math.Min(t2, tmax); // Is this Min (SE) or Max(Textbook)
tmin = MathF.Max(t1, tmin);
tmax = MathF.Min(t2, tmax); // Is this Min (SE) or Max(Textbook)
// Exit with no collision as soon as slab intersection becomes empty
if (tmin > tmax)
@@ -81,10 +83,10 @@ namespace Robust.Shared.Maths
// Y axis slab
{
if (Math.Abs(_direction.Y) < epsilon)
if (MathF.Abs(_direction.Y) < epsilon)
{
// ray is parallel to this slab, it will never hit unless ray is inside box
if (_position.Y < Math.Min(box.Top, box.Bottom) || _position.Y > Math.Max(box.Top, box.Bottom))
if (_position.Y < MathF.Min(box.Top, box.Bottom) || _position.Y > MathF.Max(box.Top, box.Bottom))
{
return false;
}
@@ -92,16 +94,16 @@ namespace Robust.Shared.Maths
// calculate intersection t value of ray with near and far plane of slab
var ood = 1.0f / _direction.Y;
var t1 = (Math.Min(box.Top, box.Bottom) - _position.Y) * ood;
var t2 = (Math.Max(box.Top, box.Bottom) - _position.Y) * ood;
var t1 = (MathF.Min(box.Top, box.Bottom) - _position.Y) * ood;
var t2 = (MathF.Max(box.Top, box.Bottom) - _position.Y) * ood;
// Make t1 be the intersection with near plane, t2 with far plane
if (t1 > t2)
MathHelper.Swap(ref t1, ref t2);
// Compute the intersection of slab intersection intervals
tmin = Math.Max(t1, tmin);
tmax = Math.Min(t2, tmax); // Is this Min (SE) or Max(Textbook)
tmin = MathF.Max(t1, tmin);
tmax = MathF.Min(t2, tmax); // Is this Min (SE) or Max(Textbook)
// Exit with no collision as soon as slab intersection becomes empty
if (tmin > tmax)

View File

@@ -12,18 +12,18 @@
</PropertyGroup>
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="NetSerializer" Version="4.1.1" />
<PackageReference Include="Nett" Version="0.13.0" />
<PackageReference Include="Nett" Version="0.15.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="nfluidsynth" Version="0.3.0" />
<PackageReference Include="NGettext" Version="0.6.5" />
<PackageReference Include="Pidgin" Version="2.2.0" />
<PackageReference Include="Pidgin" Version="2.4.0" />
<PackageReference Include="prometheus-net" Version="3.5.0" />
<PackageReference Include="Robust.Shared.AuthLib" Version="0.1.0" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Memory" Version="4.5.3" />
<PackageReference Include="YamlDotNet" Version="8.1.0" />
<PackageReference Include="YamlDotNet" Version="8.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />

View File

@@ -13,7 +13,7 @@
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.0" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Microsoft.CodeCoverage" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Moq" Version="4.13.1" />
@@ -24,7 +24,7 @@
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Threading.Channels" Version="4.5.0" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
<PackageReference Include="YamlDotNet" Version="8.1.0" />
<PackageReference Include="YamlDotNet" Version="8.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />

View File

@@ -87,10 +87,14 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
// if they are parented, the child keeps its world position, but moves to the parents map
childTrans.AttachParent(parentTrans);
Assert.That(childTrans.MapID, Is.EqualTo(parentTrans.MapID));
Assert.That(childTrans.GridID, Is.EqualTo(parentTrans.GridID));
Assert.That(childTrans.GridPosition, Is.EqualTo(new GridCoordinates(4, 4, GridA)));
Assert.That(childTrans.WorldPosition, Is.EqualTo(new Vector2(4, 4)));
Assert.Multiple(() =>
{
Assert.That(childTrans.MapID, Is.EqualTo(parentTrans.MapID));
Assert.That(childTrans.GridID, Is.EqualTo(parentTrans.GridID));
Assert.That(childTrans.GridPosition, Is.EqualTo(new GridCoordinates(4, 4, GridA)));
Assert.That(childTrans.WorldPosition, Is.EqualTo(new Vector2(4, 4)));
});
// move the parent, and the child should move with it
childTrans.WorldPosition = new Vector2(6, 6);
@@ -105,8 +109,12 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
childTrans.DetachParent();
// the gridId won't match, because we just detached from the grid entity
Assert.That(childTrans.GridPosition.Position, Is.EqualTo(oldLpos.Position));
Assert.That(childTrans.WorldPosition, Is.EqualTo(oldWpos));
Assert.Multiple(() =>
{
Assert.That(childTrans.GridPosition.Position, Is.EqualTo(oldLpos.Position));
Assert.That(childTrans.WorldPosition, Is.EqualTo(oldWpos));
});
}
/// <summary>
@@ -152,8 +160,11 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
//Assert
var result = childTrans.WorldPosition;
Assert.That(FloatMath.CloseTo(result.X, 0), result.ToString);
Assert.That(FloatMath.CloseTo(result.Y, 2), result.ToString);
Assert.Multiple(() =>
{
Assert.That(FloatMath.CloseTo(result.X, 0));
Assert.That(FloatMath.CloseTo(result.Y, 2));
});
}
/// <summary>
@@ -176,8 +187,11 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
//Assert
var result = childTrans.WorldPosition;
Assert.That(FloatMath.CloseTo(result.X, 1), result.ToString);
Assert.That(FloatMath.CloseTo(result.Y, 2), result.ToString);
Assert.Multiple(() =>
{
Assert.That(FloatMath.CloseTo(result.X, 1));
Assert.That(FloatMath.CloseTo(result.Y, 2));
});
}
/// <summary>
@@ -211,8 +225,12 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
//Assert
var result = node4Trans.WorldPosition;
Assert.That(result.X, new ApproxEqualityConstraint(-2f));
Assert.That(result.Y, new ApproxEqualityConstraint(0f));
Assert.Multiple(() =>
{
Assert.That(result.X, new ApproxEqualityConstraint(-2f));
Assert.That(result.Y, new ApproxEqualityConstraint(0f));
});
}
/// <summary>
@@ -251,8 +269,11 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var newWpos = node3Trans.WorldPosition;
// Assert
Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y), newWpos.ToString);
Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y), newWpos.ToString);
Assert.Multiple(() =>
{
Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y), newWpos.ToString);
Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y), newWpos.ToString);
});
}
/// <summary>
@@ -294,8 +315,12 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
//NOTE: Yes, this does cause a non-zero error
// Assert
Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y), newWpos.ToString);
Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y), newWpos.ToString);
Assert.Multiple(() =>
{
Assert.That(FloatMath.CloseTo(oldWpos.X, newWpos.Y));
Assert.That(FloatMath.CloseTo(oldWpos.Y, newWpos.Y));
});
}
/// <summary>
@@ -337,11 +362,15 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
Matrix3.Multiply(ref invWorldMat, ref worldMat, out var rightVerifyMatrix);
//Assert
// these should be the same (A × A-1 = A-1 × A = I)
Assert.That(leftVerifyMatrix, new ApproxEqualityConstraint(rightVerifyMatrix));
// verify matrix == identity matrix (or very close to because float precision)
Assert.That(leftVerifyMatrix, new ApproxEqualityConstraint(control));
Assert.Multiple(() =>
{
// these should be the same (A × A-1 = A-1 × A = I)
Assert.That(leftVerifyMatrix, new ApproxEqualityConstraint(rightVerifyMatrix));
// verify matrix == identity matrix (or very close to because float precision)
Assert.That(leftVerifyMatrix, new ApproxEqualityConstraint(control));
});
}
/// <summary>