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 trackPool = new List(); // Dictionary notePool = new Dictionary(); public TrackHandler(GroupHandler gh, Chart.Track _track) : base() { track = _track; this.gh = gh; } public override string TypeName { get { return "track"; } } /*EventPrehandler ph; List sevs = new List(); public void StartPrehandler(EventPrehandler parent) { List appevs = new List(); /*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(), 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 judgements = new List(); 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[] 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(); 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("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(); 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; } } }