From 5fd0251b37fa7721de70f0bec1b41cec9000dee8 Mon Sep 17 00:00:00 2001 From: Emiliana <38952746+emilianavt@users.noreply.github.com> Date: Fri, 11 Dec 2020 21:41:04 +0100 Subject: [PATCH] Added generic interpolation and smoothing framework. --- Unity/OpenSeeInterpolation.cs | 232 +++++++++++++++++++++++++++++ Unity/OpenSeeInterpolation.cs.meta | 11 ++ 2 files changed, 243 insertions(+) create mode 100644 Unity/OpenSeeInterpolation.cs create mode 100644 Unity/OpenSeeInterpolation.cs.meta diff --git a/Unity/OpenSeeInterpolation.cs b/Unity/OpenSeeInterpolation.cs new file mode 100644 index 0000000..b449504 --- /dev/null +++ b/Unity/OpenSeeInterpolation.cs @@ -0,0 +1,232 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace OpenSee { + public class InterpolatedMap where V : InterpolatedValue, new() { + private Dictionary map = new Dictionary(); + private float clamp = 1f; + private float smoothing = 0f; + private bool gotDefault = false; + private U defaultValue; + + public void Clear() { + map.Clear(); + } + + public void SetSmoothing(float smoothing) { + this.smoothing = smoothing; + foreach (var entry in map) { + if (entry.Value != null) + entry.Value.SetSmoothing(smoothing); + } + } + + public void SetClamp(float clamp) { + this.clamp = clamp; + foreach (var entry in map) { + if (entry.Value != null) + entry.Value.SetClamp(clamp); + } + } + + void Prepare(T key) { + if (!map.ContainsKey(key)) { + map.Add(key, new V()); + map[key].SetSmoothing(smoothing); + map[key].SetClamp(clamp); + } + } + + public void SetValue(T key, U v) { + Prepare(key); + map[key].SetValue(v); + } + + public void Store(T key, U v) { + Prepare(key); + map[key].UpdateValue(v); + } + + public void Store(T key, U v, float nowT) { + if (!map.ContainsKey(key)) { + map.Add(key, new V()); + map[key].SetSmoothing(smoothing); + map[key].SetClamp(clamp); + } + map[key].UpdateValue(v, nowT); + } + + public U GetDefault() { + if (gotDefault) + return defaultValue; + V tmp = new V(); + defaultValue = tmp.GetDefault(); + return defaultValue; + } + + public bool Check(T key) { + return map.ContainsKey(key); + } + + public U Get(T key) { + if (!map.ContainsKey(key)) + return GetDefault(); + return map[key].Interpolate(); + } + } + + abstract public class InterpolatedValue { + private float interpolateT = 0f; + private float updateT = 0f; + private float lastT = 0f; + private float currentT = 0f; + private float clamp = 1f; + private float smoothing = 0f; + private int gotData = 0; + + private bool haveDefault = false; + private V defaultValue; + + private bool valueSet = false; + private V dataValue; + private V dataValueLast; + + abstract public V ValueLerpUnclamped(V a, V b, float t); + abstract public V GetBuiltinDefault(); + + public void SetDefault(V defaultValue) { + this.defaultValue = defaultValue; + haveDefault = true; + } + + public void ResetDefault() { + haveDefault = false; + } + + public V GetDefault() { + if (haveDefault) + return defaultValue; + return GetBuiltinDefault(); + } + + public void SetSmoothing(float smoothing) { + this.smoothing = smoothing; + } + + public void SetClamp(float clamp) { + this.clamp = clamp; + } + + public void SetValue(V v) { + dataValueLast = v; + dataValue = v; + valueSet = true; + } + + public InterpolatedValue(float smoothing = 0f, float clamp = 1f) { + this.smoothing = smoothing; + this.clamp = clamp; + } + + public void UpdateValue(V v) { + UpdateValue(v, Time.realtimeSinceStartup); + } + + public void UpdateValue(V v, float nowT) { + if (nowT < 0f) + return; + lock (this) { + if (nowT < currentT || gotData == 0) { + // Reinitialize + gotData = 1; + updateT = Time.time; + lastT = 0f; + currentT = nowT; + dataValueLast = GetDefault(); + dataValue = ValueLerpUnclamped(v, dataValueLast, smoothing); + } else if (nowT == currentT) { + // Change value + dataValue = ValueLerpUnclamped(v, dataValueLast, smoothing); + } else { + // Regular operation + updateT = Time.time; + lastT = currentT; + currentT = nowT; + if (gotData < 2) + gotData++; + dataValueLast = dataValue; + dataValue = ValueLerpUnclamped(v, dataValueLast, smoothing); + } + } + } + + public V Interpolate() { + lock (this) { + interpolateT = Time.time; + if (gotData < 2) { + if (valueSet) + return dataValue; + else + return GetDefault(); + } + float t = Mathf.Min((interpolateT - updateT) / (float)(currentT - lastT), clamp); + return ValueLerpUnclamped(dataValueLast, dataValue, t); + } + } + } + + public class InterpolatedColor : InterpolatedValue { + public override Color ValueLerpUnclamped(Color a, Color b, float t) { + return Color.LerpUnclamped(a, b, t); + } + public override Color GetBuiltinDefault() { + return Color.clear; + } + } + + public class InterpolatedQuaternion : InterpolatedValue { + public override Quaternion ValueLerpUnclamped(Quaternion a, Quaternion b, float t) { + return Quaternion.SlerpUnclamped(a, b, t); + } + public override Quaternion GetBuiltinDefault() { + return Quaternion.identity; + } + } + + public class InterpolatedVector2 : InterpolatedValue { + public override Vector2 ValueLerpUnclamped(Vector2 a, Vector2 b, float t) { + return Vector2.LerpUnclamped(a, b, t); + } + public override Vector2 GetBuiltinDefault() { + return Vector2.zero; + } + } + + public class InterpolatedVector3 : InterpolatedValue { + public override Vector3 ValueLerpUnclamped(Vector3 a, Vector3 b, float t) { + return Vector3.LerpUnclamped(a, b, t); + } + public override Vector3 GetBuiltinDefault() { + return Vector3.zero; + } + } + + public class InterpolatedVector4 : InterpolatedValue { + public override Vector4 ValueLerpUnclamped(Vector4 a, Vector4 b, float t) { + return Vector4.LerpUnclamped(a, b, t); + } + public override Vector4 GetBuiltinDefault() { + return Vector4.zero; + } + } + + public class InterpolatedFloat : InterpolatedValue { + public override float ValueLerpUnclamped(float a, float b, float t) { + return Mathf.LerpUnclamped(a, b, t); + } + public override float GetBuiltinDefault() { + return 0f; + } + } +} \ No newline at end of file diff --git a/Unity/OpenSeeInterpolation.cs.meta b/Unity/OpenSeeInterpolation.cs.meta new file mode 100644 index 0000000..a5eda33 --- /dev/null +++ b/Unity/OpenSeeInterpolation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d61e11f1b6900a7419383be1377f191b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: