Blame mono/Assistance/InputModifierTangents.cs

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