2b429e
2b429e
2b429e
#include <tools track.h=""></tools>
2b429e
2b429e
2b429e
//*****************************************************************************************
49945e
//    Static fields
2b429e
//*****************************************************************************************
2b429e
49945e
TTrack::Id TTrack::m_lastId = 0;
2b429e
2b429e
2b429e
//*****************************************************************************************
bdb1e2
//    TTrackIntrOrig implemantation
2b429e
//*****************************************************************************************
2b429e
2b429e
TTrackPoint
bdb1e2
TTrackIntrOrig::interpolate(double index) {
bdb1e2
  return track.original ? track.calcPointFromOriginal(track.originalIndexByIndex(index))
bdb1e2
                        : track.interpolateLinear(index);
2b429e
}
2b429e
2b429e
2b429e
//*****************************************************************************************
2b429e
//    TTrack implemantation
2b429e
//*****************************************************************************************
2b429e
2b429e
TTrack::TTrack(
efa14d
  TInputState::DeviceId deviceId,
efa14d
  TInputState::TouchId touchId,
efa14d
  const TInputState::KeyHistory::Holder &keyHistory,
49945e
  const TInputState::ButtonHistory::Holder &buttonHistory,
49945e
  bool hasPressure,
bdb1e2
  bool hasTilt,
bdb1e2
  double timeOffset
2b429e
):
49945e
  id(++m_lastId),
2b429e
  deviceId(deviceId),
2b429e
  touchId(touchId),
2b429e
  keyHistory(keyHistory),
2b429e
  buttonHistory(buttonHistory),
49945e
  hasPressure(hasPressure),
49945e
  hasTilt(hasTilt),
bdb1e2
  original(),
bdb1e2
  timeOffset(timeOffset),
bdb1e2
  rootTimeOffset(timeOffset),
49945e
  pointsRemoved(),
7d1790
  pointsAdded(),
7d1790
  fixedPointsAdded(),
7d1790
  m_pointsFixed()
2b429e
  { }
2b429e
bdb1e2
TTrack::TTrack(const TTrack &original, double timeOffset):
49945e
  id(++m_lastId),
bdb1e2
  deviceId(original.deviceId),
bdb1e2
  touchId(original.touchId),
bdb1e2
  keyHistory(original.keyHistory),
bdb1e2
  buttonHistory(original.buttonHistory),
bdb1e2
  hasPressure(original.hasPressure),
bdb1e2
  hasTilt(original.hasTilt),
bdb1e2
  original(&original),
bdb1e2
  timeOffset(timeOffset),
bdb1e2
  rootTimeOffset(original.rootTimeOffset + timeOffset),
49945e
  pointsRemoved(),
7d1790
  pointsAdded(),
7d1790
  fixedPointsAdded(),
7d1790
  m_pointsFixed()
2b429e
  { }
2b429e
2b429e
const TTrack*
2b429e
TTrack::root() const
bdb1e2
  { return original ? original->root() : this; }
2b429e
2b429e
int
2b429e
TTrack::level() const
bdb1e2
  { return original ? original->level() + 1 : 0; }
2b429e
2b429e
int
7e9eb1
TTrack::floorIndex(double index, double *outFrac) const {
bdb1e2
  int i = floorIndexNoClamp(index);
7e9eb1
  if (i > size() - 1) {
7e9eb1
    if (outFrac) *outFrac = 0.0;
7e9eb1
    return size() - 1;
7e9eb1
  }
7e9eb1
  if (i < 0) {
7e9eb1
    if (outFrac) *outFrac = 0.0;
7e9eb1
    return 0;
7e9eb1
  }
7e9eb1
  if (outFrac) *outFrac = std::max(0.0, index - (double)i);
2b429e
  return i;
2b429e
}
2b429e
2b429e
void
7d1790
TTrack::push_back(const TTrackPoint &point, bool fixed) {
bdb1e2
  assert(m_points.empty() || !m_points.back().final);
49945e
  m_points.push_back(point);
bdb1e2
  TTrackPoint &p = m_points.back();
bdb1e2
  if (m_points.size() <= 1) {
bdb1e2
    p.length = 0;
bdb1e2
  } else {
9f0c16
    const TTrackPoint &prev = *(m_points.rbegin() + 1);
2b429e
9f0c16
    // fix originalIndex
9f0c16
    if (p.originalIndex < prev.originalIndex)
9f0c16
        p.originalIndex = prev.originalIndex;
2b429e
9f0c16
    // fix time
9f0c16
    p.time = std::max(p.time, prev.time + TToolTimer::step);
00337d
9f0c16
    // calculate length
bdb1e2
    p.length = prev.length + tdistance(p.position, prev.position);
9f0c16
  }
00337d
  ++pointsAdded;
7d1790
  if (fixed) fix_all();
2b429e
}
2b429e
2b429e
void
2b429e
TTrack::pop_back(int count) {
00337d
  if (count > size()) count = size();
2b429e
  if (count <= 0) return;
7d1790
  assert(size() - count >= m_pointsFixed);
00337d
  m_points.resize(size() - count);
7a5892
  if (pointsAdded > count)
7a5892
    { pointsAdded -= count; return; }
7a5892
  if (pointsAdded > 0)
7a5892
    { count -= pointsAdded; pointsAdded = 0; }
00337d
  pointsRemoved += count;
2b429e
}
2b429e
7d1790
void
7d1790
TTrack::fix_points(int count) {
7d1790
  count = std::min(count, previewSize());
7d1790
  assert(count >= 0);
7d1790
  if (count <= 0) return;
7d1790
  m_pointsFixed += count;
7d1790
  fixedPointsAdded += count;
7d1790
}
7d1790
2b429e
2b429e
TPointD
2b429e
TTrack::calcTangent(double index, double distance) const {
9f0c16
  double minDistance = 10.0*TConsts::epsilon;
2b429e
  if (distance < minDistance) distance = minDistance;
2b429e
  TTrackPoint p = calcPoint(index);
2b429e
  TTrackPoint pp = calcPoint(indexByLength(p.length - distance));
2b429e
  TPointD dp = p.position - pp.position;
2b429e
  double lenSqr = dp.x*dp.x + dp.y*dp.y;
9f0c16
  return lenSqr > TConsts::epsilon*TConsts::epsilon ? dp*(1.0/sqrt(lenSqr)) : TPointD();
2b429e
}
49945e
49945e
double
49945e
TTrack::rootIndexByIndex(double index) const {
bdb1e2
  return original
bdb1e2
       ? original->rootIndexByIndex( originalIndexByIndex(index) )
49945e
       : index;
49945e
}
49945e
49945e
TTrackPoint
49945e
TTrack::calcRootPoint(double index) const {
bdb1e2
  return original
bdb1e2
       ? original->calcRootPoint( originalIndexByIndex(index) )
49945e
       : calcPoint(index);
49945e
}