using System;
using UnityEngine;
namespace ProceduralToolkit
{
///
/// Representation of a 3D line
///
[Serializable]
public struct Line3 : IEquatable, IFormattable
{
public Vector3 origin;
public Vector3 direction;
public static Line3 xAxis => new Line3(Vector3.zero, Vector3.right);
public static Line3 yAxis => new Line3(Vector3.zero, Vector3.up);
public static Line3 zAxis => new Line3(Vector3.zero, Vector3.forward);
public Line3(Ray ray)
{
origin = ray.origin;
direction = ray.direction;
}
public Line3(Vector3 origin, Vector3 direction)
{
this.origin = origin;
this.direction = direction;
}
///
/// Returns a point at units from origin along the line
///
public Vector3 GetPoint(float distance)
{
return origin + direction*distance;
}
///
/// Linearly interpolates between two lines
///
public static Line3 Lerp(Line3 a, Line3 b, float t)
{
t = Mathf.Clamp01(t);
return new Line3(a.origin + (b.origin - a.origin)*t, a.direction + (b.direction - a.direction)*t);
}
///
/// Linearly interpolates between two lines without clamping the interpolant
///
public static Line3 LerpUnclamped(Line3 a, Line3 b, float t)
{
return new Line3(a.origin + (b.origin - a.origin)*t, a.direction + (b.direction - a.direction)*t);
}
#region Casting operators
public static explicit operator Line3(Ray ray)
{
return new Line3(ray);
}
public static explicit operator Ray(Line3 line)
{
return new Ray(line.origin, line.direction);
}
public static explicit operator Ray2D(Line3 line)
{
return new Ray2D((Vector2) line.origin, (Vector2) line.direction);
}
public static explicit operator Line2(Line3 line)
{
return new Line2((Vector2) line.origin, (Vector2) line.direction);
}
#endregion Casting operators
public static Line3 operator +(Line3 line, Vector3 vector)
{
return new Line3(line.origin + vector, line.direction);
}
public static Line3 operator -(Line3 line, Vector3 vector)
{
return new Line3(line.origin - vector, line.direction);
}
public static bool operator ==(Line3 a, Line3 b)
{
return a.origin == b.origin && a.direction == b.direction;
}
public static bool operator !=(Line3 a, Line3 b)
{
return !(a == b);
}
public override int GetHashCode()
{
return origin.GetHashCode() ^ (direction.GetHashCode() << 2);
}
public override bool Equals(object other)
{
return other is Line3 && Equals((Line3) other);
}
public bool Equals(Line3 other)
{
return origin.Equals(other.origin) && direction.Equals(other.direction);
}
public override string ToString()
{
return string.Format("Line3(origin: {0}, direction: {1})", origin, direction);
}
public string ToString(string format)
{
return string.Format("Line3(origin: {0}, direction: {1})", origin.ToString(format), direction.ToString(format));
}
public string ToString(string format, IFormatProvider formatProvider)
{
return string.Format("Line3(origin: {0}, direction: {1})", origin.ToString(format, formatProvider),
direction.ToString(format, formatProvider));
}
}
}