144 lines
3.9 KiB
C#
144 lines
3.9 KiB
C#
using Cryville.Crtr.Skin.Components;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Crtr.Event {
|
|
public abstract class TransformHandler : ContainerHandler {
|
|
protected abstract TransformHandler Parent { get; }
|
|
public override void Init() {
|
|
base.Init();
|
|
sgos = Components.OfType<SectionalGameObject>().ToArray();
|
|
}
|
|
|
|
SectionalGameObject[] sgos;
|
|
|
|
bool sflag; // Did pre-graphical update
|
|
Vector3 spos; // Start position offset
|
|
Vector3 ppt = Vector3.zero; // Previous screen point
|
|
Vector3 plp = Vector3.zero; // Previous local point
|
|
Vector3 pwp = Vector3.zero; // Previous world point
|
|
Vector3 ppwp = Vector3.zero; // Previous parent world point
|
|
double ptime; // Previous time
|
|
float length;
|
|
|
|
public override void StartPhysicalUpdate(ContainerState s) {
|
|
base.StartPhysicalUpdate(s);
|
|
if (CanDoGraphicalUpdate(s)) {
|
|
TransformAwake(s);
|
|
}
|
|
}
|
|
protected override void StartPreGraphicalUpdate(ContainerState s) {
|
|
base.StartPreGraphicalUpdate(s);
|
|
spos = Vector3.zero;
|
|
sflag = true;
|
|
pwp = Parent != null ? Parent.Position : Vector3.zero;
|
|
TransformAwake(s);
|
|
}
|
|
protected override void StartGraphicalUpdate(ContainerState s) {
|
|
base.StartGraphicalUpdate(s);
|
|
if (RootTransform) {
|
|
if (!sflag && Parent != null) { // No pre-graphical update; inherit from parent
|
|
spos = Parent.Position + (Vector3)s.ScreenPoint - (Vector3)s.Parent.ScreenPoint;
|
|
}
|
|
TransformAwake(s);
|
|
var p = Position;
|
|
foreach (var i in sgos) {
|
|
i.Reset();
|
|
i.AppendPoint(p, Rotation);
|
|
}
|
|
}
|
|
}
|
|
void TransformAwake(ContainerState s) {
|
|
plp = s.ScreenPoint;
|
|
pwp = Vector3.zero;
|
|
ptime = s.Time;
|
|
Position = spos;
|
|
Rotation = s.QuatDir;
|
|
}
|
|
|
|
public override void Update(ContainerState s, StampedEvent ev) {
|
|
base.Update(s, ev);
|
|
if (CanDoGraphicalUpdate(s)) {
|
|
ppt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
|
|
Vector3 dpt = ppt - plp; // Delta 2D point
|
|
dpt.z = (float)((s.Time - ptime) * ChartPlayer.sv * tsv); // Delta Z
|
|
Quaternion rotq = Quaternion.Euler(s.Direction); // Rotation
|
|
var dwp = rotq * dpt; // Delta world point
|
|
var nl = length + dwp.magnitude; // New length
|
|
var tdist = s.Distance;
|
|
if (nl >= tdist) { // TODO Fix dist
|
|
s.Break();
|
|
return;
|
|
}
|
|
length = nl;
|
|
var wp = pwp + dwp; // World point
|
|
pwp = wp;
|
|
if (Parent != null) ppwp = Parent.Position;
|
|
plp += dpt;
|
|
|
|
ptime = s.Time;
|
|
Position = pwp + spos;
|
|
Rotation = s.QuatDir;
|
|
|
|
if (!RootTransform || s.CloneType == 3) return;
|
|
foreach (var i in sgos)
|
|
i.AppendPoint(Position, Rotation);
|
|
}
|
|
else UpdatePosition(s);
|
|
}
|
|
|
|
void UpdatePosition(ContainerState s) {
|
|
plp = s.ScreenPoint;
|
|
pwp = Vector3.zero;
|
|
ptime = s.Time;
|
|
length = 0;
|
|
Position = pwp + spos;
|
|
Rotation = s.QuatDir;
|
|
}
|
|
|
|
// TODO Fix anchor rotation
|
|
public override void Anchor() {
|
|
base.Anchor();
|
|
spos = ppt - Position;
|
|
if (ptime < cs.Time) { // Pre-graphical update ends before anchor, compensate from parent
|
|
var dspos = ppwp - (Parent != null ? Parent.Position : Vector3.zero);
|
|
spos += dspos;
|
|
Position -= dspos;
|
|
}
|
|
}
|
|
|
|
protected override void EndGraphicalUpdate(ContainerState s) {
|
|
base.EndGraphicalUpdate(s);
|
|
EndUpdatePosition(s);
|
|
var p = Position;
|
|
foreach (var i in sgos) {
|
|
i.AppendPoint(p, Rotation);
|
|
i.Seal();
|
|
}
|
|
sflag = false;
|
|
}
|
|
|
|
void EndUpdatePosition(ContainerState s) {
|
|
ppt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
|
|
Vector3 dpt = ppt - plp;
|
|
dpt.z = (float)((s.Time - ptime) * ChartPlayer.sv * tsv);
|
|
Quaternion rotq = Quaternion.Euler(s.Direction);
|
|
var dwp = rotq * dpt; // Delta world point
|
|
var nl = length + dwp.magnitude; // New length
|
|
var tdist = s.Distance;
|
|
if (nl >= tdist)
|
|
dwp *= (tdist - length) / (nl - length);
|
|
length = nl;
|
|
var wp = pwp + dwp; // World point
|
|
pwp = wp;
|
|
plp += dpt;
|
|
Position = pwp + spos;
|
|
Rotation = s.QuatDir;
|
|
}
|
|
}
|
|
}
|