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