245 lines
7.3 KiB
C#
245 lines
7.3 KiB
C#
using Cryville.Common.Math;
|
|
using Cryville.Crtr.Components;
|
|
using Cryville.Crtr.Event;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
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";
|
|
}
|
|
}
|
|
|
|
SectionalGameObject[] sgos;
|
|
|
|
public override void Init() {
|
|
base.Init();
|
|
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
|
}
|
|
protected override void PreAwake(ContainerState s) {
|
|
base.PreAwake(s);
|
|
#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 (s.CloneType == 2) {
|
|
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) {
|
|
Position = GetFramePoint(ts.Parent, ts.Track);
|
|
Rotation = GetFrameRotation(ts.Parent, ts.Track);
|
|
if (!gogroup) return;
|
|
Chart.Note tev = Event;
|
|
if (tev.IsLong) {
|
|
foreach (var i in sgos)
|
|
i.AppendPoint(Position, Rotation);
|
|
}
|
|
}
|
|
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 == 2 && gogroup) {
|
|
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>());*/
|
|
}
|
|
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) {
|
|
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;
|
|
}
|
|
}
|
|
}
|