Files
sbox-public/engine/Sandbox.System/Math/Ray.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

88 lines
2.3 KiB
C#

using System.Numerics;
using Sandbox;
/// <summary>
/// A struct describing an origin and direction
/// </summary>
public struct Ray : IEquatable<Ray>
{
private Vector3 _origin;
private Vector3 _direction;
/// <summary>
/// Origin of the ray.
/// </summary>
public Vector3 Position
{
readonly get => _origin;
set => _origin = value;
}
/// <summary>
/// Direction of the ray.
/// </summary>
public Vector3 Forward
{
readonly get => _direction;
set => _direction = value;
}
public Ray( Vector3 origin, Vector3 direction )
{
_origin = origin;
_direction = direction;
}
/// <summary>
/// Convert a ray to be local to this transform
/// </summary>
public readonly Ray ToLocal( in Transform tx )
{
var ray = this;
ray.Forward = tx.NormalToLocal( ray.Forward );
ray.Position = tx.PointToLocal( ray.Position );
return ray;
}
/// <summary>
/// Convert a ray from being local to this transform
/// </summary>
public readonly Ray ToWorld( in Transform tx )
{
var ray = this;
ray.Forward = tx.NormalToWorld( ray.Forward );
ray.Position = tx.PointToWorld( ray.Position );
return ray;
}
/// <summary>
/// Returns a point on the ray at given distance.
/// </summary>
/// <param name="distance">How far from the <see cref="Position"/> the point should be.</param>
/// <returns>The point at given distance.</returns>
public readonly Vector3 Project( float distance ) => Position + Forward * distance;
private const float SafeMagnitude = 1e7f;
/// <summary>
/// Returns a point on the ray at given safe distance.
/// </summary>
/// <param name="distance">How far from the <see cref="Position"/> the point should be.</param>
/// <returns>The point at given distance.</returns>
internal readonly Vector3 ProjectSafe( float distance )
{
distance = float.IsNaN( distance ) ? SafeMagnitude : distance;
return Position + Forward * distance.Clamp( -SafeMagnitude, SafeMagnitude );
}
#region equality
public static bool operator ==( Ray left, Ray right ) => left.Equals( right );
public static bool operator !=( Ray left, Ray right ) => !(left == right);
public readonly override bool Equals( object obj ) => obj is Ray o && Equals( o );
public readonly bool Equals( Ray o ) => (_origin, _direction) == (o._origin, o._direction);
public readonly override int GetHashCode() => HashCode.Combine( _origin, _direction );
#endregion
}