Code structure cleanup.

This commit is contained in:
2023-08-24 15:47:34 +08:00
parent e40c98ae1b
commit 1f58390298
137 changed files with 439 additions and 362 deletions

View File

@@ -0,0 +1,52 @@
using Cryville.Audio.Source;
using System.Collections.Generic;
using System.IO;
namespace Cryville.Crtr.Event {
public class ChartHandler : TransformHandler {
protected override TransformHandler Parent { get { return null; } }
readonly Chart chart;
readonly List<LibavFileAudioSource> sounds = new List<LibavFileAudioSource>();
public ChartHandler(Chart _chart) {
chart = _chart;
}
public override string TypeName { get { return "chart"; } }
public override void PreInit() {
base.PreInit();
}
public override void Update(ContainerState s, StampedEvent ev) {
base.Update(s, ev);
if (s.CloneType == 16) {
if (ev == null) { }
else if (ev.Unstamped == null) { }
else if (ev.Unstamped is Chart.Sound) {
Chart.Sound tev = (Chart.Sound)ev.Unstamped;
var dir = new DirectoryInfo(Game.GameDataPath + "/songs/" + tev.id);
var files = dir.GetFiles();
var source = new LibavFileAudioSource(files[0].FullName);
source.SelectStream();
sounds.Add(source);
Game.AudioSession.Sequence(
s.Time - tev.offset + ChartPlayer.soundOffset,
source
);
}
}
}
public override void EndLogicalUpdate(ContainerState s) {
base.EndLogicalUpdate(s);
// TODO End of chart
}
public override void DisposeAll() {
base.DisposeAll();
foreach (var s in sounds) s.Dispose();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 59e25dacd9b4d1f45b1da3a381187560
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +1,9 @@
using Cryville.Common;
using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using Cryville.Crtr.Components;
using Cryville.Crtr.Ruleset;
using Cryville.Crtr.Skin;
using Cryville.Crtr.Skin.Components;
using System;
using System.Collections.Generic;
using System.Globalization;

View File

@@ -2,6 +2,8 @@ using Cryville.Common;
using Cryville.Common.Buffers;
using Cryville.Common.Collections.Specialized;
using Cryville.Common.Pdt;
using Cryville.Crtr.Ruleset;
using Cryville.Crtr.Skin;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

View File

@@ -1,3 +1,5 @@
using Cryville.Crtr.Ruleset;
using Cryville.Crtr.Skin;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

View File

@@ -0,0 +1,52 @@
using Cryville.Common.Math;
using System;
using UnityEngine;
namespace Cryville.Crtr.Event {
public class GroupHandler : TransformHandler {
protected override TransformHandler Parent { get { return _ch; } }
public ChartHandler _ch;
ColumnVector<float> coeffs;
SquareMatrix matFrame;
ContainerState[] tracks;
public GroupHandler(Chart.Group tg, ChartHandler ch) : base() {
_ch = ch;
}
public override string TypeName { get { return "group"; } }
public override void PreInit() {
base.PreInit();
tracks = cs.TypedChildren[typeof(Chart.Track)].ToArray();
int numTracks = tracks.Length;
coeffs = new ColumnVector<float>(numTracks);
matFrame = SquareMatrix.WithPolynomialCoefficients(numTracks);
frame1 = new ColumnVector<Vector3>(numTracks);
frame2 = new ColumnVector<Vector3>(numTracks);
}
ColumnVector<Vector3> frame1;
ColumnVector<Vector3> frame2;
public Vector3 GetCurrentFrame(Func<ContainerState, Vector3> func, float track) {
for (int i = 0; i < tracks.Length; i++)
frame1[i] = func(tracks[i]);
matFrame.Eliminate(frame1, frame2, Vector3Operator.Instance);
ColumnVector<float>.FillWithPolynomialCoefficients(coeffs, track);
return frame2.Dot(coeffs, Vector3Operator.Instance);
}
}
class Vector3Operator : IVectorOperator<Vector3> {
public static Vector3Operator Instance = new Vector3Operator();
public Vector3 Add(Vector3 lhs, Vector3 rhs) {
return lhs + rhs;
}
public Vector3 ScalarMultiply(float lhs, Vector3 rhs) {
return lhs * rhs;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a254d6c958ea6c5409991bde44e67635
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,155 @@
using Cryville.Common;
using Cryville.Crtr.Ruleset;
using Cryville.Crtr.Skin.Components;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Cryville.Crtr.Event {
public class NoteHandler : ContainerHandler {
readonly GroupHandler gh;
readonly Chart.Note _note;
public NoteHandler(Chart.Note ev, GroupHandler gh) : base() {
_note = ev;
this.gh = gh;
}
public override string TypeName { get { return "note"; } }
SectionalGameObject[] sgos;
readonly Dictionary<Chart.Judge, JudgeState> judges = new Dictionary<Chart.Judge, JudgeState>();
class JudgeState {
static readonly int _var_judge_result = IdentifierManager.Shared.Request("judge_result");
static readonly int _var_judge_time_absolute = IdentifierManager.Shared.Request("judge_time_absolute");
static readonly int _var_judge_time_relative = IdentifierManager.Shared.Request("judge_time_relative");
public Anchor StaticAnchor { get; private set; }
readonly PropStores.Float _jtabsst = new PropStores.Float();
readonly PropStores.Float _jtrelst = new PropStores.Float();
readonly PropStores.Identifier _resultst = new PropStores.Identifier();
public JudgeState(NoteHandler handler, int name) {
StaticAnchor = handler.RegisterAnchor(handler.judge.judgeMap[name], false, 3);
}
public void MarkJudged(float abs, float rel, int result) {
_jtabsst.Value = abs;
_jtrelst.Value = rel;
_resultst.Value = result;
}
public void InitPropSrcs() {
StaticAnchor.PropSrcs.Add(_var_judge_result, _resultst.Source);
StaticAnchor.PropSrcs.Add(_var_judge_time_absolute, _jtabsst.Source);
StaticAnchor.PropSrcs.Add(_var_judge_time_relative, _jtrelst.Source);
}
}
public override void PreInit() {
base.PreInit();
foreach (var j in _note.judges) {
judges.Add(j, new JudgeState(this, j.Id.Key));
}
}
public override void Init() {
base.Init();
sgos = RootTransform.GetComponentsInChildren<SectionalGameObject>();
foreach (var judge in judges) judge.Value.InitPropSrcs();
}
public override void StartPhysicalUpdate(ContainerState s) {
base.StartPhysicalUpdate(s);
if (s.CloneType == 2) {
TransformAwake(s);
}
}
protected override void StartGraphicalUpdate(ContainerState s) {
base.StartGraphicalUpdate(s);
TransformAwake(s);
if (RootTransform) {
if (_note.IsLong) {
foreach (var i in sgos) {
i.Reset();
i.AppendPoint(Position, Rotation);
}
}
else {
#if UNITY_5_6_OR_NEWER
RootTransform.SetPositionAndRotation(Position, Rotation);
#else
RootTransform.position = Position;
RootTransform.rotation = Rotation;
#endif
}
}
}
void TransformAwake(ContainerState s) {
Position = GetFramePoint(s.Parent, s.Track);
Rotation = GetFrameRotation(s.Parent, s.Track);
}
public override void Update(ContainerState s, StampedEvent ev) {
if (s.CloneType <= 2) {
Position = GetFramePoint(s.Parent, s.Track);
Rotation = GetFrameRotation(s.Parent, s.Track);
if (s.CloneType == 2 && RootTransform && _note.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.Judge) {
judge._etor.ContextEvent = ev.Unstamped;
judge._etor.ContextState = s;
judge.Prepare(ev, this);
judge._etor.ContextState = null;
judge._etor.ContextEvent = null;
}
}
if (s.CloneType == 2 && ev != null && ev.Unstamped is Chart.Judge) {
var anchor = judges[(Chart.Judge)ev.Unstamped].StaticAnchor;
#if UNITY_5_6_OR_NEWER
anchor.Transform.SetPositionAndRotation(Position, Rotation);
#else
anchor.Transform.position = Position;
anchor.Transform.rotation = Rotation;
#endif
OpenAnchor(anchor);
base.Update(s, ev);
CloseAnchor();
}
else base.Update(s, ev);
}
protected override void EndGraphicalUpdate(ContainerState s) {
if (RootTransform) {
foreach (var i in sgos) i.Seal();
}
base.EndGraphicalUpdate(s);
}
Vector3 GetFramePoint(ContainerState state, float track) {
return GetFrame(state, track, th => th.Handler.Position);
}
Quaternion GetFrameRotation(ContainerState state, float track) {
var r = GetFrame(state, track, th => th.Handler.Rotation * Vector3.forward);
return Quaternion.LookRotation(r, state.Normal);
}
Vector3 GetFrame(ContainerState state, float track, Func<ContainerState, Vector3> func) {
// TODO
int id = Mathf.FloorToInt(track);
if (track == id) {
var ts0 = state.GetChild(id, typeof(Chart.Track));
var p1 = func(ts0);
return p1;
}
return gh.GetCurrentFrame(func, track);
}
internal void ReportJudge(JudgeEvent ev, float time, Identifier result) {
JudgeState state;
if (!judges.TryGetValue(ev.BaseEvent, out state)) return;
state.MarkJudged(time, (float)(ev.StartTime - time), result.Key);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ffea8276b5ce64d4392c75332b223f87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using Cryville.Common.Collections.Specialized;
using System;
namespace Cryville.Crtr.Event {
public class RealtimeMotionValue {
Type _type;
public Vector AbsoluteValue;
public Vector RelativeValue;
public IntKeyedDictionary<MotionNode> RelativeNodes;
internal byte CloneTypeFlag;
public RealtimeMotionValue Init(Vector init) {
_type = init.GetType();
RelativeNodes = new IntKeyedDictionary<MotionNode>();
AbsoluteValue = init;
RelativeValue = (Vector)Activator.CreateInstance(_type);
return this;
}
public RealtimeMotionValue Clone() {
return new RealtimeMotionValue() {
_type = _type,
AbsoluteValue = AbsoluteValue.Clone(),
RelativeValue = RelativeValue.Clone(),
RelativeNodes = RelativeNodes,
};
}
public void CopyTo(RealtimeMotionValue dest, bool cloneNodes) {
AbsoluteValue.CopyTo(dest.AbsoluteValue);
RelativeValue.CopyTo(dest.RelativeValue);
if (cloneNodes) {
dest.ReturnAllRelativeNodes();
foreach (var node in RelativeNodes) {
var dnode = MotionNodePool.Shared.Rent(_type);
node.Value.CopyTo(dnode);
dest.RelativeNodes.Add(node.Key, dnode);
}
}
else dest.RelativeNodes = RelativeNodes;
}
public void ReturnAllRelativeNodes() {
foreach (var node in RelativeNodes) {
MotionNodePool.Shared.Return(_type, node.Value);
}
RelativeNodes.Clear();
}
public MotionNode GetRelativeNode(short id) {
MotionNode result;
RelativeNodes.TryGetValue(id, out result);
return result;
}
public void SetRelativeNode(MotionNode node) {
MotionNode cnode;
if (!RelativeNodes.TryGetValue(node.Id, out cnode)) {
cnode = MotionNodePool.Shared.Rent(_type);
cnode.Id = node.Id;
RelativeNodes.Add(node.Id, cnode);
}
if (node.Time != null) node.Time.CopyTo(cnode.Time);
if (node.EndTime != null) node.EndTime.CopyTo(cnode.EndTime);
if (node.Value != null) node.Value.CopyTo(cnode.Value);
}
/// <summary>
/// Computes the motion value.
/// </summary>
/// <typeparam name="T">The vector type of the value.</typeparam>
/// <param name="result">The result.</param>
public void Compute<T>(ref T result) where T : Vector {
AbsoluteValue.CopyTo(result);
result.ApplyFrom(RelativeValue);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f86bb688b0e51b84cbea3253abbe73e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using CAnchor = Cryville.Crtr.Anchor;
namespace Cryville.Crtr.Event {
public class StampedEvent : IComparable<StampedEvent> {
public double Time;
public ChartEvent Unstamped;
public EventContainer Container;
public StampedEvent Origin;
public List<StampedEvent> Coevents;
public double Duration {
get {
if (ReleaseEvent != null)
return ReleaseEvent.Time - Time;
else return 0;
}
}
public virtual int Priority {
get {
if (Unstamped != null) return Unstamped.Priority;
if (Origin != null) return Origin.Priority + 1;
throw new NotImplementedException();
}
}
public class Temporary : StampedEvent, IComparable<Temporary> {
public virtual bool CanDiscard { get; set; }
public int CompareTo(Temporary other) {
return base.CompareTo(other);
}
}
public class Anchor : Temporary {
public CAnchor Target;
int m_priority;
public bool Forced { get; set; }
public override bool CanDiscard { get { return !Forced; } }
public override int Priority { get { return m_priority; } }
public void SetPriority(int value) { m_priority = value + Container.Priority - 0x800; }
}
public class ClipBehind : StampedEvent {
public override int Priority {
get { return Origin.Priority - 0x8000; }
}
}
public class ClipAhead : StampedEvent {
public override int Priority {
get { return 0x7fff - Origin.Priority; }
}
}
public class RelativeMotion : Temporary {
public int Name { get; set; }
public MotionNode Node { get; set; }
public override bool CanDiscard { get { return false; } }
public override int Priority { get { return -2; } }
}
public StampedEvent ReleaseEvent { get; set; }
public override string ToString() {
if (Unstamped == null)
return string.Format("stmpev at {0} {1}", Time, this.GetType().Name);
return string.Format("stmpev at {0} {1}", Time, Unstamped.GetType().Name);
}
public int CompareTo(StampedEvent other) {
int u = this.Time.CompareTo(other.Time);
if (u != 0) return u;
u = this.Priority.CompareTo(other.Priority);
if (u != 0) return u;
u = this.Duration.CompareTo(other.Duration);
if (u != 0) return u;
u = CompareExtra(other);
if (u != 0) return u;
return GetHashCode().CompareTo(other.GetHashCode());
}
protected virtual int CompareExtra(StampedEvent other) {
return 0;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 767c16f09c4593940aa934d0ca6de4ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,139 @@
using System.Collections.Generic;
namespace Cryville.Crtr.Event {
/// <summary>
/// A time-forward handler of a sequence of events.
/// </summary>
/// <typeparam name="T">The event type.</typeparam>
public abstract class StateBase<T> {
/// <summary>
/// The current time of the state in seconds.
/// </summary>
public double Time { get; protected set; }
/// <summary>
/// The index of the event to be handled next.
/// </summary>
public int EventId { get; protected set; }
/// <summary>
/// The event count.
/// </summary>
public int EventCount { get { return Events.Count; } }
/// <summary>
/// The event list.
/// </summary>
protected readonly List<T> Events;
bool breakflag = false;
/// <summary>
/// Creates an instance of the <see cref="StateBase{T}" /> class.
/// </summary>
/// <param name="evs">The event list.</param>
public StateBase(List<T> evs) {
Events = evs;
EventId = 0;
Time = 0;
}
/// <summary>
/// Creates a copy of the current state.
/// </summary>
/// <returns>A copy of the current state.</returns>
/// <remarks>
/// <para><see cref="Events" /> is shared across copies.</para>
/// </remarks>
public virtual StateBase<T> Clone() {
return (StateBase<T>)MemberwiseClone();
}
/// <summary>
/// Copies the state to another existing state.
/// </summary>
/// <param name="dest">The state to be overridden.</param>
public virtual void CopyTo(StateBase<T> dest) {
dest.Time = Time;
dest.EventId = EventId;
dest.breakflag = breakflag;
}
/// <summary>
/// Interrupts the forward process.
/// </summary>
public virtual void Break() {
breakflag = true;
}
/// <summary>
/// Walks through all the remaining events.
/// </summary>
public void Forward() {
ForwardToTime(double.PositiveInfinity);
}
/// <summary>
/// Forwards to the next event.
/// </summary>
public void ForwardOnce() {
ForwardOnceToTime(double.PositiveInfinity);
}
/// <summary>
/// Forwards the time by the specified span and walks through all the encountered events.
/// </summary>
/// <param name="time">The span in seconds.</param>
public void ForwardByTime(double time) {
ForwardToTime(Time + time);
}
/// <summary>
/// Forwards the time by the specified span but walks through at most one event.
/// </summary>
/// <param name="time">The span in seconds.</param>
public void ForwardOnceByTime(double time) {
ForwardOnceToTime(Time + time);
}
/// <summary>
/// Forwards the time to the specified time and walks through all the encountered events.
/// </summary>
/// <param name="toTime">The time in seconds.</param>
public void ForwardToTime(double toTime) {
breakflag = false;
ForwardOnceToTime(Time);
while (Time < toTime) {
ForwardOnceToTime(toTime);
if (breakflag) break;
}
}
/// <summary>
/// Forwards the time by the specified span and walks through all the encountered events, with a specified step.
/// </summary>
/// <param name="time">The span in seconds.</param>
/// <param name="step">The step in seconds.</param>
public void ForwardStepByTime(double time, double step) {
ForwardStepToTime(Time + time, step);
}
/// <summary>
/// Forwards the time to the specified time and walks through all the encountered events, with a specified step.
/// </summary>
/// <param name="toTime">The time in seconds.</param>
/// <param name="step">The step in seconds.</param>
public void ForwardStepToTime(double toTime, double step) {
breakflag = false;
ForwardOnceToTime(Time);
while (Time < toTime) {
double next = Time + step;
ForwardOnceToTime(next < toTime ? next : toTime);
if (breakflag) break;
}
}
/// <summary>
/// Forwards the time to the specified time but walks through at most one event.
/// </summary>
/// <param name="toTime">The time in seconds.</param>
public abstract void ForwardOnceToTime(double toTime);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ea84a1810568034e96c8d3837b3ca2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
namespace Cryville.Crtr.Event {
public class TrackHandler : TransformHandler {
protected override TransformHandler Parent { get { return _gh; } }
readonly GroupHandler _gh;
readonly Chart.Track _track;
public TrackHandler(Chart.Track ev, GroupHandler gh) : base() {
_track = ev;
_gh = gh;
}
public override string TypeName { get { return "track"; } }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9a4d5fe2d0dc5d4d869d91670cc1aab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,143 @@
using Cryville.Crtr.Skin.Components;
using System.Linq;
using UnityEngine;
namespace Cryville.Crtr.Event {
public abstract class TransformHandler : ContainerHandler {
protected abstract TransformHandler Parent { get; }
public override void Init() {
base.Init();
sgos = Components.Where(c => c is SectionalGameObject).Cast<SectionalGameObject>().ToArray();
}
SectionalGameObject[] sgos;
bool sflag; // Did pre-graphical update
Vector3 spos; // Start position offset
Vector3 ppt = Vector3.zero; // Previous screen point
Vector3 plp = Vector3.zero; // Previous local point
Vector3 pwp = Vector3.zero; // Previous world point
Vector3 ppwp = Vector3.zero; // Previous parent world point
double ptime; // Previous time
float length;
public override void StartPhysicalUpdate(ContainerState s) {
base.StartPhysicalUpdate(s);
if (CanDoGraphicalUpdate(s)) {
TransformAwake(s);
}
}
protected override void StartPreGraphicalUpdate(ContainerState s) {
base.StartPreGraphicalUpdate(s);
spos = Vector3.zero;
sflag = true;
pwp = Parent != null ? Parent.Position : Vector3.zero;
TransformAwake(s);
}
protected override void StartGraphicalUpdate(ContainerState s) {
base.StartGraphicalUpdate(s);
if (RootTransform) {
if (!sflag && Parent != null) { // No pre-graphical update; inherit from parent
spos = Parent.Position + (Vector3)s.ScreenPoint - (Vector3)s.Parent.ScreenPoint;
}
TransformAwake(s);
var p = Position;
foreach (var i in sgos) {
i.Reset();
i.AppendPoint(p, Rotation);
}
}
}
void TransformAwake(ContainerState s) {
plp = s.ScreenPoint;
pwp = Vector3.zero;
ptime = s.Time;
Position = spos;
Rotation = s.QuatDir;
}
public override void Update(ContainerState s, StampedEvent ev) {
base.Update(s, ev);
if (CanDoGraphicalUpdate(s)) {
ppt = s.ScreenPoint;
var tsv = s.ScrollVelocity;
Vector3 dpt = ppt - plp; // 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) { // TODO Fix dist
s.Break();
return;
}
length = nl;
var wp = pwp + dwp; // World point
pwp = wp;
if (Parent != null) ppwp = Parent.Position;
plp += dpt;
ptime = s.Time;
Position = pwp + spos;
Rotation = s.QuatDir;
if (!RootTransform || s.CloneType == 3) return;
foreach (var i in sgos)
i.AppendPoint(Position, Rotation);
}
else UpdatePosition(s);
}
void UpdatePosition(ContainerState s) {
plp = s.ScreenPoint;
pwp = Vector3.zero;
ptime = s.Time;
length = 0;
Position = pwp + spos;
Rotation = s.QuatDir;
}
// TODO Fix anchor rotation
public override void Anchor() {
base.Anchor();
spos = ppt - Position;
if (ptime < cs.Time) { // Pre-graphical update ends before anchor, compensate from parent
var dspos = ppwp - (Parent != null ? Parent.Position : Vector3.zero);
spos += dspos;
Position -= dspos;
}
}
protected override void EndGraphicalUpdate(ContainerState s) {
base.EndGraphicalUpdate(s);
EndUpdatePosition(s);
var p = Position;
foreach (var i in sgos) {
i.AppendPoint(p, Rotation);
i.Seal();
}
sflag = false;
}
void EndUpdatePosition(ContainerState s) {
ppt = s.ScreenPoint;
var tsv = s.ScrollVelocity;
Vector3 dpt = ppt - plp;
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;
plp += dpt;
Position = pwp + spos;
Rotation = s.QuatDir;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b6f66c022b25fe344908a0e34ef40615
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: