// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) VRMADA, All rights reserved. // // -------------------------------------------------------------------------------------------------------------------- using System.Collections.Generic; using UnityEngine; namespace UltimateXR.Animation.Splines { /// /// Linear interpolation point sequence. It is used to interpolate linearly between a set of points. /// public class UxrLinearPath : UxrSpline { #region Public Overrides UxrSpline /// /// Does the object contain valid data in order to evaluate the path? /// public override bool HasValidData => _points != null && _points.Count > 1; /// /// Evaluates the path. /// /// Interpolation parameter [0.0f, 1.0f] /// Interpolated point /// Success or failure public override bool Evaluate(float t, out Vector3 position) { return Evaluate(t, out position, out float _); } #endregion #region Public Methods /// /// Creates a path. If > 0 it will also precompute samples in order /// to evaluate the path using arc-length parameter. /// /// Set of points defining the curve /// Success or failure public bool Create(params Vector3[] points) { _points = new List(points); if (points.Length < 2) { return false; } ComputeArcLengthSamples(); return true; } #endregion #region Private Methods /// /// Interpolates the path using linear interpolation. /// /// Interpolation parameter [0.0f, 1.0f] /// Interpolated position /// Length of the segment that this point belongs to /// Success or failure private bool Evaluate(float t, out Vector3 position, out float segmentLength) { position = Vector3.zero; segmentLength = 0.0f; t = Mathf.Clamp01(t); // Compute the index of p1 int indexA = Mathf.FloorToInt(t * (_points.Count - 1)); float segmentT = t * (_points.Count - 1) - indexA; if (indexA >= _points.Count - 1) { indexA = _points.Count - 2; segmentT = 1.0f; } Vector3 p1 = _points[indexA]; Vector3 p2 = _points[indexA + 1]; segmentLength = Vector3.Distance(p1, p2); // Interpolate position = Vector3.Lerp(p1, p2, segmentT); return true; } #endregion #region Private Types & Data private List _points; #endregion } }