|
|
c3ebff |
using System;
|
|
|
c3ebff |
using System.Collections.Generic;
|
|
|
c3ebff |
|
|
|
c3ebff |
namespace Assistance {
|
|
|
c3ebff |
public class InputModifierTangents: InputManager.Modifier {
|
|
|
702257 |
public struct Tangent {
|
|
|
702257 |
public Point position;
|
|
|
702257 |
public double pressure;
|
|
|
702257 |
public Point tilt;
|
|
|
702257 |
|
|
|
702257 |
public Tangent(
|
|
|
702257 |
Point position,
|
|
|
702257 |
double pressure = 0.0,
|
|
|
702257 |
Point tilt = new Point() )
|
|
|
702257 |
{
|
|
|
702257 |
this.position = position;
|
|
|
702257 |
this.pressure = pressure;
|
|
|
702257 |
this.tilt = tilt;
|
|
|
702257 |
}
|
|
|
702257 |
}
|
|
|
702257 |
|
|
|
c3ebff |
public class Modifier: Track.Modifier {
|
|
|
589f9a |
public Modifier(Track.Handler handler):
|
|
|
c3ebff |
base(handler) { }
|
|
|
c3ebff |
|
|
|
c3ebff |
public InputManager.KeyPoint.Holder holder = null;
|
|
|
702257 |
public readonly List<tangent> tangents = new List<tangent>();</tangent></tangent>
|
|
|
c3ebff |
|
|
|
702257 |
public override Track.Point calcPoint(double originalIndex) {
|
|
|
c3ebff |
double frac;
|
|
|
c3ebff |
int i0 = original.floorIndex(originalIndex, out frac);
|
|
|
c3ebff |
int i1 = original.ceilIndex(originalIndex);
|
|
|
702257 |
Track.Point p = i0 < 0 ? new Track.Point()
|
|
|
702257 |
: interpolateSpline(
|
|
|
72d2fd |
original[i0],
|
|
|
72d2fd |
original[i1],
|
|
|
72d2fd |
i0 < tangents.Count ? tangents[i0] : new Tangent(),
|
|
|
72d2fd |
i1 < tangents.Count ? tangents[i1] : new Tangent(),
|
|
|
702257 |
frac );
|
|
|
7bbf70 |
p.originalIndex = originalIndex;
|
|
|
7bbf70 |
return p;
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
|
|
|
702257 |
public static Track.Point interpolateSpline(Track.Point p0, Track.Point p1, Tangent t0, Tangent t1, double l) {
|
|
|
702257 |
if (l <= Geometry.precision) return p0;
|
|
|
702257 |
if (l >= 1.0 - Geometry.precision) return p1;
|
|
|
702257 |
return new Track.Point(
|
|
|
702257 |
Geometry.interpolationSpline(p0.position, p1.position, t0.position, t1.position, l),
|
|
|
702257 |
Geometry.interpolationSpline(p0.pressure, p1.pressure, t0.pressure, t1.pressure, l),
|
|
|
702257 |
Geometry.interpolationSpline(p0.tilt, p1.tilt, t0.tilt, t1.tilt, l),
|
|
|
702257 |
Geometry.interpolationLinear(p0.originalIndex, p1.originalIndex, l),
|
|
|
702257 |
Geometry.interpolationLinear(p0.time, p1.time, l),
|
|
|
702257 |
Geometry.interpolationLinear(p0.length, p1.length, l) );
|
|
|
702257 |
}
|
|
|
702257 |
|
|
|
589f9a |
public override void modify(Track track, InputManager.KeyPoint keyPoint, List<track> outTracks) {
|
|
|
c3ebff |
if (track.handler == null) {
|
|
|
c3ebff |
track.handler = new Track.Handler(this, track);
|
|
|
c3ebff |
track.handler.tracks.Add(new Track( new Modifier(track.handler) ));
|
|
|
c3ebff |
}
|
|
|
c3ebff |
|
|
|
c3ebff |
Track subTrack = track.handler.tracks[0];
|
|
|
c3ebff |
Modifier modifier = (Modifier)subTrack.modifier;
|
|
|
c3ebff |
outTracks.Add(subTrack);
|
|
|
c3ebff |
|
|
|
72d2fd |
if ( !track.wasChanged
|
|
|
72d2fd |
&& track.count == subTrack.count
|
|
|
72d2fd |
&& track.count == modifier.tangents.Count )
|
|
|
c3ebff |
return;
|
|
|
c3ebff |
|
|
|
72d2fd |
if (!track.wasChanged && subTrack.count == track.count - 1) {
|
|
|
c3ebff |
// add temporary point
|
|
|
702257 |
modifier.tangents.Add(new Tangent());
|
|
|
72d2fd |
subTrack.add(track.getLast());
|
|
|
c3ebff |
} else {
|
|
|
c3ebff |
// apply permanent changes
|
|
|
c3ebff |
|
|
|
c3ebff |
// remove points
|
|
|
72d2fd |
int start = track.count - track.pointsAdded;
|
|
|
c3ebff |
if (start < 0) start = 0;
|
|
|
c3ebff |
if (start > 1) --start;
|
|
|
72d2fd |
subTrack.truncate(start);
|
|
|
0f2bf8 |
if (start < modifier.tangents.Count)
|
|
|
c3ebff |
modifier.tangents.RemoveRange(start, modifier.tangents.Count - start);
|
|
|
c3ebff |
|
|
|
c3ebff |
// add first point
|
|
|
c3ebff |
int index = start;
|
|
|
c3ebff |
if (index == 0) {
|
|
|
702257 |
modifier.tangents.Add(new Tangent());
|
|
|
72d2fd |
subTrack.add(track.getLast());
|
|
|
c3ebff |
++index;
|
|
|
c3ebff |
}
|
|
|
c3ebff |
|
|
|
c3ebff |
// add points with tangents
|
|
|
72d2fd |
if (track.count > 2) {
|
|
|
72d2fd |
while(index < track.count) {
|
|
|
72d2fd |
Track.Point p0 = track[index-1];
|
|
|
72d2fd |
Track.Point p1 = track[index];
|
|
|
72d2fd |
Track.Point p2 = track[index+1];
|
|
|
702257 |
double dt = p2.time - p0.time;
|
|
|
702257 |
double k = dt > Geometry.precision ? (p1.time - p0.time)/dt : 0.0;
|
|
|
702257 |
Tangent tangent = new Tangent(
|
|
|
702257 |
(p2.position - p0.position)*k,
|
|
|
702257 |
(p2.pressure - p0.pressure)*k,
|
|
|
702257 |
(p2.tilt - p0.tilt)*k );
|
|
|
702257 |
modifier.tangents.Add(tangent);
|
|
|
72d2fd |
subTrack.add(p1);
|
|
|
c3ebff |
++index;
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
|
|
|
72d2fd |
track.resetCounters();
|
|
|
c3ebff |
|
|
|
c3ebff |
// release previous key point
|
|
|
589f9a |
if (modifier.holder != null) {
|
|
|
1d3aae |
modifier.holder.Dispose();
|
|
|
1d3aae |
modifier.holder = null;
|
|
|
1d3aae |
}
|
|
|
c3ebff |
|
|
|
589f9a |
if (track.isFinished()) {
|
|
|
c3ebff |
// finish
|
|
|
702257 |
modifier.tangents.Add(new Tangent());
|
|
|
72d2fd |
subTrack.add(track.getLast());
|
|
|
c3ebff |
} else {
|
|
|
c3ebff |
// save key point
|
|
|
c3ebff |
modifier.holder = keyPoint.hold();
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
}
|
|
|
c3ebff |
|