252 lines
7.0 KiB
C#
252 lines
7.0 KiB
C#
using Cryville.Crtr.Components;
|
|
using Cryville.Crtr.Event;
|
|
using UnityEngine;
|
|
using Logger = Cryville.Common.Logger;
|
|
|
|
namespace Cryville.Crtr {
|
|
class TrackHandler : ContainerHandler {
|
|
// private StampedState cs;
|
|
|
|
readonly GroupHandler gh;
|
|
readonly Chart.Track track;
|
|
// List<GameObject> trackPool = new List<GameObject>();
|
|
// Dictionary<StampedEvent, GameObject> notePool = new Dictionary<StampedEvent, GameObject>();
|
|
|
|
public TrackHandler(GroupHandler gh, Chart.Track _track) : base() {
|
|
track = _track;
|
|
this.gh = gh;
|
|
}
|
|
|
|
public override string TypeName {
|
|
get {
|
|
return "track";
|
|
}
|
|
}
|
|
|
|
/*EventPrehandler ph;
|
|
List<StampedEvent> sevs = new List<StampedEvent>();
|
|
public void StartPrehandler(EventPrehandler parent) {
|
|
List<Chart.Event> appevs = new List<Chart.Event>();
|
|
/*foreach (Chart.Note ev in track.notes) {
|
|
if (ev.duration > 0) {
|
|
for (float b = 0f; b < ev.duration; b += ev.judgeinterval) {
|
|
appevs.Add(new Chart.Track.InternalJudgement() { beat = ev.beat, BeatOffset = b, Parent = ev });
|
|
}
|
|
}
|
|
}
|
|
ph = new EventPrehandler(
|
|
parent.chart,
|
|
track.motions.Cast<Chart.Event>(),
|
|
parent
|
|
);
|
|
}
|
|
|
|
public void PrehandleToTime(float toTime) {
|
|
ph.ForwardToTime(toTime, ev => { });
|
|
/*phs.ForwardToTime(toTime, ev => {
|
|
if (ev is Chart.Note) {
|
|
var tev = (Chart.Note)ev;
|
|
sevs.Add(new StampedEvent.Judge() {
|
|
Time = phs.Time - judge * tev.tol,
|
|
EndTime = phs.Time + judge * tev.tol,
|
|
Event = tev,
|
|
Type = tev.wipe ? JudgementType.Held : JudgementType.Attack,
|
|
JudgeArea = new Area() {
|
|
Point1 = phs.Point,
|
|
Point2 = phs.Point + new Chart.Point(0f, 0.1f, 0f, 0.1f).ToRelative(hitRect),
|
|
Type = AreaType.Circle
|
|
}
|
|
});
|
|
}
|
|
else if (ev is Chart.InternalJudgement) {
|
|
var tev = (Chart.InternalJudgement)ev;
|
|
sevs.Add(new StampedEvent.Judge() {
|
|
Time = phs.Time - judge * tev.Parent.tol,
|
|
EndTime = phs.Time + judge * tev.Parent.tol,
|
|
Event = tev,
|
|
Type = JudgementType.Held,
|
|
JudgeArea = new Area() {
|
|
Point1 = phs.Point,
|
|
Point2 = phs.Point + new Chart.Point(0f, 0.1f, 0f, 0.1f).ToRelative(hitRect),
|
|
Type = AreaType.Circle
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
public void EndPrehandler(StampedState parent) {
|
|
sevs = ph.Result;
|
|
cs = new StampedState(gh.ch.chart, sevs, parent);
|
|
}*/
|
|
|
|
/*List<StampedEvent.Judge> judgements = new List<StampedEvent.Judge>();
|
|
public void SendInput(int id, TouchPhase phase, Vector2 jpos) {
|
|
for (int i = judgements.Count - 1; i >= 0; i--) {
|
|
if (judgements[i].JudgeArea.Contains(jpos)) {
|
|
if (phase == TouchPhase.Began && judgements[i].Type == JudgementType.Attack) {
|
|
gh.ch.ReportJudge(true);
|
|
judgements.RemoveAt(i);
|
|
}
|
|
else if ((phase == TouchPhase.Stationary || phase == TouchPhase.Moved) && judgements[i].Type == JudgementType.Held) {
|
|
gh.ch.ReportJudge(true);
|
|
judgements.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
public override void Init() {
|
|
base.Init();
|
|
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
|
}
|
|
SectionalGameObject[] sgos;
|
|
Vector3 bpos; Quaternion brot;
|
|
Vector3 spos;
|
|
protected override void PreAwake(ContainerState s) {
|
|
base.PreAwake(s);
|
|
pwp = Vector3.zero;
|
|
cpt = s.ScreenPoint;
|
|
ptime = s.Time;
|
|
if (s.CloneType == 2) {
|
|
a_head.position = GetCurrentWorldPoint();
|
|
a_head.rotation = Quaternion.Euler(s.Direction);
|
|
}
|
|
else if (s.CloneType == 3) {
|
|
spos = Vector3.zero;
|
|
bpos = cpt;
|
|
brot = Quaternion.Euler(s.Direction);
|
|
}
|
|
}
|
|
protected override void Awake(ContainerState s) {
|
|
base.Awake(s);
|
|
if (!gogroup) return;
|
|
var p = GetCurrentWorldPoint();
|
|
foreach (var i in sgos) {
|
|
i.Reset();
|
|
i.AppendPoint(p, s.QuatDir);
|
|
}
|
|
}
|
|
|
|
// readonly SectionalGameObject trackObj;
|
|
Vector3 cpt; // Current point
|
|
Vector3 ppt = Vector3.zero; // Previous point
|
|
Vector3 pwp = Vector3.zero; // Previous world point
|
|
float ptime; // Previous time
|
|
float length;
|
|
// readonly GameObject obj;
|
|
|
|
public override void Update(ContainerState s, StampedEvent ev) {
|
|
base.Update(s, ev);
|
|
if (s.CloneType == 2 || s.CloneType == 3) {
|
|
var tpt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
|
|
/*Vector3 p = (Vector3)tpt - cpt;
|
|
p.z = prevz + (ts.Time - prevtime) * Main.sv * tsv;
|
|
Quaternion rotq = Quaternion.Euler(ts.Direction);
|
|
var np = prevwp + rotq * (p - prevp);
|
|
prevp = p;
|
|
prevz = p.z;
|
|
p = np;
|
|
prevwp = p;
|
|
|
|
prevtime = ts.Time;*/
|
|
|
|
Vector3 dpt = (Vector3)tpt - ppt; // Delta 2D point
|
|
dpt.z = (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;
|
|
// sgos = gogroup.GetComponentsInChildren<PolygonSGO>();
|
|
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 EndUpdate(ContainerState s) {
|
|
OpenAnchor("tail");
|
|
base.EndUpdate(s);
|
|
CloseAnchor("tail");
|
|
if (s.CloneType == 0 || s.CloneType == 2) {
|
|
EndUpdatePosition(ts);
|
|
|
|
/*if (trackObj != null) {
|
|
trackObj.AppendPoint(p);
|
|
trackObj.Seal();
|
|
}*/
|
|
|
|
// sgos = gogroup.GetComponentsInChildren<PolygonSGO>();
|
|
var p = GetCurrentWorldPoint();
|
|
foreach (var i in sgos) {
|
|
i.AppendPoint(p, s.QuatDir);
|
|
i.Seal();
|
|
}
|
|
a_tail.position = GetCurrentWorldPoint();
|
|
a_tail.rotation = Quaternion.Euler(ts.Direction);
|
|
}
|
|
else if (s.CloneType == 3) EndUpdatePosition(ns);
|
|
else if (s.CloneType >= 16) EndUpdatePosition(ps);
|
|
}
|
|
|
|
void EndUpdatePosition(ContainerState s) {
|
|
var tpt = s.ScreenPoint;
|
|
var tsv = s.ScrollVelocity;
|
|
/*float endtime = ts.Time + Main.fogDist;
|
|
Vector3 ep;
|
|
ep = (Vector3)tpt - (Vector3)cpt;
|
|
ep.z = (endtime - cs.Time) * Main.sv * tsv;
|
|
|
|
Quaternion erotq = Quaternion.Euler(ts.Direction);
|
|
ep = pwp + erotq * (ep - ppt);*/
|
|
|
|
Vector3 dpt = (Vector3)tpt - ppt;
|
|
dpt.z = (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;
|
|
}
|
|
}
|
|
}
|