mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-11 07:48:36 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
233 lines
5.3 KiB
C#
233 lines
5.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace TestSystem.Math;
|
|
|
|
[TestClass]
|
|
public class RotationTest
|
|
{
|
|
private static bool AlmostEqual( float a, float b, float precision = 0.0001f )
|
|
{
|
|
return a.AlmostEqual( b, 0.001f );
|
|
}
|
|
|
|
private static bool AlmostEqual( Rotation a, Rotation b )
|
|
{
|
|
var forward = a.Forward.Dot( b.Forward );
|
|
var right = a.Right.Dot( b.Right );
|
|
var up = a.Up.Dot( b.Up );
|
|
|
|
return AlmostEqual( forward, 1f ) && AlmostEqual( right, 1f ) && AlmostEqual( up, 1f );
|
|
}
|
|
|
|
private static bool AlmostEqual( Angles a, Angles b )
|
|
{
|
|
return AlmostEqual( a.yaw, b.yaw ) && AlmostEqual( a.pitch, b.pitch ) && AlmostEqual( a.roll, b.roll );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a bunch of rotations, and make sure they return trip from euler angles.
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void AnglesRandom()
|
|
{
|
|
SandboxSystem.SetRandomSeed( 123456 );
|
|
|
|
for ( var i = 0; i < 1_000_000; ++i )
|
|
{
|
|
var srcRotation = Rotation.Random;
|
|
var angles = srcRotation.Angles();
|
|
var dstRotation = angles.ToRotation();
|
|
|
|
Assert.IsTrue( AlmostEqual( srcRotation, dstRotation ) );
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ParseAngles()
|
|
{
|
|
{
|
|
Rotation r = Rotation.Parse( "5,3,2" );
|
|
var angles = new Angles( 5, 3, 2 );
|
|
|
|
Assert.IsTrue( AlmostEqual( r.Angles(), angles ) );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "5, 3, 2" );
|
|
var angles = new Angles( 5, 3, 2 );
|
|
|
|
Assert.IsTrue( AlmostEqual( r.Angles(), angles ) );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[5,3,2]" );
|
|
var angles = new Angles( 5, 3, 2 );
|
|
|
|
Assert.IsTrue( AlmostEqual( r.Angles(), angles ) );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[ 5, 3, 2] " );
|
|
var angles = new Angles( 5, 3, 2 );
|
|
|
|
Assert.IsTrue( AlmostEqual( r.Angles(), angles ) );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[ 5,\n\r 3,\n\r 2,\n\r ] " );
|
|
var angles = new Angles( 5, 3, 2 );
|
|
|
|
Assert.IsTrue( AlmostEqual( r.Angles(), angles ) );
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test converting to and from angles near +-90 pitch.
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void AnglesPoles()
|
|
{
|
|
for ( var pitch = 87f; pitch <= 100f; pitch += 1f / 1024f )
|
|
{
|
|
for ( var yaw = -180; yaw < 180; yaw += 1 )
|
|
{
|
|
for ( var sign = -1; sign <= 1; sign += 2 )
|
|
{
|
|
var srcRotation = new Angles( pitch * sign, yaw, 0f ).ToRotation();
|
|
var angles = srcRotation.Angles();
|
|
var dstRotation = angles.ToRotation();
|
|
|
|
Assert.IsTrue( AlmostEqual( srcRotation, dstRotation ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test converting to and from tricky angles against other engines
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void AnglesParity()
|
|
{
|
|
// Unity poles but not normalized
|
|
var list = new List<(Angles, Angles)>()
|
|
{
|
|
new( new( 90, 112, 19 ), new( 90, 93, 0 ) ),
|
|
new( new( 90, 12, 180 ), new( 90, -168, 0 ) ),
|
|
new( new( -90, 90, -60 ), new( -90, 30, 0 ) ),
|
|
};
|
|
|
|
foreach ( var a in list )
|
|
{
|
|
Console.WriteLine( $"{Rotation.From( a.Item1 ).Angles()}\t{a.Item2}" );
|
|
Assert.IsTrue( AlmostEqual( Rotation.From( a.Item1 ).Angles(), a.Item2 ) );
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void Parse()
|
|
{
|
|
{
|
|
Rotation r = Rotation.Parse( "1.1,2.1,3.1,4.1" );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "1.1, 2.1, 3.1, 4.1" );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[1.1,2.1,3.1,4.1]" );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[ 1.1, 2.1, 3.1, 4.1] " );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Rotation r = Rotation.Parse( "[ 1.1,\n\r 2.1,\n\r 3.1,\n\r 4.1\n\r ] " );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TryParse()
|
|
{
|
|
{
|
|
Assert.IsTrue( Rotation.TryParse( "1.1,2.1,3.1,4.1", out var r ) );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Assert.IsTrue( Rotation.TryParse( "1.1, 2.1, 3.1, 4.1", out var r ) );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Assert.IsTrue( Rotation.TryParse( "[1.1,2.1,3.1,4.1]", out var r ) );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Assert.IsTrue( Rotation.TryParse( "[ 1.1, 2.1, 3.1, 4.1] ", out var r ) );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Assert.IsTrue( Rotation.TryParse( "[ 1.1,\n\r 2.1,\n\r 3.1,\n\r 4.1\n\r ] ", out var r ) );
|
|
|
|
Assert.AreEqual( r.x, 1.1f );
|
|
Assert.AreEqual( r.y, 2.1f );
|
|
Assert.AreEqual( r.z, 3.1f );
|
|
Assert.AreEqual( r.w, 4.1f );
|
|
}
|
|
|
|
{
|
|
Assert.IsFalse( Rotation.TryParse( "1", out _ ) );
|
|
Assert.IsFalse( Rotation.TryParse( "abcdef", out _ ) );
|
|
Assert.IsFalse( Rotation.TryParse( "1.1, 2.2", out _ ) );
|
|
}
|
|
}
|
|
}
|