From 8670482c0487992c95d89a2dff1ece9c67f834eb Mon Sep 17 00:00:00 2001 From: PopSlime Date: Thu, 20 Apr 2023 00:18:49 +0800 Subject: [PATCH] Implement new transition. --- Assets/Cryville/Crtr/Chart.cs | 5 ++ .../Crtr/ChartCompatibilityHandler.cs | 3 + Assets/Cryville/Crtr/Event/ContainerState.cs | 23 ++++++- Assets/Cryville/Crtr/JsonPdtExpConverter.cs | 19 ++++++ .../Cryville/Crtr/JsonPdtExpConverter.cs.meta | 11 ++++ Assets/Cryville/Crtr/Motion.cs | 63 +++++++++++++++++-- Assets/Cryville/Crtr/PdtEvaluator.cs | 51 +++++++++++---- Assets/Cryville/Crtr/PropOp.cs | 28 ++++++--- 8 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 Assets/Cryville/Crtr/JsonPdtExpConverter.cs create mode 100644 Assets/Cryville/Crtr/JsonPdtExpConverter.cs.meta diff --git a/Assets/Cryville/Crtr/Chart.cs b/Assets/Cryville/Crtr/Chart.cs index 5ac91c2..325caaa 100644 --- a/Assets/Cryville/Crtr/Chart.cs +++ b/Assets/Cryville/Crtr/Chart.cs @@ -1,5 +1,6 @@ using Cryville.Common; using Cryville.Common.Collections.Specialized; +using Cryville.Common.Pdt; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -237,6 +238,7 @@ namespace Cryville.Crtr { result += "#" + node.Id; if (node.Time != null) result += "@" + node.Time.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(); } else { @@ -264,6 +266,9 @@ namespace Cryville.Crtr { [JsonIgnore] public MotionNode Node; + [JsonConverter(typeof(JsonPdtExpConverter))] + public PdtExpression transition; + [DefaultValue(0.0f)] public float sumfix = 0.0f; diff --git a/Assets/Cryville/Crtr/ChartCompatibilityHandler.cs b/Assets/Cryville/Crtr/ChartCompatibilityHandler.cs index 2773653..e7c042c 100644 --- a/Assets/Cryville/Crtr/ChartCompatibilityHandler.cs +++ b/Assets/Cryville/Crtr/ChartCompatibilityHandler.cs @@ -106,6 +106,9 @@ namespace Cryville.Crtr { ChartPlayer.etor.Evaluate(_vecop, exp); node.EndTime = new Vec1(_vecbuf); break; + case '^': + node.Transition = exp; + break; case ':': ChartPlayer.etor.Evaluate(_vecop, exp); node.Value = Vector.Construct(ChartPlayer.motionRegistry[name].Type, _vecbuf); diff --git a/Assets/Cryville/Crtr/Event/ContainerState.cs b/Assets/Cryville/Crtr/Event/ContainerState.cs index 983cc9e..994675f 100644 --- a/Assets/Cryville/Crtr/Event/ContainerState.cs +++ b/Assets/Cryville/Crtr/Event/ContainerState.cs @@ -1,6 +1,7 @@ using Cryville.Common; using Cryville.Common.Buffers; using Cryville.Common.Collections.Specialized; +using Cryville.Common.Pdt; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -424,7 +425,8 @@ namespace Cryville.Crtr.Event { } else { 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 { @@ -442,6 +444,7 @@ namespace Cryville.Crtr.Event { } else { 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) { var start = m.Value.GetRelativeNode(tev.Node.Id); if (start == null) { @@ -450,16 +453,30 @@ namespace Cryville.Crtr.Event { else { var target = value.GetRelativeNode(tev.Node.Id); 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 { - 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() { Handler.PreInit(); diff --git a/Assets/Cryville/Crtr/JsonPdtExpConverter.cs b/Assets/Cryville/Crtr/JsonPdtExpConverter.cs new file mode 100644 index 0000000..795ee85 --- /dev/null +++ b/Assets/Cryville/Crtr/JsonPdtExpConverter.cs @@ -0,0 +1,19 @@ +using Cryville.Common.Pdt; +using Newtonsoft.Json; +using System; + +namespace Cryville.Crtr { + public class JsonPdtExpConverter : JsonConverter { + 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; } } + } +} diff --git a/Assets/Cryville/Crtr/JsonPdtExpConverter.cs.meta b/Assets/Cryville/Crtr/JsonPdtExpConverter.cs.meta new file mode 100644 index 0000000..c5e09a7 --- /dev/null +++ b/Assets/Cryville/Crtr/JsonPdtExpConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d92ef22b7db80448b0d8f8691267890 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Cryville/Crtr/Motion.cs b/Assets/Cryville/Crtr/Motion.cs index 01882bd..8a6c3cd 100644 --- a/Assets/Cryville/Crtr/Motion.cs +++ b/Assets/Cryville/Crtr/Motion.cs @@ -120,6 +120,7 @@ namespace Cryville.Crtr { public bool Reset; public Vec1 Time; public Vec1 EndTime; + public PdtExpression Transition; public Vector Value; public void Init(Type type) { @@ -135,20 +136,20 @@ namespace Cryville.Crtr { 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; if (Time == null) result.Time = start.Time; else { 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; else { 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; - 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 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 unsafe void ToArray(float* arr); @@ -227,6 +229,15 @@ namespace Cryville.Crtr { var s = (Vec1)start; 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) { var d = (Vec1)dest; @@ -269,6 +280,15 @@ namespace Cryville.Crtr { var s = (VecI1)start; 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) { var d = (VecI1)dest; @@ -311,6 +331,15 @@ namespace Cryville.Crtr { var s = (Vec1m)start; 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) { var d = (Vec1m)dest; @@ -355,6 +384,17 @@ namespace Cryville.Crtr { r.x = s.x * (1 - lerpedTime) + x * 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() { return new Vector3(x, y); @@ -406,6 +446,19 @@ namespace Cryville.Crtr { r.y = s.y * (1 - lerpedTime) + y * 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() { return new Vector3(x, y, z); @@ -428,7 +481,7 @@ namespace Cryville.Crtr { } public unsafe class VectorSrc : PropSrc.FixedBuffer { - const int MAX_DIMENSION = 8; + const int MAX_DIMENSION = 4; protected readonly Func _cb; public VectorSrc(Func cb) : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) { _cb = cb; diff --git a/Assets/Cryville/Crtr/PdtEvaluator.cs b/Assets/Cryville/Crtr/PdtEvaluator.cs index 7ca773f..8ca8a2c 100644 --- a/Assets/Cryville/Crtr/PdtEvaluator.cs +++ b/Assets/Cryville/Crtr/PdtEvaluator.cs @@ -506,20 +506,23 @@ namespace Cryville.Crtr { var dim1 = GetDimension(op1); var dim2 = GetDimension(op2); var dim0 = Math.Min(dim1, dim2); - float time; + Vector4 trans; switch (LoadedOperandCount) { - case 2: time = oputil.AsNumber(_ctxcb()); break; - case 3: time = GetOperand(2).AsNumber(); break; + case 2: + 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"); } if (dim0 == 1) { GetReturnFrame(PdtInternalType.Number, sizeof(float)) - .SetNumber(op1.AsNumber() * (1 - time) + op2.AsNumber() * time); + .SetNumber(op1.AsNumber() * (1 - trans.x) + op2.AsNumber() * trans.x); } else { var ret = GetReturnFrame(PdtInternalType.Vector, dim0 * sizeof(float) + sizeof(int)); 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); } @@ -536,6 +539,28 @@ namespace Cryville.Crtr { 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(); + case 3: return op.As(); + default: return op.As(); + } + default: throw new ArgumentException("Not animatable"); + } + } } class func_cubic_bezier : PdtOperator { readonly Func _ctxcb; @@ -552,7 +577,7 @@ namespace Cryville.Crtr { 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)); + .SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-3f)); } } class func_cubic_bezier_fixed : PdtOperator { @@ -571,17 +596,17 @@ namespace Cryville.Crtr { 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)); + .SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-3f)); } } #endregion #region Judge Functions - static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn"); - static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn"); - static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft"); - static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt"); - static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv"); - static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv"); + static readonly int _var_fn = IdentifierManager.SharedInstance.Request("judge_clip_from"); + static readonly int _var_tn = IdentifierManager.SharedInstance.Request("judge_clip_to"); + static readonly int _var_ft = IdentifierManager.SharedInstance.Request("input_time_from"); + static readonly int _var_tt = IdentifierManager.SharedInstance.Request("input_time_to"); + static readonly int _var_fv = IdentifierManager.SharedInstance.Request("input_vec_from"); + static readonly int _var_tv = IdentifierManager.SharedInstance.Request("input_vec_to"); abstract class JudgeFunction : PdtOperator { readonly Func _ctxcb; protected JudgeFunction(int pc, Func ctxcb) : base(pc) { diff --git a/Assets/Cryville/Crtr/PropOp.cs b/Assets/Cryville/Crtr/PropOp.cs index a7c3744..ffdb2eb 100644 --- a/Assets/Cryville/Crtr/PropOp.cs +++ b/Assets/Cryville/Crtr/PropOp.cs @@ -9,6 +9,7 @@ using RColor = UnityEngine.Color; using RTargetString = Cryville.Common.Buffers.TargetString; using RVector2 = UnityEngine.Vector2; using RVector3 = UnityEngine.Vector3; +using RVector4 = UnityEngine.Vector4; namespace Cryville.Crtr { public abstract class PropOp : PdtOperator { @@ -159,14 +160,27 @@ namespace Cryville.Crtr { float num = o.AsNumber(); _cb(new RVector3(num, num)); break; - case 2: - _cb(o.As()); + case 2: _cb(o.As()); break; + case 3: _cb(o.As()); break; + default: throw new InvalidOperationException("Invalid array size"); + } + } + } + public class Vector4 : PropOp { + readonly Action _cb; + public Vector4(Action 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; - case 3: - _cb(o.As()); - break; - default: - throw new InvalidOperationException("Invalid array size"); + case 2: _cb(o.As()); break; + case 3: _cb(o.As()); break; + case 4: _cb(o.As()); break; + default: throw new InvalidOperationException("Invalid array size"); } } }