Files
2026-03-04 10:03:45 +08:00

99 lines
2.9 KiB
C#

using UnityEngine;
namespace SplineMesh
{
public struct CurveSample
{
public readonly Vector3 location;
public readonly Vector3 tangent;
public readonly Vector3 up;
public readonly Vector2 scale;
public readonly float roll;
public readonly float distanceInCurve;
public readonly float timeInCurve;
public readonly CubicBezierCurve curve;
private Quaternion rotation;
public Quaternion Rotation
{
get
{
if (rotation == Quaternion.identity)
{
Vector3 upwards = Vector3.Cross(tangent, Vector3.Cross(Quaternion.AngleAxis(roll, Vector3.forward) * up, tangent).normalized);
rotation = Quaternion.LookRotation(tangent, upwards);
}
return rotation;
}
}
public CurveSample(Vector3 location, Vector3 tangent, Vector3 up, Vector2 scale, float roll, float distanceInCurve, float timeInCurve, CubicBezierCurve curve)
{
this.location = location;
this.tangent = tangent;
this.up = up;
this.roll = roll;
this.scale = scale;
this.distanceInCurve = distanceInCurve;
this.timeInCurve = timeInCurve;
this.curve = curve;
rotation = Quaternion.identity;
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
CurveSample curveSample = (CurveSample)obj;
if (location == curveSample.location && tangent == curveSample.tangent && up == curveSample.up && scale == curveSample.scale && roll == curveSample.roll && distanceInCurve == curveSample.distanceInCurve)
{
return timeInCurve == curveSample.timeInCurve;
}
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(CurveSample cs1, CurveSample cs2)
{
return cs1.Equals(cs2);
}
public static bool operator !=(CurveSample cs1, CurveSample cs2)
{
return !cs1.Equals(cs2);
}
public static CurveSample Lerp(CurveSample a, CurveSample b, float t)
{
return new CurveSample(Vector3.Lerp(a.location, b.location, t), Vector3.Lerp(a.tangent, b.tangent, t).normalized, Vector3.Lerp(a.up, b.up, t), Vector2.Lerp(a.scale, b.scale, t), Mathf.Lerp(a.roll, b.roll, t), Mathf.Lerp(a.distanceInCurve, b.distanceInCurve, t), Mathf.Lerp(a.timeInCurve, b.timeInCurve, t), a.curve);
}
public MeshVertex GetBent(MeshVertex vert)
{
MeshVertex meshVertex = new MeshVertex(vert.position, vert.normal, vert.uv);
meshVertex.position = Vector3.Scale(meshVertex.position, new Vector3(0f, scale.y, scale.x));
meshVertex.position = Quaternion.AngleAxis(roll, Vector3.right) * meshVertex.position;
meshVertex.normal = Quaternion.AngleAxis(roll, Vector3.right) * meshVertex.normal;
meshVertex.position.x = 0f;
Quaternion quaternion = Rotation * Quaternion.Euler(0f, -90f, 0f);
meshVertex.position = quaternion * meshVertex.position + location;
meshVertex.normal = quaternion * meshVertex.normal;
return meshVertex;
}
}
}