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.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;

View File

@@ -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);

View File

@@ -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();

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 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<Vector> _cb;
public VectorSrc(Func<Vector> cb) : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) {
_cb = cb;

View File

@@ -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<Vector2>();
case 3: return op.As<Vector3>();
default: return op.As<Vector4>();
}
default: throw new ArgumentException("Not animatable");
}
}
}
class func_cubic_bezier : PdtOperator {
readonly Func<PropSrc> _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<int, PropSrc> _ctxcb;
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 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<RVector2>());
case 2: _cb(o.As<RVector2>()); break;
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;
case 3:
_cb(o.As<RVector3>());
break;
default:
throw new InvalidOperationException("Invalid array size");
case 2: _cb(o.As<RVector2>()); break;
case 3: _cb(o.As<RVector3>()); break;
case 4: _cb(o.As<RVector4>()); break;
default: throw new InvalidOperationException("Invalid array size");
}
}
}