mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-04 04:18:27 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
97 lines
2.3 KiB
C#
97 lines
2.3 KiB
C#
using System.Runtime.InteropServices;
|
|
namespace Sandbox;
|
|
|
|
[StructLayout( LayoutKind.Sequential )]
|
|
public struct Triangle : System.IEquatable<Triangle>
|
|
{
|
|
public Vector3 A;
|
|
public Vector3 B;
|
|
public Vector3 C;
|
|
|
|
public float Perimeter => A.Distance( B ) + B.Distance( C ) + C.Distance( A );
|
|
public float Area => Vector3.Cross( B - A, C - A ).Length * 0.5f;
|
|
public bool IsRight => (B - A).Dot( C - A ) == 0.0f;
|
|
public Vector3 Normal => Vector3.Cross( B - A, C - A ).Normal;
|
|
|
|
public Triangle( Vector3 a, Vector3 b, Vector3 c )
|
|
{
|
|
A = a;
|
|
B = b;
|
|
C = c;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{A} / {B} / {C}";
|
|
}
|
|
|
|
public readonly Vector3 ClosestPoint( in Vector3 P )
|
|
{
|
|
// voronoi
|
|
|
|
Vector3 e0 = B - A;
|
|
Vector3 e1 = C - A;
|
|
Vector3 p0 = P - A;
|
|
|
|
// voronoi region of A
|
|
float d1 = e0.Dot( p0 );
|
|
float d2 = e1.Dot( p0 );
|
|
if ( d1 <= 0.0f && d2 <= 0.0f )
|
|
return A;
|
|
|
|
// voronoi region of B
|
|
Vector3 p1 = P - B;
|
|
float d3 = e0.Dot( p1 );
|
|
float d4 = e1.Dot( p1 );
|
|
if ( d3 >= 0.0f && d4 <= d3 )
|
|
return B;
|
|
|
|
// voronoi region of e0 (A-B)
|
|
float ve2 = d1 * d4 - d3 * d2;
|
|
if ( ve2 <= 0.0f && d1 >= 0.0f && d3 <= 0.0f )
|
|
{
|
|
float v = d1 / (d1 - d3);
|
|
return A + v * e0;
|
|
}
|
|
|
|
// voronoi region of C
|
|
Vector3 p2 = P - C;
|
|
float d5 = e0.Dot( p2 );
|
|
float d6 = e1.Dot( p2 );
|
|
if ( d6 >= 0.0f && d5 <= d6 )
|
|
return C;
|
|
|
|
// voronoi region of e2
|
|
float ve1 = d5 * d2 - d1 * d6;
|
|
if ( ve1 <= 0.0f && d2 >= 0.0f && d6 <= 0.0f )
|
|
{
|
|
float w = d2 / (d2 - d6);
|
|
return A + w * e1;
|
|
}
|
|
|
|
// voronoi region on e1
|
|
float ve0 = d3 * d6 - d5 * d4;
|
|
if ( ve0 <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f )
|
|
{
|
|
float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
|
return B + w * (C - B);
|
|
}
|
|
|
|
// voronoi region of ABC triangle
|
|
{
|
|
float denom = 1.0f / (ve0 + ve1 + ve2);
|
|
float v = ve1 * denom;
|
|
float w = ve2 * denom;
|
|
return A + e0 * v + e1 * w;
|
|
}
|
|
}
|
|
|
|
#region equality
|
|
public static bool operator ==( Triangle left, Triangle right ) => left.Equals( right );
|
|
public static bool operator !=( Triangle left, Triangle right ) => !(left == right);
|
|
public override bool Equals( object obj ) => obj is Triangle o && Equals( o );
|
|
public readonly bool Equals( Triangle o ) => (A) == (o.A) && (B) == (o.B) && (C) == (o.C);
|
|
public readonly override int GetHashCode() => HashCode.Combine( A, B, C );
|
|
#endregion
|
|
}
|