Implement new transition.

This commit is contained in:
2023-04-20 00:18:49 +08:00
parent d2b71e41c9
commit 8670482c04
8 changed files with 175 additions and 28 deletions

View File

@@ -1,5 +1,6 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Collections.Specialized; using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -237,6 +238,7 @@ namespace Cryville.Crtr {
result += "#" + node.Id; result += "#" + node.Id;
if (node.Time != null) result += "@" + node.Time.ToString(); if (node.Time != null) result += "@" + node.Time.ToString();
if (node.EndTime != null) result += "~" + node.EndTime.ToString(); if (node.EndTime != null) result += "~" + node.EndTime.ToString();
if (node.Transition != null) result += "^" + node.Transition.ToString();
if (node.Value != null) result += ":" + node.Value.ToString(); if (node.Value != null) result += ":" + node.Value.ToString();
} }
else { else {
@@ -264,6 +266,9 @@ namespace Cryville.Crtr {
[JsonIgnore] [JsonIgnore]
public MotionNode Node; public MotionNode Node;
[JsonConverter(typeof(JsonPdtExpConverter))]
public PdtExpression transition;
[DefaultValue(0.0f)] [DefaultValue(0.0f)]
public float sumfix = 0.0f; public float sumfix = 0.0f;

View File

@@ -106,6 +106,9 @@ namespace Cryville.Crtr {
ChartPlayer.etor.Evaluate(_vecop, exp); ChartPlayer.etor.Evaluate(_vecop, exp);
node.EndTime = new Vec1(_vecbuf); node.EndTime = new Vec1(_vecbuf);
break; break;
case '^':
node.Transition = exp;
break;
case ':': case ':':
ChartPlayer.etor.Evaluate(_vecop, exp); ChartPlayer.etor.Evaluate(_vecop, exp);
node.Value = Vector.Construct(ChartPlayer.motionRegistry[name].Type, _vecbuf); node.Value = Vector.Construct(ChartPlayer.motionRegistry[name].Type, _vecbuf);

View File

@@ -1,6 +1,7 @@
using Cryville.Common; using Cryville.Common;
using Cryville.Common.Buffers; using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized; using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -424,7 +425,8 @@ namespace Cryville.Crtr.Event {
} }
else { else {
var scaledTime = (float)((Time - tev.Time) / tev.Duration); var scaledTime = (float)((Time - tev.Time) / tev.Duration);
tev.Node.Value.LerpWith(m.Value.RelativeValue, scaledTime, ref value.RelativeValue); var transition = GetTransition(scaledTime, tev.Node.Transition);
tev.Node.Value.LerpWith(m.Value.RelativeValue, transition, ref value.RelativeValue);
} }
} }
else { else {
@@ -442,6 +444,7 @@ namespace Cryville.Crtr.Event {
} }
else { else {
var scaledTime = (float)((Time - m.Key.Time - ChartPlayer.actualRenderStep * tev.sumfix) / m.Key.Duration); var scaledTime = (float)((Time - m.Key.Time - ChartPlayer.actualRenderStep * tev.sumfix) / m.Key.Duration);
var transition = GetTransition(scaledTime, tev.transition);
if (tev.Node.Id >= 0) { if (tev.Node.Id >= 0) {
var start = m.Value.GetRelativeNode(tev.Node.Id); var start = m.Value.GetRelativeNode(tev.Node.Id);
if (start == null) { if (start == null) {
@@ -450,16 +453,30 @@ namespace Cryville.Crtr.Event {
else { else {
var target = value.GetRelativeNode(tev.Node.Id); var target = value.GetRelativeNode(tev.Node.Id);
if (target == null) value.SetRelativeNode(tev.Node); if (target == null) value.SetRelativeNode(tev.Node);
else tev.Node.LerpWith(m.Value.GetRelativeNode(tev.Node.Id), scaledTime, ref target); else tev.Node.LerpWith(m.Value.GetRelativeNode(tev.Node.Id), transition, ref target);
} }
} }
else { else {
tev.Node.Value.LerpWith(m.Value.AbsoluteValue, scaledTime, ref value.AbsoluteValue); tev.Node.Value.LerpWith(m.Value.AbsoluteValue, transition, ref value.AbsoluteValue);
} }
} }
} }
} }
} }
static float _ttime;
static Vector4 _trans;
static readonly PropSrc _ttimesrc = new PropSrc.Float(() => _ttime);
static readonly PropOp _transop = new PropOp.Vector4(v => _trans = v);
Vector4 GetTransition(float time, PdtExpression transition) {
if (time >= 1 || transition == null)
return new Vector4(time, time, time, time);
_ttime = time;
_ttimesrc.Invalidate();
ChartPlayer.etor.ContextSelfValue = _ttimesrc;
ChartPlayer.etor.Evaluate(_transop, transition);
ChartPlayer.etor.ContextSelfValue = null;
return _trans;
}
public void BroadcastPreInit() { public void BroadcastPreInit() {
Handler.PreInit(); Handler.PreInit();

View File

@@ -0,0 +1,19 @@
using Cryville.Common.Pdt;
using Newtonsoft.Json;
using System;
namespace Cryville.Crtr {
public class JsonPdtExpConverter : JsonConverter<PdtExpression> {
static readonly PdtFragmentInterpreter _itor = new PdtFragmentInterpreter();
public override PdtExpression ReadJson(JsonReader reader, Type objectType, PdtExpression existingValue, bool hasExistingValue, JsonSerializer serializer) {
_itor.SetSource((string)reader.Value);
return _itor.GetExp();
}
public override void WriteJson(JsonWriter writer, PdtExpression value, JsonSerializer serializer) {
throw new NotSupportedException();
}
public override bool CanWrite { get { return false; } }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d92ef22b7db80448b0d8f8691267890
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -120,6 +120,7 @@ namespace Cryville.Crtr {
public bool Reset; public bool Reset;
public Vec1 Time; public Vec1 Time;
public Vec1 EndTime; public Vec1 EndTime;
public PdtExpression Transition;
public Vector Value; public Vector Value;
public void Init(Type type) { public void Init(Type type) {
@@ -135,20 +136,20 @@ namespace Cryville.Crtr {
Value.CopyTo(dest.Value); Value.CopyTo(dest.Value);
} }
public void LerpWith(MotionNode start, float lerpedTime, ref MotionNode result) { public void LerpWith(MotionNode start, Vector4 trans, ref MotionNode result) {
result.Id = Id; result.Id = Id;
if (Time == null) result.Time = start.Time; if (Time == null) result.Time = start.Time;
else { else {
var t = (Vector)result.Time; var t = (Vector)result.Time;
Time.LerpWith(start.Time, lerpedTime, ref t); Time.LerpWith(start.Time, trans, ref t);
} }
if (EndTime == null) result.EndTime = start.EndTime; if (EndTime == null) result.EndTime = start.EndTime;
else { else {
var t = (Vector)result.EndTime; var t = (Vector)result.EndTime;
EndTime.LerpWith(start.EndTime, lerpedTime, ref t); EndTime.LerpWith(start.EndTime, trans, ref t);
} }
if (Value == null) result.Value = start.Value; if (Value == null) result.Value = start.Value;
else Value.LerpWith(start.Value, lerpedTime, ref result.Value); else Value.LerpWith(start.Value, trans, ref result.Value);
} }
} }
@@ -185,6 +186,7 @@ namespace Cryville.Crtr {
public abstract void ApplyFrom(Vector parent); public abstract void ApplyFrom(Vector parent);
public abstract void LerpWith(Vector start, float lerpedTime, ref Vector result); public abstract void LerpWith(Vector start, float lerpedTime, ref Vector result);
public abstract void LerpWith(Vector start, Vector4 trans, ref Vector result);
public abstract override string ToString(); public abstract override string ToString();
public abstract unsafe void ToArray(float* arr); public abstract unsafe void ToArray(float* arr);
@@ -227,6 +229,15 @@ namespace Cryville.Crtr {
var s = (Vec1)start; var s = (Vec1)start;
r.Value = s.Value * (1 - lerpedTime) + Value * lerpedTime; r.Value = s.Value * (1 - lerpedTime) + Value * lerpedTime;
} }
public override void LerpWith(Vector start, Vector4 trans, ref Vector result) {
var r = (Vec1)result;
if (start == null) {
r.Value = Value;
return;
}
var s = (Vec1)start;
r.Value = s.Value * (1 - trans.x) + Value * trans.x;
}
public override void CopyTo(Vector dest) { public override void CopyTo(Vector dest) {
var d = (Vec1)dest; var d = (Vec1)dest;
@@ -269,6 +280,15 @@ namespace Cryville.Crtr {
var s = (VecI1)start; var s = (VecI1)start;
r.Value = (int)(s.Value * (1 - lerpedTime) + Value * lerpedTime); r.Value = (int)(s.Value * (1 - lerpedTime) + Value * lerpedTime);
} }
public override void LerpWith(Vector start, Vector4 trans, ref Vector result) {
var r = (VecI1)result;
if (start == null) {
r.Value = Value;
return;
}
var s = (VecI1)start;
r.Value = (int)(s.Value * (1 - trans.x) + Value * trans.x);
}
public override void CopyTo(Vector dest) { public override void CopyTo(Vector dest) {
var d = (VecI1)dest; var d = (VecI1)dest;
@@ -311,6 +331,15 @@ namespace Cryville.Crtr {
var s = (Vec1m)start; var s = (Vec1m)start;
r.Value = s.Value * (1 - lerpedTime) + Value * lerpedTime; r.Value = s.Value * (1 - lerpedTime) + Value * lerpedTime;
} }
public override void LerpWith(Vector start, Vector4 trans, ref Vector result) {
var r = (Vec1m)result;
if (start == null) {
r.Value = Value;
return;
}
var s = (Vec1m)start;
r.Value = s.Value * (1 - trans.x) + Value * trans.x;
}
public override void CopyTo(Vector dest) { public override void CopyTo(Vector dest) {
var d = (Vec1m)dest; var d = (Vec1m)dest;
@@ -355,6 +384,17 @@ namespace Cryville.Crtr {
r.x = s.x * (1 - lerpedTime) + x * lerpedTime; r.x = s.x * (1 - lerpedTime) + x * lerpedTime;
r.y = s.y * (1 - lerpedTime) + y * lerpedTime; r.y = s.y * (1 - lerpedTime) + y * lerpedTime;
} }
public override void LerpWith(Vector start, Vector4 trans, ref Vector result) {
var r = (Vec2)result;
if (start == null) {
r.x = x;
r.y = y;
return;
}
var s = (Vec2)start;
r.x = s.x * (1 - trans.x) + x * trans.x;
r.y = s.y * (1 - trans.y) + y * trans.y;
}
public Vector3 ToVector2() { public Vector3 ToVector2() {
return new Vector3(x, y); return new Vector3(x, y);
@@ -406,6 +446,19 @@ namespace Cryville.Crtr {
r.y = s.y * (1 - lerpedTime) + y * lerpedTime; r.y = s.y * (1 - lerpedTime) + y * lerpedTime;
r.z = s.z * (1 - lerpedTime) + z * lerpedTime; r.z = s.z * (1 - lerpedTime) + z * lerpedTime;
} }
public override void LerpWith(Vector start, Vector4 trans, ref Vector result) {
var r = (Vec3)result;
if (start == null) {
r.x = x;
r.y = y;
r.z = z;
return;
}
var s = (Vec3)start;
r.x = s.x * (1 - trans.x) + x * trans.x;
r.y = s.y * (1 - trans.y) + y * trans.y;
r.z = s.z * (1 - trans.z) + z * trans.z;
}
public Vector3 ToVector3() { public Vector3 ToVector3() {
return new Vector3(x, y, z); return new Vector3(x, y, z);
@@ -428,7 +481,7 @@ namespace Cryville.Crtr {
} }
public unsafe class VectorSrc : PropSrc.FixedBuffer { public unsafe class VectorSrc : PropSrc.FixedBuffer {
const int MAX_DIMENSION = 8; const int MAX_DIMENSION = 4;
protected readonly Func<Vector> _cb; protected readonly Func<Vector> _cb;
public VectorSrc(Func<Vector> cb) : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) { public VectorSrc(Func<Vector> cb) : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) {
_cb = cb; _cb = cb;

View File

@@ -506,20 +506,23 @@ namespace Cryville.Crtr {
var dim1 = GetDimension(op1); var dim1 = GetDimension(op1);
var dim2 = GetDimension(op2); var dim2 = GetDimension(op2);
var dim0 = Math.Min(dim1, dim2); var dim0 = Math.Min(dim1, dim2);
float time; Vector4 trans;
switch (LoadedOperandCount) { switch (LoadedOperandCount) {
case 2: time = oputil.AsNumber(_ctxcb()); break; case 2:
case 3: time = GetOperand(2).AsNumber(); break; var num = oputil.AsNumber(_ctxcb());
trans = new Vector4(num, num, num, num);
break;
case 3: trans = GetTransition(GetOperand(2)); break;
default: throw new ArgumentException("Argument count not 2 or 3"); default: throw new ArgumentException("Argument count not 2 or 3");
} }
if (dim0 == 1) { if (dim0 == 1) {
GetReturnFrame(PdtInternalType.Number, sizeof(float)) GetReturnFrame(PdtInternalType.Number, sizeof(float))
.SetNumber(op1.AsNumber() * (1 - time) + op2.AsNumber() * time); .SetNumber(op1.AsNumber() * (1 - trans.x) + op2.AsNumber() * trans.x);
} }
else { else {
var ret = GetReturnFrame(PdtInternalType.Vector, dim0 * sizeof(float) + sizeof(int)); var ret = GetReturnFrame(PdtInternalType.Vector, dim0 * sizeof(float) + sizeof(int));
for (int i = 0; i < dim0 * sizeof(float); i += sizeof(float)) { for (int i = 0; i < dim0 * sizeof(float); i += sizeof(float)) {
ret.SetNumber(op1.AsNumber(i) * (1 - time) + op2.AsNumber(i) * time, i); ret.SetNumber(op1.AsNumber(i) * (1 - trans[i]) + op2.AsNumber(i) * trans[i], i);
} }
ret.SetArraySuffix(PdtInternalType.Number); ret.SetArraySuffix(PdtInternalType.Number);
} }
@@ -536,6 +539,28 @@ namespace Cryville.Crtr {
default: throw new ArgumentException("Not animatable"); default: throw new ArgumentException("Not animatable");
} }
} }
static Vector4 GetTransition(PdtVariableMemory op) {
switch (op.Type) {
case PdtInternalType.Number:
var num = op.AsNumber();
return new Vector4(num, num, num, num);
case PdtInternalType.Vector:
int arrtype, _;
op.GetArraySuffix(out arrtype, out _);
if (arrtype != PdtInternalType.Number)
throw new ArgumentException("Not animatable");
switch ((op.Length - sizeof(int)) / sizeof(float)) {
case 0: throw new ArgumentException("Empty vector");
case 1:
num = op.AsNumber();
return new Vector4(num, num, num, num);
case 2: return op.As<Vector2>();
case 3: return op.As<Vector3>();
default: return op.As<Vector4>();
}
default: throw new ArgumentException("Not animatable");
}
}
} }
class func_cubic_bezier : PdtOperator { class func_cubic_bezier : PdtOperator {
readonly Func<PropSrc> _ctxcb; readonly Func<PropSrc> _ctxcb;
@@ -552,7 +577,7 @@ namespace Cryville.Crtr {
default: throw new ArgumentException("Argument count not 4 or 5"); default: throw new ArgumentException("Argument count not 4 or 5");
} }
GetReturnFrame(PdtInternalType.Number, sizeof(float)) GetReturnFrame(PdtInternalType.Number, sizeof(float))
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f)); .SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-3f));
} }
} }
class func_cubic_bezier_fixed : PdtOperator { class func_cubic_bezier_fixed : PdtOperator {
@@ -571,17 +596,17 @@ namespace Cryville.Crtr {
default: throw new ArgumentException("Argument count not 0 or 1"); default: throw new ArgumentException("Argument count not 0 or 1");
} }
GetReturnFrame(PdtInternalType.Number, sizeof(float)) GetReturnFrame(PdtInternalType.Number, sizeof(float))
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f)); .SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-3f));
} }
} }
#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("judge_clip_from");
static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn"); static readonly int _var_tn = IdentifierManager.SharedInstance.Request("judge_clip_to");
static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft"); static readonly int _var_ft = IdentifierManager.SharedInstance.Request("input_time_from");
static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt"); static readonly int _var_tt = IdentifierManager.SharedInstance.Request("input_time_to");
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv"); static readonly int _var_fv = IdentifierManager.SharedInstance.Request("input_vec_from");
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv"); static readonly int _var_tv = IdentifierManager.SharedInstance.Request("input_vec_to");
abstract class JudgeFunction : PdtOperator { abstract class JudgeFunction : PdtOperator {
readonly Func<int, PropSrc> _ctxcb; readonly Func<int, PropSrc> _ctxcb;
protected JudgeFunction(int pc, Func<int, PropSrc> ctxcb) : base(pc) { protected JudgeFunction(int pc, Func<int, PropSrc> ctxcb) : base(pc) {

View File

@@ -9,6 +9,7 @@ using RColor = UnityEngine.Color;
using RTargetString = Cryville.Common.Buffers.TargetString; using RTargetString = Cryville.Common.Buffers.TargetString;
using RVector2 = UnityEngine.Vector2; using RVector2 = UnityEngine.Vector2;
using RVector3 = UnityEngine.Vector3; using RVector3 = UnityEngine.Vector3;
using RVector4 = UnityEngine.Vector4;
namespace Cryville.Crtr { namespace Cryville.Crtr {
public abstract class PropOp : PdtOperator { public abstract class PropOp : PdtOperator {
@@ -159,14 +160,27 @@ namespace Cryville.Crtr {
float num = o.AsNumber(); float num = o.AsNumber();
_cb(new RVector3(num, num)); _cb(new RVector3(num, num));
break; break;
case 2: case 2: _cb(o.As<RVector2>()); break;
_cb(o.As<RVector2>()); case 3: _cb(o.As<RVector3>()); break;
default: throw new InvalidOperationException("Invalid array size");
}
}
}
public class Vector4 : PropOp {
readonly Action<RVector4> _cb;
public Vector4(Action<RVector4> cb) { _cb = cb; }
protected override unsafe void Execute() {
var o = GetOperand(0);
switch ((o.Length - 4) / 4) {
case 0: // Number
case 1: // Array[1]
float num = o.AsNumber();
_cb(new RVector4(num, num, num, num));
break; break;
case 3: case 2: _cb(o.As<RVector2>()); break;
_cb(o.As<RVector3>()); case 3: _cb(o.As<RVector3>()); break;
break; case 4: _cb(o.As<RVector4>()); break;
default: default: throw new InvalidOperationException("Invalid array size");
throw new InvalidOperationException("Invalid array size");
} }
} }
} }