Obsolete transition and rate, and add end time for relative motion node.

This commit is contained in:
2023-04-18 09:33:47 +08:00
parent 17d620ff0c
commit f4411629e4
7 changed files with 119 additions and 44 deletions

View File

@@ -0,0 +1,59 @@
using System;
using System.Reflection;
namespace Cryville.Common.Pdt {
/// <summary>
/// Interpreter for fragments in Property Definition Tree (PDT) file format.
/// </summary>
public class PdtFragmentInterpreter : PdtInterpreter {
public PdtFragmentInterpreter() : base(null, new EmptyBinder()) { }
/// <summary>
/// Sets the new source string for the fragment interpreter and resets the position.
/// </summary>
/// <param name="value">The new source string.</param>
public void SetSource(string value) {
Source = value;
Position = 0;
}
/// <summary>
/// The binder.
/// </summary>
public Binder Binder {
get { return _binder; }
set { _binder = value; }
}
/// <summary>
/// Reads the current character and increments the position.
/// </summary>
/// <returns>The current character.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
public new char GetChar() { return base.GetChar(); }
/// <summary>
/// Reads an identifier.
/// </summary>
/// <returns>An identifier.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
public new string GetIdentifier() { return base.GetIdentifier(); }
/// <summary>
/// Reads a number.
/// </summary>
/// <returns>A number.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
public new string GetNumber() { return base.GetNumber(); }
/// <summary>
/// Reads a string.
/// </summary>
/// <returns>A string.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
public new string GetString() { return base.GetString(); }
/// <summary>
/// Reads an expression.
/// </summary>
/// <returns>An expression.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
public new PdtExpression GetExp() { return base.GetExp(); }
}
}

View File

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

View File

@@ -61,12 +61,12 @@ namespace Cryville.Common.Pdt {
/// <summary>
/// The source string.
/// </summary>
public string Source { get; private set; }
Binder _binder;
public string Source { get; protected set; }
protected Binder _binder;
/// <summary>
/// The current position in the string being parsed by the interpreter.
/// </summary>
public int Position { get; private set; }
public int Position { get; protected set; }
#pragma warning disable IDE1006
/// <summary>
/// The character at the current position.

View File

@@ -1,10 +1,10 @@
using Cryville.Common;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using UnsafeIL;
@@ -302,33 +302,47 @@ namespace Cryville.Crtr {
}
#pragma warning restore IDE1006
static readonly PdtFragmentInterpreter _itor = new PdtFragmentInterpreter();
private void LoadFromString(string s) {
if (Node != null)
throw new InvalidOperationException("The motion property can only be set at initialization");
Match m = Regex.Match(s, @"^(.+?)(#(\d+))?(@(.+?))?(\^(.+?))?(\*(.+?))?(:(.+))?$");
Match m = Regex.Match(s, @"^([0-9A-Za-z_]+)(#(\d+))?(.+)?$");
if (!m.Success) throw new ArgumentException("Invalid motion string format");
name = new Identifier(m.Groups[1].Value);
var registry = ChartPlayer.motionRegistry[name];
Node = new MotionNode();
if (m.Groups[3].Success) {
short id = short.Parse(m.Groups[3].Value);
if (id < 0) throw new ArgumentException("Got negative motion node index");
Vec1 time = m.Groups[5].Success ? new Vec1(m.Groups[5].Value) : null;
byte? trs = m.Groups[7].Success ? byte.Parse(m.Groups[7].Value) : null;
Vec1 rate = m.Groups[9].Success ? new Vec1(m.Groups[9].Value) : null;
Vector value = m.Groups[11].Success ? Vector.Construct(registry.Type, m.Groups[11].Value) : null;
Node = new MotionNode {
Id = id,
Time = time,
Transition = (TransitionType?)trs,
Rate = rate,
Value = value
};
Node.Id = id;
}
else {
Node = new MotionNode {
Value = Vector.Construct(registry.Type, m.Groups[11].Value)
};
if (m.Groups[4].Success) {
_itor.SetSource(m.Groups[4].Value);
while (_itor.Position < _itor.Source.Length) {
var c = _itor.GetChar();
var exp = _itor.GetExp();
switch (c) {
case '@':
ChartPlayer.etor.Evaluate(new VectorOp(v => {
Node.Time = new Vec1(v);
}), exp);
break;
case '!':
ChartPlayer.etor.Evaluate(new VectorOp(v => {
Node.EndTime = new Vec1(v);
}), exp);
break;
case ':':
ChartPlayer.etor.Evaluate(new VectorOp(v => {
Node.Value = Vector.Construct(ChartPlayer.motionRegistry[Name].Type, v);
}), exp);
break;
default:
throw new ArgumentException("Invalid motion string format");
}
}
}
else Node.Reset = true;
SubmitPropSrc("value", new VectorSrc(() => Node.Value));
}
@@ -338,8 +352,7 @@ namespace Cryville.Crtr {
var node = Node;
result += "#" + node.Id;
if (node.Time != null) result += "@" + node.Time.ToString();
if (node.Transition != null) result = "^" + ((byte)node.Transition).ToString(CultureInfo.InvariantCulture);
if (node.Rate != null) result += "*" + node.Rate.ToString();
if (node.EndTime != null) result += "~" + node.EndTime.ToString();
if (node.Value != null) result += ":" + node.Value.ToString();
}
else {
@@ -367,10 +380,6 @@ namespace Cryville.Crtr {
[JsonIgnore]
public MotionNode Node;
[DefaultValue(TransitionType.Ease)][Obsolete]
public TransitionType transition = TransitionType.Ease;
[DefaultValue(1.0f)][Obsolete]
public float rate = 1.0f;
[DefaultValue(0.0f)]
public float sumfix = 0.0f;

View File

@@ -586,7 +586,7 @@ namespace Cryville.Crtr {
MissingMemberHandling = MissingMemberHandling.Error
});
if (chart.format != 2) throw new FormatException("Invalid chart file format version");
if (chart.format != 3) throw new FormatException("Invalid chart file format version");
etor = new PdtEvaluator(); loadPregress = .05f;

View File

@@ -403,7 +403,7 @@ namespace Cryville.Crtr.Event {
}
else {
var scaledTime = (float)((Time - m.Key.Time - ChartPlayer.actualRenderStep * tev.sumfix) / m.Key.Duration);
var lerpedTime = MotionLerper.GetEaseTime(scaledTime, tev.transition, tev.rate);
var lerpedTime = MotionLerper.GetEaseTime(scaledTime, TransitionType.Ease, 1);
if (tev.Node.Id >= 0) {
var start = m.Value.GetRelativeNode(tev.Node.Id);
if (start == null) {

View File

@@ -132,8 +132,7 @@ namespace Cryville.Crtr {
new MotionNode() {
Id = 0,
Time = new Vec1(0),
Transition = TransitionType.Ease,
Rate = new Vec1(1),
EndTime = new Vec1(0),
Value = init
}
};
@@ -181,9 +180,8 @@ namespace Cryville.Crtr {
cnode = new MotionNode {
Id = node.Id,
Time = new Vec1(0),
Transition = TransitionType.Ease,
Rate = new Vec1(1),
Value = (Vector)Activator.CreateInstance(node.Value.GetType())
EndTime = new Vec1(0),
Value = (Vector)Activator.CreateInstance(AbsoluteValue.GetType())
};
}
else {
@@ -191,8 +189,7 @@ namespace Cryville.Crtr {
RelativeNodes.RemoveAt(i);
}
if (node.Time != null) cnode.Time = node.Time;
if (node.Transition != null) cnode.Transition = node.Transition;
if (node.Rate != null) cnode.Rate = node.Rate;
if (node.EndTime != null) cnode.EndTime = node.EndTime;
if (node.Value != null) cnode.Value.ReplaceFrom(node.Value);
int i2 = RelativeNodes.BinarySearch(cnode);
@@ -207,6 +204,7 @@ namespace Cryville.Crtr {
/// <param name="reltime">The relative time.</param>
/// <param name="result">The result.</param>
/// <returns></returns>
[Obsolete]
public void GetValue<T>(float reltime, ref T result) where T : Vector {
int i = BinarySearch(reltime);
if (i >= 0) RelativeNodes[i].Value.CopyTo(result);
@@ -243,7 +241,9 @@ namespace Cryville.Crtr {
public class MotionNode : IComparable<MotionNode> {
public short Id = -1;
public bool Reset;
public Vec1 Time;
public Vec1 EndTime;
float CmpTime { get { return Time != null ? Time.Value : 0; } }
[Obsolete]
public TransitionType? Transition;
@@ -255,8 +255,7 @@ namespace Cryville.Crtr {
return new MotionNode() {
Id = Id,
Time = (Vec1)Time.Clone(),
Transition = Transition,
Rate = (Vec1)Rate.Clone(),
EndTime = (Vec1)EndTime.Clone(),
Value = Value.Clone()
};
}
@@ -264,8 +263,7 @@ namespace Cryville.Crtr {
public void CopyTo(MotionNode dest) {
dest.Id = Id;
Time.CopyTo(dest.Time);
dest.Transition = Transition;
Rate.CopyTo(dest.Rate);
EndTime.CopyTo(dest.EndTime);
Value.CopyTo(dest.Value);
}
@@ -280,12 +278,10 @@ namespace Cryville.Crtr {
var t = (Vector)result.Time;
Time.LerpWith(start.Time, lerpedTime, ref t);
}
if (Transition == null) result.Transition = start.Transition;
else result.Transition = Transition;
if (Rate == null) result.Rate = start.Rate;
if (EndTime == null) result.EndTime = start.EndTime;
else {
var t = (Vector)result.Rate;
Rate.LerpWith(start.Rate, lerpedTime, ref t);
var t = (Vector)result.EndTime;
EndTime.LerpWith(start.EndTime, lerpedTime, ref t);
}
if (Value == null) result.Value = start.Value;
else Value.LerpWith(start.Value, lerpedTime, ref result.Value);