Last active
October 1, 2024 22:05
-
-
Save keenanwoodall/c37ce12e0b7c08bd59f7235ec9614562 to your computer and use it in GitHub Desktop.
A struct that makes using animation curves with the job system easy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
using UnityEngine; | |
using Unity.Collections; | |
using static Unity.Mathematics.math; | |
public struct NativeCurve : IDisposable | |
{ | |
public bool IsCreated => values.IsCreated; | |
private NativeArray<float> values; | |
private WrapMode preWrapMode; | |
private WrapMode postWrapMode; | |
private void InitializeValues (int count) | |
{ | |
if (values.IsCreated) | |
values.Dispose (); | |
values = new NativeArray<float> (count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); | |
} | |
public void Update (AnimationCurve curve, int resolution) | |
{ | |
if (curve == null) | |
throw new NullReferenceException ("Animation curve is null."); | |
preWrapMode = curve.preWrapMode; | |
postWrapMode = curve.postWrapMode; | |
if (!values.IsCreated || values.Length != resolution) | |
InitializeValues (resolution); | |
for (int i = 0; i < resolution; i++) | |
values[i] = curve.Evaluate ((float)i / (float)resolution); | |
} | |
public float Evaluate (float t) | |
{ | |
var count = values.Length; | |
if (count == 1) | |
return values[0]; | |
if (t < 0f) | |
{ | |
switch (preWrapMode) | |
{ | |
default: | |
return values[0]; | |
case WrapMode.Loop: | |
t = 1f - (abs (t) % 1f); | |
break; | |
case WrapMode.PingPong: | |
t = pingpong (t, 1f); | |
break; | |
} | |
} | |
else if (t > 1f) | |
{ | |
switch (postWrapMode) | |
{ | |
default: | |
return values[count - 1]; | |
case WrapMode.Loop: | |
t %= 1f; | |
break; | |
case WrapMode.PingPong: | |
t = pingpong (t, 1f); | |
break; | |
} | |
} | |
var it = t * (count - 1); | |
var lower = (int)it; | |
var upper = lower + 1; | |
if (upper >= count) | |
upper = count - 1; | |
return lerp (values[lower], values[upper], it - lower); | |
} | |
public void Dispose () | |
{ | |
if (values.IsCreated) | |
values.Dispose (); | |
} | |
[MethodImpl (MethodImplOptions.AggressiveInlining)] | |
private float repeat (float t, float length) | |
{ | |
return clamp (t - floor (t / length) * length, 0, length); | |
} | |
[MethodImpl (MethodImplOptions.AggressiveInlining)] | |
private float pingpong (float t, float length) | |
{ | |
t = repeat (t, length * 2f); | |
return length - abs (t - length); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is excellent! I found out that it is a need to make private NativeArray values assigned with property [NativeDisableParallelForRestriction].