Re-implement relative motion.

This commit is contained in:
2023-04-19 13:54:35 +08:00
parent 1b30d3e62c
commit 2b3898655f
5 changed files with 116 additions and 26 deletions

View File

@@ -158,6 +158,8 @@ namespace Cryville.Crtr {
UnityEngine.Profiling.Profiler.EndSample();
actualRenderStep = step;
nbus.PreAnchor();
nbus.StripTempEvents();
nbus.ForwardStepByTime(clippingDist, step);
nbus.EndPreGraphicalUpdate();
nbus.Anchor();

View File

@@ -203,6 +203,7 @@ namespace Cryville.Crtr.Event {
}
#endregion
#region Anchor
public virtual void PreAnchor() { }
public virtual void Anchor() {
foreach (var p in PropSrcs) p.Value.Invalidate();
foreach (var a in DynamicAnchors) DynamicAnchorSetTime[a.Key] = double.NaN;

View File

@@ -331,6 +331,12 @@ namespace Cryville.Crtr.Event {
public void Discard(StampedEvent ev) {
Handler.Discard(this, ev);
if (ev is StampedEvent.RelativeMotion) {
relmEvPool.Return((StampedEvent.RelativeMotion)ev);
}
else if (ev.Origin is StampedEvent.RelativeMotion) {
erelmEvPool.Return((StampedEvent.Temporary)ev);
}
}
public void Handle(StampedEvent ev) {
@@ -348,6 +354,19 @@ namespace Cryville.Crtr.Event {
_rmvpa.Return(mv);
}
}
else if (ev is StampedEvent.RelativeMotion) {
var tev = (StampedEvent.RelativeMotion)ev;
var mv = _rmvpa.Rent(tev.Name);
mv.CloneTypeFlag = CloneType;
GetMotionValue(tev.Name).CopyTo(mv);
PlayingMotions.Add(ev, mv);
Update(ev);
if (ev.Duration == 0) {
PlayingMotions.Remove(ev);
_rmvpa.Return(mv);
relmEvPool.Return(tev);
}
}
else if (ev.Unstamped is EventContainer) {
var cev = (EventContainer)ev.Unstamped;
var ccs = GetChild(cev);
@@ -357,20 +376,30 @@ namespace Cryville.Crtr.Event {
ccs.LogicalActive = false;
}
}
else if (ev.Unstamped is ReleaseEvent) {
var tev = (ReleaseEvent)ev.Unstamped;
var nev = tev.Original;
if (nev is Chart.Motion) {
else if (ev.Origin != null) {
var oev = ev.Origin;
if (oev is StampedEvent.RelativeMotion) {
Update(ev);
var mv = PlayingMotions[ev.Origin];
var mv = PlayingMotions[oev];
if (mv.CloneTypeFlag == CloneType) _rmvpa.Return(mv);
PlayingMotions.Remove(ev.Origin);
PlayingMotions.Remove(oev);
erelmEvPool.Return((StampedEvent.Temporary)ev);
relmEvPool.Return((StampedEvent.RelativeMotion)oev);
}
else if (nev is EventContainer) {
var cev = (EventContainer)ev.Origin.Unstamped;
var ccs = GetChild(cev);
UpdateMotions();
ccs.LogicalActive = false;
else {
var nev = oev.Unstamped;
if (nev is Chart.Motion) {
Update(ev);
var mv = PlayingMotions[oev];
if (mv.CloneTypeFlag == CloneType) _rmvpa.Return(mv);
PlayingMotions.Remove(oev);
}
else if (nev is EventContainer) {
var cev = (EventContainer)nev;
var ccs = GetChild(cev);
UpdateMotions();
ccs.LogicalActive = false;
}
}
}
Update(ev.Unstamped == null || ev.Unstamped.Priority >= 0 ? ev : null);
@@ -386,32 +415,45 @@ namespace Cryville.Crtr.Event {
private void UpdateMotions() {
foreach (var m in PlayingMotions) {
var tev = (Chart.Motion)m.Key.Unstamped;
if (tev.Node.Id >= 0 && CloneType == 2) continue;
var value = GetMotionValue(tev.Name.Key);
InvalidateMotion(tev.Name.Key);
if (m.Key.Duration == 0) {
if (tev.Node.Id >= 0) {
value.SetRelativeNode(tev.Node);
if (m.Key is StampedEvent.RelativeMotion) {
var tev = (StampedEvent.RelativeMotion)m.Key;
var value = GetMotionValue(tev.Name);
InvalidateMotion(tev.Name);
if (tev.Duration == 0) {
tev.Node.Value.CopyTo(value.RelativeValue);
}
else {
tev.Node.Value.CopyTo(value.AbsoluteValue);
var scaledTime = (float)((Time - tev.Time) / tev.Duration);
tev.Node.Value.LerpWith(m.Value.RelativeValue, scaledTime, ref value.RelativeValue);
}
}
else {
var scaledTime = (float)((Time - m.Key.Time - ChartPlayer.actualRenderStep * tev.sumfix) / m.Key.Duration);
if (tev.Node.Id >= 0) {
var start = m.Value.GetRelativeNode(tev.Node.Id);
if (start == null) {
var tev = (Chart.Motion)m.Key.Unstamped;
if (tev.Node.Id >= 0 && (CloneType == 2 || CloneType == 3)) continue;
var value = GetMotionValue(tev.Name.Key);
InvalidateMotion(tev.Name.Key);
if (m.Key.Duration == 0) {
if (tev.Node.Id >= 0) {
value.SetRelativeNode(tev.Node);
}
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);
tev.Node.Value.CopyTo(value.AbsoluteValue);
}
}
else {
var scaledTime = (float)((Time - m.Key.Time - ChartPlayer.actualRenderStep * tev.sumfix) / m.Key.Duration);
if (tev.Node.Id >= 0) {
var start = m.Value.GetRelativeNode(tev.Node.Id);
if (start == null) {
value.SetRelativeNode(tev.Node);
}
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.Value.LerpWith(m.Value.AbsoluteValue, scaledTime, ref value.AbsoluteValue);
}
}
@@ -446,12 +488,45 @@ namespace Cryville.Crtr.Event {
}
}
static readonly SimpleObjectPool<StampedEvent.RelativeMotion> relmEvPool
= new SimpleObjectPool<StampedEvent.RelativeMotion>(1024);
static readonly SimpleObjectPool<StampedEvent.Temporary> erelmEvPool
= new SimpleObjectPool<StampedEvent.Temporary>(1024);
public void PreAnchor() {
PushRelativeMotions(Handler.ns.Bus);
Handler.PreAnchor();
foreach (var ls in Children) {
if (ls.Value.Handler.Alive) ls.Value.PreAnchor();
}
}
public void Anchor() {
PushRelativeMotions(Handler.ts.Bus);
Handler.Anchor();
foreach (var ls in Children) {
if (ls.Value.Handler.Alive) ls.Value.Anchor();
}
}
void PushRelativeMotions(EventBus bus) {
foreach (var m in Values) {
foreach (var node in m.Value.RelativeNodes) {
var ev = relmEvPool.Rent();
ev.Time = rootPrototype.Time + node.Value.Time.Value;
ev.Container = Container;
ev.Name = m.Key;
ev.Node = node.Value;
ev.ReleaseEvent = null;
bus.PushTempEvent(ev);
if (node.Value.EndTime.Value > node.Value.Time.Value) {
var eev = erelmEvPool.Rent();
eev.Time = rootPrototype.Time + node.Value.EndTime.Value;
eev.Container = Container;
eev.Origin = ev;
ev.ReleaseEvent = eev;
bus.PushTempEvent(eev);
}
}
}
}
#endregion
}
}

View File

@@ -175,6 +175,7 @@ namespace Cryville.Crtr.Event {
public void EndPreGraphicalUpdate() {
RootState.EndPreGraphicalUpdate();
ClearTempEvents();
}
public void EndGraphicalUpdate() {
RootState.EndGraphicalUpdate();
@@ -190,6 +191,10 @@ namespace Cryville.Crtr.Event {
tempEvents.Clear();
}
public void PreAnchor() {
if (RootState.Handler.Alive) RootState.PreAnchor();
}
public void Anchor() {
if (RootState.Handler.Alive) RootState.Anchor();
}

View File

@@ -54,6 +54,13 @@ namespace Cryville.Crtr {
}
}
public class RelativeMotion : Temporary {
public int Name { get; set; }
public MotionNode Node { get; set; }
public override bool CanDiscard { get { return false; } }
public override int Priority { get { return -2; } }
}
public StampedEvent ReleaseEvent { get; set; }
public override string ToString() {