Blob Blame Raw
#include <tools/modifiers/modifiertangents.h>
//*****************************************************************************************
// TModifierTangents::Modifier implementation
//*****************************************************************************************
TTrackPoint
TModifierTangents::Modifier::calcPoint(double originalIndex) {
double frac;
int i0 = original.floorIndex(originalIndex, &frac);
int i1 = original.ceilIndex(originalIndex);
TTrackPoint p = i0 < 0 ? TTrackPoint()
: TTrack::interpolationSpline(
original[i0],
original[i1],
i0 < (int)tangents.size() ? tangents[i0] : TTrackTangent(),
i1 < (int)tangents.size() ? tangents[i1] : TTrackTangent(),
frac );
p.originalIndex = originalIndex;
return p;
}
//*****************************************************************************************
// TModifierTangents implementation
//*****************************************************************************************
void
TModifierTangents::modifyTrack(
const TTrack &track,
const TInputSavePoint::Holder &savePoint,
TTrackList &outTracks )
{
if (!track.handler) {
track.handler = new TTrackHandler(track);
track.handler->tracks.push_back(
new TTrack(
new Modifier(*track.handler) ));
}
if (track.handler->tracks.empty())
return;
TTrack &subTrack = *track.handler->tracks.front();
Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer());
if (!modifier)
return;
outTracks.push_back(track.handler->tracks.front());
if ( !track.changed()
&& track.size() == subTrack.size()
&& track.size() == (int)modifier->tangents.size() )
return;
if (!track.changed() && subTrack.size() == track.size() - 1) {
// add temporary point
modifier->tangents.push_back(TTrackTangent());
subTrack.push_back(track.back());
} else {
// apply permanent changes
// remove points
int start = track.size() - track.pointsAdded;
if (start < 0) start = 0;
if (start > 1) --start;
subTrack.truncate(start);
TTrackTangent lastTangent =
start < (int)modifier->tangents.size() ? modifier->tangents[start]
: modifier->tangents.empty() ? TTrackTangent()
: modifier->tangents.back();
modifier->tangents.resize(start, lastTangent);
// add first point
int index = start;
if (index == 0) {
modifier->tangents.push_back(TTrackTangent());
subTrack.push_back(track.back());
++index;
}
// add points with tangents
while(index < track.size() - 1) {
const TTrackPoint &p0 = track[index-1];
const TTrackPoint &p1 = track[index];
const TTrackPoint &p2 = track[index+1];
double dt = p2.time - p0.time;
double k = dt > TTrack::epsilon ? (p1.time - p0.time)/dt : 0.5;
TTrackTangent tangent(
(p2.position - p0.position)*k,
(p2.pressure - p0.pressure)*k,
(p2.tilt - p0.tilt)*k );
modifier->tangents.push_back(tangent);
subTrack.push_back(p1);
++index;
}
track.resetChanges();
// release previous key point
modifier->savePoint.reset();
if (track.finished()) {
// finish
modifier->tangents.push_back(TTrackTangent());
subTrack.push_back(track.back());
} else {
// save key point
modifier->savePoint = savePoint;
}
}
}