Add cubic bezier functions.
This commit is contained in:
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using SMath = System.Math;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Math {
|
||||||
|
// Ported from https://github.com/arian/cubic-bezier/blob/master/index.js
|
||||||
|
public static class CubicBezier {
|
||||||
|
public static float Evaluate(float t, float x1, float y1, float x2, float y2, float epsilon) {
|
||||||
|
float x = t, t0, t1, t2, tx, d2, i;
|
||||||
|
for (t2 = x, i = 0; i < 8; i++) {
|
||||||
|
tx = CurveX(t2, x1, x2) - x;
|
||||||
|
if (SMath.Abs(tx) < epsilon) return CurveY(t2, y1, y2);
|
||||||
|
d2 = DerivativeCurveX(t2, x1, x2);
|
||||||
|
if (SMath.Abs(d2) < 1e-6) break;
|
||||||
|
t2 -= tx / d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
t0 = 0; t1 = 1; t2 = x;
|
||||||
|
|
||||||
|
if (t2 < t0) return CurveY(t0, y1, y2);
|
||||||
|
if (t2 > t1) return CurveY(t1, y1, y2);
|
||||||
|
|
||||||
|
while (t0 < t1) {
|
||||||
|
tx = CurveX(t2, x1, x2);
|
||||||
|
if (SMath.Abs(tx - x) < epsilon) return CurveY(t2, y1, y2);
|
||||||
|
if (x > tx) t0 = t2;
|
||||||
|
else t1 = t2;
|
||||||
|
t2 = (t1 - t0) * .5f + t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CurveY(t2, y1, y2);
|
||||||
|
}
|
||||||
|
static float CurveX(float t, float x1, float x2) {
|
||||||
|
float v = 1 - t;
|
||||||
|
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
||||||
|
}
|
||||||
|
static float CurveY(float t, float y1, float y2) {
|
||||||
|
float v = 1 - t;
|
||||||
|
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
||||||
|
}
|
||||||
|
static float DerivativeCurveX(float t, float x1, float x2) {
|
||||||
|
float v = 1 - t;
|
||||||
|
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Cryville/Common/Math/CubicBezier.cs.meta
Normal file
11
Assets/Cryville/Common/Math/CubicBezier.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 17dd6f775fc965f43960da7166b55b87
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Cryville.Common;
|
using Cryville.Common;
|
||||||
|
using Cryville.Common.Math;
|
||||||
using Cryville.Common.Pdt;
|
using Cryville.Common.Pdt;
|
||||||
using Cryville.Crtr.Event;
|
using Cryville.Crtr.Event;
|
||||||
using System;
|
using System;
|
||||||
@@ -152,6 +153,11 @@ namespace Cryville.Crtr {
|
|||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
|
||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("anim"), new func_anim(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("anim"), new func_anim(() => ContextSelfValue));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("cubic_bezier"), new func_cubic_bezier(() => ContextSelfValue));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease"), new func_cubic_bezier_fixed(0.25f, 0.1f, 0.25f, 1f, () => ContextSelfValue));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_in"), new func_cubic_bezier_fixed(0.42f, 0f, 1f, 1f, () => ContextSelfValue));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_out"), new func_cubic_bezier_fixed(0f, 0f, 0.58f, 1f, () => ContextSelfValue));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_in_out"), new func_cubic_bezier_fixed(0.42f, 0f, 0.58f, 1f, () => ContextSelfValue));
|
||||||
|
|
||||||
Func<int, PropSrc> cccb = k => ContextCascadeLookup(k);
|
Func<int, PropSrc> cccb = k => ContextCascadeLookup(k);
|
||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("attack_timing"), new func_attack_timing(cccb));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("attack_timing"), new func_attack_timing(cccb));
|
||||||
@@ -533,6 +539,43 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class func_cubic_bezier : PdtOperator {
|
||||||
|
readonly Func<PropSrc> _ctxcb;
|
||||||
|
public func_cubic_bezier(Func<PropSrc> ctxcb) : base(5) {
|
||||||
|
_ctxcb = ctxcb;
|
||||||
|
}
|
||||||
|
protected override unsafe void Execute() {
|
||||||
|
float x1 = GetOperand(0).AsNumber(), y1 = GetOperand(1).AsNumber();
|
||||||
|
float x2 = GetOperand(2).AsNumber(), y2 = GetOperand(3).AsNumber();
|
||||||
|
float time;
|
||||||
|
switch (LoadedOperandCount) {
|
||||||
|
case 4: time = oputil.AsNumber(_ctxcb()); break;
|
||||||
|
case 5: time = GetOperand(4).AsNumber(); break;
|
||||||
|
default: throw new ArgumentException("Argument count not 4 or 5");
|
||||||
|
}
|
||||||
|
GetReturnFrame(PdtInternalType.Number, sizeof(float))
|
||||||
|
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class func_cubic_bezier_fixed : PdtOperator {
|
||||||
|
readonly float x1, y1, x2, y2;
|
||||||
|
readonly Func<PropSrc> _ctxcb;
|
||||||
|
public func_cubic_bezier_fixed(float x1, float y1, float x2, float y2, Func<PropSrc> ctxcb) : base(1) {
|
||||||
|
this.x1 = x1; this.y1 = y1;
|
||||||
|
this.x2 = x2; this.y2 = y2;
|
||||||
|
_ctxcb = ctxcb;
|
||||||
|
}
|
||||||
|
protected override void Execute() {
|
||||||
|
float time;
|
||||||
|
switch (LoadedOperandCount) {
|
||||||
|
case 0: time = oputil.AsNumber(_ctxcb()); break;
|
||||||
|
case 1: time = GetOperand(0).AsNumber(); break;
|
||||||
|
default: throw new ArgumentException("Argument count not 0 or 1");
|
||||||
|
}
|
||||||
|
GetReturnFrame(PdtInternalType.Number, sizeof(float))
|
||||||
|
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region Judge Functions
|
#region Judge Functions
|
||||||
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
|
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
|
||||||
|
|||||||
Reference in New Issue
Block a user