Unify absolute value and relative node of motion event.

This commit is contained in:
2023-04-04 21:18:34 +08:00
parent fd7c1e6635
commit 676d19f452
3 changed files with 25 additions and 29 deletions

View File

@@ -303,19 +303,20 @@ namespace Cryville.Crtr {
#pragma warning restore IDE1006 #pragma warning restore IDE1006
private void LoadFromString(string s) { private void LoadFromString(string s) {
if (RelativeNode != null || AbsoluteValue != null) if (Node != null)
throw new InvalidOperationException("The motion property can only be set at initialization"); throw new InvalidOperationException("The motion property can only be set at initialization");
Match m = Regex.Match(s, @"^(.+?)(#(\d+))?(@(.+?))?(\^(.+?))?(\*(.+?))?(:(.+))?$"); Match m = Regex.Match(s, @"^(.+?)(#(\d+))?(@(.+?))?(\^(.+?))?(\*(.+?))?(:(.+))?$");
if (!m.Success) throw new ArgumentException("Invalid motion string format"); if (!m.Success) throw new ArgumentException("Invalid motion string format");
name = new Identifier(m.Groups[1].Value); name = new Identifier(m.Groups[1].Value);
var registry = ChartPlayer.motionRegistry[name]; var registry = ChartPlayer.motionRegistry[name];
if (m.Groups[3].Success) { if (m.Groups[3].Success) {
ushort id = ushort.Parse(m.Groups[3].Value); 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; 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; 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; 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; Vector value = m.Groups[11].Success ? Vector.Construct(registry.Type, m.Groups[11].Value) : null;
RelativeNode = new MotionNode() { Node = new MotionNode {
Id = id, Id = id,
Time = time, Time = time,
Transition = (TransitionType?)trs, Transition = (TransitionType?)trs,
@@ -324,18 +325,17 @@ namespace Cryville.Crtr {
}; };
} }
else { else {
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value); Node = new MotionNode {
Value = Vector.Construct(registry.Type, m.Groups[11].Value)
};
} }
SubmitPropSrc("value", new VectorSrc(() => { SubmitPropSrc("value", new VectorSrc(() => Node.Value));
if (RelativeNode != null) return RelativeNode.Value;
else return AbsoluteValue;
}));
} }
public override string ToString() { public override string ToString() {
string result = Name.ToString(); string result = Name.ToString();
if (RelativeNode != null) { if (Node.Id >= 0) {
var node = RelativeNode; var node = Node;
result += "#" + node.Id; result += "#" + node.Id;
if (node.Time != null) result += "@" + node.Time.ToString(); if (node.Time != null) result += "@" + node.Time.ToString();
if (node.Transition != null) result = "^" + ((byte)node.Transition).ToString(CultureInfo.InvariantCulture); if (node.Transition != null) result = "^" + ((byte)node.Transition).ToString(CultureInfo.InvariantCulture);
@@ -343,7 +343,7 @@ namespace Cryville.Crtr {
if (node.Value != null) result += ":" + node.Value.ToString(); if (node.Value != null) result += ":" + node.Value.ToString();
} }
else { else {
result += ":" + AbsoluteValue.ToString(); result += ":" + Node.Value.ToString();
} }
return result; return result;
} }
@@ -359,16 +359,13 @@ namespace Cryville.Crtr {
MotionRegistry reg; MotionRegistry reg;
if (!ChartPlayer.motionRegistry.TryGetValue(value, out reg)) if (!ChartPlayer.motionRegistry.TryGetValue(value, out reg))
throw new ArgumentException("Invalid motion name"); throw new ArgumentException("Invalid motion name");
if (RelativeNode != null) RelativeNode.Value = reg.InitValue; Node = new MotionNode { Value = reg.InitValue };
else AbsoluteValue = reg.InitValue;
name = value; name = value;
} }
} }
[JsonIgnore] [JsonIgnore]
public Vector AbsoluteValue; public MotionNode Node;
[JsonIgnore]
public MotionNode RelativeNode;
[DefaultValue(TransitionType.Ease)][Obsolete] [DefaultValue(TransitionType.Ease)][Obsolete]
public TransitionType transition = TransitionType.Ease; public TransitionType transition = TransitionType.Ease;
@@ -391,8 +388,7 @@ namespace Cryville.Crtr {
})); }));
SubmitPropOp("value", new VectorOp(v => { SubmitPropOp("value", new VectorOp(v => {
var vec = Vector.Construct(ChartPlayer.motionRegistry[Name].Type, v); var vec = Vector.Construct(ChartPlayer.motionRegistry[Name].Type, v);
if (RelativeNode != null) RelativeNode.Value = vec; Node.Value = vec;
else AbsoluteValue = vec;
})); }));
} }
} }

View File

@@ -390,26 +390,26 @@ namespace Cryville.Crtr.Event {
private void UpdateMotions() { private void UpdateMotions() {
foreach (var m in PlayingMotions) { foreach (var m in PlayingMotions) {
var tev = (Chart.Motion)m.Key.Unstamped; var tev = (Chart.Motion)m.Key.Unstamped;
if (tev.RelativeNode != null && CloneType == 2) continue; if (tev.Node.Id >= 0 && CloneType == 2) continue;
var value = GetMotionValue(tev.Name.Key/*, true*/); var value = GetMotionValue(tev.Name.Key/*, true*/);
InvalidateMotion(tev.Name.Key); InvalidateMotion(tev.Name.Key);
if (m.Key.Duration == 0) { if (m.Key.Duration == 0) {
if (tev.RelativeNode != null) { if (tev.Node.Id >= 0) {
value.SetRelativeNode(tev.RelativeNode); value.SetRelativeNode(tev.Node);
} }
else { else {
value.AbsoluteValue.ReplaceFrom(tev.AbsoluteValue); value.AbsoluteValue.ReplaceFrom(tev.Node.Value);
} }
} }
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 lerpedTime = MotionLerper.GetEaseTime(scaledTime, tev.transition, tev.rate); var lerpedTime = MotionLerper.GetEaseTime(scaledTime, tev.transition, tev.rate);
if (tev.RelativeNode != null) { if (tev.Node.Id >= 0) {
var target = value.QueryRelativeNode(tev.RelativeNode.Id); var target = value.QueryRelativeNode(tev.Node.Id);
tev.RelativeNode.LerpWith(m.Value.GetRelativeNode(tev.RelativeNode.Id), lerpedTime, ref target); tev.Node.LerpWith(m.Value.GetRelativeNode(tev.Node.Id), lerpedTime, ref target);
} }
else { else {
tev.AbsoluteValue.LerpWith(m.Value.AbsoluteValue, lerpedTime, ref value.AbsoluteValue); tev.Node.Value.LerpWith(m.Value.AbsoluteValue, lerpedTime, ref value.AbsoluteValue);
} }
} }
Values[tev.Name.Key] = value; Values[tev.Name.Key] = value;

View File

@@ -170,7 +170,7 @@ namespace Cryville.Crtr {
dest.RelativeNodes.RemoveRange(tcount, dcount - tcount); dest.RelativeNodes.RemoveRange(tcount, dcount - tcount);
} }
public MotionNode GetRelativeNode(ushort id) { public MotionNode GetRelativeNode(short id) {
int i = RelativeNodes.FindIndex(n => n.Id == id); int i = RelativeNodes.FindIndex(n => n.Id == id);
if (i == -1) { if (i == -1) {
var r = GetRelativeNode((ushort)(id - 1)); var r = GetRelativeNode((ushort)(id - 1));
@@ -181,7 +181,7 @@ namespace Cryville.Crtr {
return RelativeNodes[i]; return RelativeNodes[i];
} }
public MotionNode QueryRelativeNode(ushort id) { public MotionNode QueryRelativeNode(short id) {
int i = RelativeNodes.FindIndex(n => n.Id == id); int i = RelativeNodes.FindIndex(n => n.Id == id);
MotionNode cnode; MotionNode cnode;
if (i == -1) cnode = new MotionNode { Id = id }; if (i == -1) cnode = new MotionNode { Id = id };
@@ -256,7 +256,7 @@ namespace Cryville.Crtr {
} }
public class MotionNode : IComparable<MotionNode> { public class MotionNode : IComparable<MotionNode> {
public ushort Id; public short Id = -1;
public Vec1 Time; public Vec1 Time;
float CmpTime { get { return Time != null ? Time.Value : 0; } } float CmpTime { get { return Time != null ? Time.Value : 0; } }
[Obsolete] [Obsolete]