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