Trying match Unity Animation Curve with Hermit Spline. Ger Weird behaviour....
Hello, I'am trying to draw custom graph inside my custom inspector and need to render graph like unity made it. I found that they using Some Sort of Hermit Spline to do it. I generate logarithmic curve and try make it smooth between generate keyframe. But in between of two keyframes Evaluate method from Hermit Spline Get wrong values...
There are my test class for render and debugging. What I am doing wrong? Resolution is just amount of point inside segment between two keyframes
There pic of weird behaviour inside inspector: But I Want it to be like this, but smooth and like unity built-in anim curves( I am using them, but can't render properly):
using System.Collections.Generic;
using UnityEngine;
public class HermitTest : MonoBehaviour
{
public AnimationCurve curve;
public LineRenderer lineRenderer;
private Vector4 parameters;
private int resolution = 2;
public void Start()
{
curve = LogarithmicCurve(new Vector2(0, 1f));
lineRenderer.positionCount = (curve.keys.Length-1)*resolution+curve.keys.Length;
for (int i = 0; i < curve.keys.Length-1; i++)
{
Vector3 p0 = new Vector3(curve.keys[i].time, curve.keys[i].value, curve.keys[i].outTangent);
Vector3 p1 = new Vector3(curve.keys[i+1].time, curve.keys[i+1].value, curve.keys[i+1].inTangent);
parameters = CalculateParameters(p0, p1);
for (int j = 0; j < resolution; j++)
{
float t = (j * 1.0f) / (resolution);
float y = Evaluate(parameters, t);
float x = Mathf.Lerp(p0.x, p1.x, t);
lineRenderer.SetPosition(i*resolution+j, new Vector3(x, 0, y));
}
}
}
private float LogValue(float distance, float minDistance)
{
distance = Mathf.Max(distance, 0.0001f);
return minDistance / distance;
}
private AnimationCurve LogarithmicCurve(Vector2 range)
{
float value, slope, s;
List<Keyframe> keys = new List<Keyframe>();
float step = 2;
range.x = Mathf.Max(range.x, 0.01f);
for (float i = range.x; i < range.y; i *= step)
{
value = LogValue(i, range.x);
s = i / 50f;
slope = (LogValue(i + s, range.x) - LogValue(i - s, range.x)) / (s * 2);
keys.Add(new Keyframe(i, value, slope, slope));
}
value = LogValue(range.y, range.x);
s = range.y / 50f;
slope = (LogValue(range.y + s, range.x) - LogValue(range.y - s, range.x)) / (s * 2);
keys.Add(new Keyframe(range.y, value, slope, slope));
return new AnimationCurve(keys.ToArray());
}
private Vector4 CalculateParameters(Vector3 p1, Vector3 p2)
{
float p1x = p1.x;
float p2x = p2.x;
float p1y = p1.y;
float p2y = p2.y;
float tp1 = p1.z;
float tp2 = p2.z;
float a = (p1x * tp1 + p1x * tp2 - p2x * tp1 - p2x * tp2 - 2 * p1y + 2 * p2y) / (p1x * p1x * p1x - p2x * p2x * p2x + 3 * p1x * p2x * p2x - 3 * p1x * p1x * p2x);
float b = ((-p1x * p1x * tp1 - 2 * p1x * p1x * tp2 + 2 * p2x * p2x * tp1 + p2x * p2x * tp2 - p1x * p2x * tp1 + p1x * p2x * tp2 + 3 * p1x * p1y - 3 * p1x * p2y + 3 * p1y * p2x - 3 * p2x * p2y) / (p1x * p1x * p1x - p2x * p2x * p2x + 3 * p1x * p2x * p2x - 3 * p1x * p1x * p2x));
float c = ((p1x * p1x * p1x * tp2 - p2x * p2x * p2x * tp1 - p1x * p2x * p2x * tp1 - 2 * p1x * p2x * p2x * tp2 + 2 * p1x * p1x * p2x * tp1 + p1x * p1x * p2x * tp2 - 6 * p1x * p1y * p2x + 6 * p1x * p2x * p2y) / (p1x * p1x * p1x - p2x * p2x * p2x + 3 * p1x * p2x * p2x - 3 * p1x * p1x * p2x));
float d = ((p1x * p2x * p2x * p2x * tp1 - p1x * p1x * p2x * p2x * tp1 + p1x * p1x * p2x * p2x * tp2 - p1x * p1x * p1x * p2x * tp2 - p1y * p2x * p2x * p2x + p1x * p1x * p1x * p2y + 3 * p1x * p1y * p2x * p2x - 3 * p1x * p1x * p2x * p2y) / (p1x * p1x * p1x - p2x * p2x * p2x + 3 * p1x * p2x * p2x - 3 * p1x * p1x * p2x));
return new Vector4(a, b, c, d);
}
private float Evaluate(Vector4 parameters, float t)
{
return parameters.x * t * t * t + parameters.y * t * t + parameters.z * t + parameters.w;
}
}
Your answer
Follow this Question
Related Questions
Undo Problem With Curve Fields In Custom Editor Window 1 Answer
How could I find out if an objects vector3 hits between 2 points without raycasting in a 3D game? 1 Answer
Unity5-serializedObject.FindProperty("listname") for ReorderableList doesn't work... 2 Answers
Getting an array of objects to show in editor 1 Answer
Thin black lines between meshes 1 Answer