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);
7d1790
  int i1 = i0 + 1;
9f0c16
9f0c16
  TTrackPoint p;
7d1790
7d1790
  // calculate tangent length to make monotonic subdivisions,
7d1790
  // (because we don't have valid input time)
7d1790
  const TTrackPoint &p0 = original[i0];
7d1790
  const TTrackPoint &p1 = original[i1];
7d1790
  TTrackTangent t0 = i0 >= 0 && i0 < (int)tangents.size() ? tangents[i0] : TTrackTangent();
7d1790
  TTrackTangent t1 = i1 >= 0 && i1 < (int)tangents.size() ? tangents[i1] : TTrackTangent();
7d1790
  double l = p1.length - p0.length;
7d1790
  
7d1790
  t0.position.x *= l;
7d1790
  t0.position.y *= l;
7d1790
  t0.pressure *= l;
7d1790
  t0.tilt.x *= l;
7d1790
  t0.tilt.y *= l;
7d1790
  
7d1790
  t1.position.x *= l;
7d1790
  t1.position.y *= l;
7d1790
  t1.pressure *= l;
7d1790
  t1.tilt.x *= l;
7d1790
  t1.tilt.y *= l;
7d1790
  
7d1790
  p = TTrack::interpolationSpline(p0, p1, t0, t1, frac);
d8eddc
  p.originalIndex = originalIndex;
d8eddc
  return p;
d8eddc
}
d8eddc
d8eddc
d8eddc
//*****************************************************************************************
d8eddc
//    TModifierTangents implementation
d8eddc
//*****************************************************************************************
d8eddc
d8eddc
9f0c16
TTrackTangent
7d1790
TModifierTangents::calcTangent(const TTrack &track, int index) const {
7d1790
  if (index <= 0 || index >= track.size() - 1)
7d1790
    return TTrackTangent();
7d1790
  
7d1790
  const TTrackPoint &p0 = track[index-1];
7d1790
  const TTrackPoint &p2 = track[index+1];
7d1790
7d1790
  // calculate tangent length by time
7d1790
  // for that we need know time of actual user input
7d1790
  // instead of time when message dispatched
7d1790
  //double k = p2.time - p0.time;
7d1790
  
7d1790
  // calculate tangent based on length, util we have no valid times
7d1790
  double k = p2.length - p0.length;
7d1790
  
7d1790
  k = k > TConsts::epsilon ? 1/k : 0;
9f0c16
  return TTrackTangent(
7d1790
    (p2.position - p0.position)*k,
7d1790
    (p2.pressure - p0.pressure)*k,
7d1790
    (p2.tilt     - p0.tilt    )*k );
9f0c16
}
9f0c16
9f0c16
d8eddc
void
d8eddc
TModifierTangents::modifyTrack(
c3c215
  const TTrack &track,
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());
7d1790
  if (!track.changed())
7d1790
    return;
7d1790
  
7d1790
  // update subTrack
7d1790
  int start = track.size() - track.pointsAdded;
7d1790
  if (start > 1) --start;
7d1790
  if (start < 0) start = 0;
7d1790
  subTrack.truncate(start);
398cd8
  for(int i = start; i < track.size(); ++i) {
398cd8
    TTrackPoint p = track[i];
398cd8
    p.originalIndex = i;
398cd8
    subTrack.push_back(p, false);
398cd8
  }
7d1790
  
7d1790
  // update tangents
7d1790
  modifier->tangents.resize(start);
7d1790
  for(int i = start; i < track.size(); ++i)
7d1790
    modifier->tangents.push_back(calcTangent(track, i));
7d1790
  
7d1790
  // fix points
7d1790
  if (track.fixedFinished()) {
7d1790
    subTrack.fix_all();
7d1790
  } else
7d1790
  if (track.fixedSize()) {
7d1790
    subTrack.fix_to(std::max(track.fixedSize() - 1, 1));
d8eddc
  }
7d1790
  
7d1790
  track.resetChanges();
d8eddc
}
d8eddc