Add project files.
This commit is contained in:
297
Assets/Cryville/Crtr/NoteHandler.cs
Normal file
297
Assets/Cryville/Crtr/NoteHandler.cs
Normal file
@@ -0,0 +1,297 @@
|
||||
using Cryville.Common.Math;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
class NoteHandler : ContainerHandler {
|
||||
readonly GroupHandler gh;
|
||||
public readonly Chart.Note Event;
|
||||
readonly Judge judge;
|
||||
public NoteHandler(GroupHandler gh, Chart.Note ev, Judge j) : base() {
|
||||
this.gh = gh;
|
||||
Event = ev;
|
||||
judge = j;
|
||||
}
|
||||
|
||||
public override string TypeName {
|
||||
get {
|
||||
return "note";
|
||||
}
|
||||
}
|
||||
|
||||
/*public override void Dispose() {
|
||||
base.Dispose();
|
||||
for (int i = notePool.Count - 1; i >= 0; i--) {
|
||||
var t = notePool.ElementAt(i);
|
||||
GameObject.Destroy(t.Value);
|
||||
}
|
||||
}*/
|
||||
|
||||
//Dictionary<StampedEvent, GameObject> notePool = new Dictionary<StampedEvent, GameObject>();
|
||||
|
||||
// Trail trail;
|
||||
SectionalGameObject[] sgos;
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
||||
}
|
||||
protected override void PreAwake(ContainerState s) {
|
||||
base.PreAwake(s);
|
||||
/*var attev = StampedEvent.AttackEvent;
|
||||
if (attev != null) {
|
||||
GameObject headObj = null;
|
||||
bool pooledh = notePool.TryGetValue(attev, out headObj);
|
||||
if (pooledh)
|
||||
GameObject.Destroy(headObj);
|
||||
}*/
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
a_head.SetPositionAndRotation(Position = GetFramePoint(s.Parent, s.Track), Rotation = GetFrameRotation(s.Parent, s.Track));
|
||||
#else
|
||||
a_head.position = Position = GetFramePoint(s.Parent, s.Track);
|
||||
a_head.rotation = Rotation = GetFrameRotation(s.Parent, s.Track);
|
||||
#endif
|
||||
}
|
||||
protected override void Awake(ContainerState s) {
|
||||
base.Awake(s);
|
||||
if (!gogroup) return;
|
||||
Chart.Note tev = Event;
|
||||
if (tev.IsLong) {
|
||||
foreach (var i in sgos) {
|
||||
i.Reset();
|
||||
i.AppendPoint(Position, Rotation);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
gogroup.SetPositionAndRotation(Position, Rotation);
|
||||
#else
|
||||
gogroup.position = Position;
|
||||
gogroup.rotation = Rotation;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
readonly Dictionary<Chart.Motion, Vec1> phMotions = new Dictionary<Chart.Motion, Vec1>();
|
||||
bool invalidated = false;
|
||||
readonly List<StampedEvent.Judge> patchedJudgeEvents = new List<StampedEvent.Judge>();
|
||||
|
||||
public override void StartUpdate(ContainerState s) {
|
||||
base.StartUpdate(s);
|
||||
if (s.CloneType == 16 && Event.judge != null) {
|
||||
// var etor = new Evaluator();
|
||||
//CompiledRuleset.PatchJudge(Event, ChartPlayer.cruleset.primary_judges[Event.judge], s.Time, etor, patchedJudgeEvents, !Event.@long);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(ContainerState s, StampedEvent ev) {
|
||||
base.Update(s, ev);
|
||||
if (s.CloneType == 1) {
|
||||
Position = GetFramePoint(bs.Parent, bs.Track);
|
||||
Rotation = GetFrameRotation(bs.Parent, bs.Track);
|
||||
}
|
||||
else if (s.CloneType == 2) {
|
||||
/*for (int i = notePool.Count - 1; i >= 0; i--) {
|
||||
var t = notePool.ElementAt(i);
|
||||
var eev = t.Key;
|
||||
var rev = t.Key.ReleaseEvent;
|
||||
if (rev != null) {
|
||||
eev = rev;
|
||||
}
|
||||
if (eev.Time < cs.Time) {
|
||||
GameObject.Destroy(t.Value);
|
||||
notePool.Remove(t.Key);
|
||||
}
|
||||
}*/
|
||||
Position = GetFramePoint(ts.Parent, ts.Track);
|
||||
Rotation = GetFrameRotation(ts.Parent, ts.Track);
|
||||
if (!gogroup) return;
|
||||
// sgos = gogroup.GetComponentsInChildren<PolygonSGO>();
|
||||
Chart.Note tev = Event;
|
||||
if (tev.IsLong) {
|
||||
foreach (var i in sgos)
|
||||
i.AppendPoint(Position, Rotation);
|
||||
}
|
||||
/*else {
|
||||
gogroup.position = p;
|
||||
gogroup.rotation = Quaternion.Euler(ts.Direction);
|
||||
}*/
|
||||
}
|
||||
else if (s.CloneType == 16) {
|
||||
if (ev == null) { }
|
||||
else if (ev.Unstamped == null) { }
|
||||
else if (ev.Unstamped is Chart.Motion) {
|
||||
var tev = (Chart.Motion)ev.Unstamped;
|
||||
if (tev.Name.MainName != "judge") return;
|
||||
phMotions.Add(tev, (Vec1)s.GetRawValue<Vec1>(tev.Name).Clone());
|
||||
}
|
||||
else if (ev.Unstamped is InstantEvent) {
|
||||
var oev = ((InstantEvent)ev.Unstamped).Original;
|
||||
if (oev is Chart.Motion) {
|
||||
var tev = (Chart.Motion)oev;
|
||||
if (tev.Name.MainName != "judge") return;
|
||||
var v0 = phMotions[tev];
|
||||
var v1 = s.GetRawValue<Vec1>(tev.Name);
|
||||
// var etor = new Evaluator();
|
||||
for (var vi = Mathf.Ceil(v0.Value); vi < v1.Value; vi++) {
|
||||
var v = new Vec1(vi);
|
||||
var t = MotionLerper.Delerp(v, ev.Time, v1, ev.Origin.Time, v0, tev.transition, tev.rate);
|
||||
/*CompiledRuleset.PatchJudge(
|
||||
Event, ChartPlayer.cruleset.primary_judges[tev.Name.SubName],
|
||||
t, etor, patchedJudgeEvents
|
||||
);*/
|
||||
}
|
||||
phMotions.Remove(tev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExUpdate(ContainerState s, StampedEvent ev) {
|
||||
base.ExUpdate(s, ev);
|
||||
if (ev is StampedEvent.Judge) {
|
||||
var tev = (StampedEvent.Judge)ev;
|
||||
if (tev.TargetJudge != null && s.CloneType == 0 && !invalidated) {
|
||||
//judge.Issue(tev, this);
|
||||
}
|
||||
else if (tev.TargetJudge == null && s.CloneType == 17) {
|
||||
//judge.RecordPos(tev.StartEvent, GetFramePoint(s.Parent, s.Track));
|
||||
}
|
||||
else
|
||||
return;
|
||||
patchedJudgeEvents.Remove(tev);
|
||||
// Logger.Log("main", 0, "Judge", "ir {0}", patchedJudgeEvents.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MotionUpdate(byte ct, Chart.Motion ev) {
|
||||
base.MotionUpdate(ct, ev);
|
||||
if (ct == 0) {
|
||||
if (ev.Name.MainName == "judge") {
|
||||
if (invalidated) return;
|
||||
if (ev.Name.SubName == null)
|
||||
throw new InvalidOperationException();
|
||||
// judge.IssueImmediate(this, ev.Name.SubName, GetFramePoint(cs.Parent, cs.Track));
|
||||
}
|
||||
}
|
||||
else if (ct == 16) {
|
||||
/*var etor = new EvalImpl();
|
||||
if (ev.MotionName == "judge") {
|
||||
if (ev.MotionSubName == null)
|
||||
throw new InvalidOperationException();
|
||||
var l = new List<StampedEvent>();
|
||||
float t = ps.Time;
|
||||
CompiledRuleset.PatchJudge(
|
||||
Event, ChartPlayer.cruleset.primary_judges[ev.MotionSubName],
|
||||
t, etor, ref l
|
||||
);
|
||||
cs.Bus.IssueEventPatch(l);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public override void EndUpdate(ContainerState s) {
|
||||
if (s.CloneType == 0 || s.CloneType == 2) {
|
||||
if (!gogroup) goto return_ahead;
|
||||
// sgos = gogroup.GetComponentsInChildren<PolygonSGO>();
|
||||
foreach (var i in sgos) i.Seal();
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
a_tail.SetPositionAndRotation(GetFramePoint(ts.Parent, ts.Track), Quaternion.Euler(ts.Direction));
|
||||
#else
|
||||
a_tail.position = GetFramePoint(ts.Parent, ts.Track);
|
||||
a_tail.rotation = Quaternion.Euler(ts.Direction);
|
||||
#endif
|
||||
}
|
||||
else if (s.CloneType == 16) {
|
||||
if (Event.endjudge != null) {
|
||||
//var etor = new Evaluator();
|
||||
//CompiledRuleset.PatchJudge(Event, ChartPlayer.cruleset.primary_judges[Event.endjudge], ps.Time, etor, patchedJudgeEvents, true);
|
||||
}
|
||||
cs.Bus.IssuePatch(patchedJudgeEvents.Cast<StampedEvent>());
|
||||
}
|
||||
return_ahead:
|
||||
OpenAnchor("tail");
|
||||
base.EndUpdate(s);
|
||||
CloseAnchor("tail");
|
||||
}
|
||||
|
||||
Vector3 GetFramePoint(ContainerState state, float track) {
|
||||
return GetFrame(state, track, th => ((TrackHandler)th.Handler).GetCurrentWorldPoint());
|
||||
}
|
||||
|
||||
Quaternion GetFrameRotation(ContainerState state, float track) {
|
||||
var r = GetFrame(state, track, th => Quaternion.Euler(th.Direction) * Vector3.forward);
|
||||
return Quaternion.LookRotation(r, state.Normal);
|
||||
}
|
||||
|
||||
Vector3 GetFrame(ContainerState state, float track, Func<ContainerState, Vector3> func) {
|
||||
// TODO
|
||||
int id = Mathf.FloorToInt(track);
|
||||
var ts0 = state.GetChild(id, typeof(Chart.Track));
|
||||
var p1 = func(ts0);
|
||||
if (track == id)
|
||||
return p1;
|
||||
var ts1 = state.GetChild(id + 1, typeof(Chart.Track));
|
||||
var p2 = func(ts1);
|
||||
bool c0 = ts0.Corner;
|
||||
bool c1 = ts1.Corner;
|
||||
float t = track - id;
|
||||
float deltaz = p2.z - p1.z;
|
||||
float nt = 1 - t;
|
||||
if (c0 && c1)
|
||||
return (1 - t) * p1 + t * p2;
|
||||
else {
|
||||
var ctrl = new List<Vector3>(2);
|
||||
if (!c0) {
|
||||
var tp = ts0.GetControlPoint(true, deltaz);
|
||||
if (tp != Vector3.zero) ctrl.Add(tp);
|
||||
}
|
||||
if (!c1) {
|
||||
var tp = ts1.GetControlPoint(false, -deltaz);
|
||||
if (tp != Vector3.zero) ctrl.Add(tp);
|
||||
}
|
||||
if (ctrl.Count == 0) {
|
||||
/* // Early algorithm
|
||||
Vector3 m0, m1;
|
||||
bool flag0 = id == 0;
|
||||
bool flag1 = id == state.Children.Where(i => i.Key.Event is Chart.Track).Count() - 2;
|
||||
if (flag0 && flag1) // Only two tracks exist
|
||||
return (1 - t) * p1 + t * p2;
|
||||
else {
|
||||
Vector3 p0, p3;
|
||||
if (!flag1) p3 = ((TrackHandler)tl.ElementAt(id + 2).Value.Handler).GetCurrentWorldPoint();
|
||||
if (!flag0) p0 = ((TrackHandler)tl.ElementAt(id - 1).Value.Handler).GetCurrentWorldPoint();
|
||||
if (flag0) m0 = 2 * (p2-p1).normalized - (p3-p1).normalized;
|
||||
else m0 = 1f*((p1-p0).normalized + (p2-p1).normalized);
|
||||
if (flag1) m1 = 2 * (p2-p1).normalized - (p2-p0).normalized;
|
||||
else m1 = 1f*((p2-p1).normalized + (p3-p2).normalized);
|
||||
return t*t*(2*t-3)*(p1-p2)+p1 + t*(t-1)*((t-1)*m0+t*m1);
|
||||
}*/
|
||||
var frame = gh.GetCurrentFrame(func);
|
||||
return frame.Dot(
|
||||
ColumnVector<float>.WithPolynomialCoefficients(
|
||||
frame.Size, track
|
||||
),
|
||||
new Vector3Operator()
|
||||
);
|
||||
}
|
||||
else if (ctrl.Count == 1) {
|
||||
return nt * (nt * p1 + t * (ctrl[0] + p1)) + t * t * p2;
|
||||
}
|
||||
else {
|
||||
var t2 = t * t;
|
||||
return nt * (nt * (nt * p1 + t * (ctrl[0] + p1)) + t2 * (ctrl[1] + p1)) + t2 * t * p2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<StampedEvent.Judge> Invalidate() {
|
||||
invalidated = true;
|
||||
return patchedJudgeEvents;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user