using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace RimWorldAnimationStudio { public class SimpleCurve : IEnumerable, IEnumerable { public void Clear() { this.points.Clear(); } public int PointsCount { get { return this.points.Count; } } public List Points { get { return this.points; } } public SimpleCurve(IEnumerable points) { this.SetPoints(points); } public SimpleCurve() { } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public IEnumerator GetEnumerator() { foreach (CurvePoint curvePoint in this.points) { yield return curvePoint; } List.Enumerator enumerator = default(List.Enumerator); yield break; yield break; } public CurvePoint this[int i] { get { return this.points[i]; } set { this.points[i] = value; } } public void SetPoints(IEnumerable newPoints) { this.points.Clear(); foreach (CurvePoint item in newPoints) { this.points.Add(item); } this.SortPoints(); } public void Add(float x, float y, bool sort = true) { CurvePoint newPoint = new CurvePoint(x, y); this.Add(newPoint, sort); } public void Add(CurvePoint newPoint, bool sort = true) { this.points.Add(newPoint); if (sort) { this.SortPoints(); } } public void SortPoints() { this.points.Sort(SimpleCurve.CurvePointsComparer); } public float ClampToCurve(float value) { if (this.points.Count == 0) { Debug.Log("Clamping a value to an empty SimpleCurve."); return value; } return Mathf.Clamp(value, this.points[0].y, this.points[this.points.Count - 1].y); } public void RemovePointNear(CurvePoint point) { for (int i = 0; i < this.points.Count; i++) { if ((this.points[i].Loc - point.Loc).sqrMagnitude < 0.001f) { this.points.RemoveAt(i); return; } } } public float Evaluate(float x) { if (this.points.Count == 0) { Debug.Log("Evaluating a SimpleCurve with no points."); return 0f; } if (x <= this.points[0].x) { return this.points[0].y; } if (x >= this.points[this.points.Count - 1].x) { return this.points[this.points.Count - 1].y; } CurvePoint curvePoint = this.points[0]; CurvePoint curvePoint2 = this.points[this.points.Count - 1]; int i = 0; while (i < this.points.Count) { if (x <= this.points[i].x) { curvePoint2 = this.points[i]; if (i > 0) { curvePoint = this.points[i - 1]; break; } break; } else { i++; } } float t = (x - curvePoint.x) / (curvePoint2.x - curvePoint.x); return Mathf.Lerp(curvePoint.y, curvePoint2.y, t); } public float EvaluateInverted(float y) { if (this.points.Count == 0) { Debug.Log("Evaluating a SimpleCurve with no points."); return 0f; } if (this.points.Count == 1) { return this.points[0].x; } int i = 0; while (i < this.points.Count - 1) { if ((y >= this.points[i].y && y <= this.points[i + 1].y) || (y <= this.points[i].y && y >= this.points[i + 1].y)) { if (y == this.points[i].y) { return this.points[i].x; } if (y == this.points[i + 1].y) { return this.points[i + 1].x; } return GenMath.LerpDouble(this.points[i].y, this.points[i + 1].y, this.points[i].x, this.points[i + 1].x, y); } else { i++; } } if (y < this.points[0].y) { float result = 0f; float num = 0f; for (int j = 0; j < this.points.Count; j++) { if (j == 0 || this.points[j].y < num) { num = this.points[j].y; result = this.points[j].x; } } return result; } float result2 = 0f; float num2 = 0f; for (int k = 0; k < this.points.Count; k++) { if (k == 0 || this.points[k].y > num2) { num2 = this.points[k].y; result2 = this.points[k].x; } } return result2; } public float PeriodProbabilityFromCumulative(float startX, float span) { if (this.points.Count < 2) { return 0f; } if (this.points[0].y != 0f) { Debug.Log("PeriodProbabilityFromCumulative should only run on curves whose first point is 0."); } float num = this.Evaluate(startX + span) - this.Evaluate(startX); if (num < 0f) { Debug.Log("PeriodicProbability got negative probability from " + this + ": slope should never be negative."); num = 0f; } if (num > 1f) { num = 1f; } return num; } public IEnumerable ConfigErrors(string prefix) { for (int i = 0; i < this.points.Count - 1; i++) { if (this.points[i + 1].x < this.points[i].x) { yield return prefix + ": points are out of order"; break; } } yield break; } private List points = new List(); private static Comparison CurvePointsComparer = delegate (CurvePoint a, CurvePoint b) { if (a.x < b.x) { return -1; } if (b.x < a.x) { return 1; } return 0; }; } }