141 lines
3.5 KiB
C#
141 lines
3.5 KiB
C#
using Cryville.Crtr.Components;
|
|
using Cryville.Crtr.Event;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Crtr {
|
|
class TrackHandler : ContainerHandler {
|
|
readonly GroupHandler gh;
|
|
readonly Chart.Track track;
|
|
|
|
public TrackHandler(Chart.Track ev, GroupHandler gh) : base() {
|
|
track = ev;
|
|
this.gh = gh;
|
|
}
|
|
|
|
public override string TypeName { get { return "track"; } }
|
|
|
|
public override void Init() {
|
|
base.Init();
|
|
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
|
}
|
|
SectionalGameObject[] sgos;
|
|
Vector3 bpos; Quaternion brot;
|
|
Vector3 spos;
|
|
public override void StartPhysicalUpdate(ContainerState s) {
|
|
base.StartPhysicalUpdate(s);
|
|
if (CanDoGraphicalUpdate(s)) {
|
|
TransformAwake(s);
|
|
}
|
|
}
|
|
public override void StartPreGraphicalUpdate(ContainerState s) {
|
|
base.StartPreGraphicalUpdate(s);
|
|
TransformAwake(s);
|
|
}
|
|
public override void StartGraphicalUpdate(ContainerState s) {
|
|
base.StartGraphicalUpdate(s);
|
|
if (gogroup) {
|
|
TransformAwake(s);
|
|
var p = GetCurrentWorldPoint();
|
|
foreach (var i in sgos) {
|
|
i.Reset();
|
|
i.AppendPoint(p, s.QuatDir);
|
|
}
|
|
}
|
|
}
|
|
void TransformAwake(ContainerState s) {
|
|
pwp = Vector3.zero;
|
|
cpt = s.ScreenPoint;
|
|
ptime = s.Time;
|
|
if (s.CloneType == 3) {
|
|
spos = Vector3.zero;
|
|
bpos = cpt;
|
|
brot = Quaternion.Euler(s.Direction);
|
|
}
|
|
}
|
|
|
|
Vector3 cpt; // Current point
|
|
Vector3 ppt = Vector3.zero; // Previous point
|
|
Vector3 pwp = Vector3.zero; // Previous world point
|
|
double ptime; // Previous time
|
|
float length;
|
|
|
|
public override void Update(ContainerState s, StampedEvent ev) {
|
|
base.Update(s, ev);
|
|
if (CanDoGraphicalUpdate(s)) {
|
|
var tpt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
|
|
Vector3 dpt = (Vector3)tpt - ppt; // 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) {
|
|
s.Break();
|
|
return;
|
|
}
|
|
length = nl;
|
|
var wp = pwp + dwp; // World point
|
|
pwp = wp;
|
|
ppt += dpt;
|
|
|
|
ptime = s.Time;
|
|
|
|
if (!gogroup || s.CloneType == 3) return;
|
|
var p = GetCurrentWorldPoint();
|
|
foreach (var i in sgos)
|
|
i.AppendPoint(p, s.QuatDir);
|
|
}
|
|
else UpdatePosition(s);
|
|
}
|
|
|
|
void UpdatePosition(ContainerState s) {
|
|
cpt = s.ScreenPoint;
|
|
ppt = cpt;
|
|
pwp = Vector3.zero;
|
|
ptime = s.Time;
|
|
length = 0;
|
|
// Logger.LogFormat("main", 0, "Debug", "SV: {0}", cs.GetRawValue<Vec1m>("svm").Value);
|
|
}
|
|
|
|
// TODO Fix anchor rotation
|
|
public override void Anchor() {
|
|
base.Anchor();
|
|
spos = bpos - GetCurrentWorldPoint();
|
|
}
|
|
|
|
public override void EndGraphicalUpdate(ContainerState s) {
|
|
base.EndGraphicalUpdate(s);
|
|
EndUpdatePosition(s);
|
|
var p = GetCurrentWorldPoint();
|
|
foreach (var i in sgos) {
|
|
i.AppendPoint(p, s.QuatDir);
|
|
i.Seal();
|
|
}
|
|
}
|
|
|
|
void EndUpdatePosition(ContainerState s) {
|
|
var tpt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
|
|
Vector3 dpt = (Vector3)tpt - ppt;
|
|
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;
|
|
ppt += dpt;
|
|
}
|
|
|
|
public Vector3 GetCurrentWorldPoint() {
|
|
return pwp + cpt + spos;
|
|
}
|
|
}
|
|
}
|