|
|
2b429e |
#pragma once
|
|
|
2b429e |
|
|
|
2b429e |
#ifndef TRACK_INCLUDED
|
|
|
2b429e |
#define TRACK_INCLUDED
|
|
|
2b429e |
|
|
|
2b429e |
// TnzTools includes
|
|
|
efa14d |
#include <tools inputstate.h=""></tools>
|
|
|
efa14d |
|
|
|
efa14d |
// TnzCore includes
|
|
|
2b429e |
#include <tcommon.h></tcommon.h>
|
|
|
2b429e |
#include <tgeometry.h></tgeometry.h>
|
|
|
2b429e |
|
|
|
2b429e |
// Qt headers
|
|
|
2b429e |
#include <qt></qt>
|
|
|
2b429e |
|
|
|
2b429e |
// std includes
|
|
|
2b429e |
#include <vector></vector>
|
|
|
2b429e |
#include <algorithm></algorithm>
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
#undef DVAPI
|
|
|
2b429e |
#undef DVVAR
|
|
|
2b429e |
#ifdef TNZTOOLS_EXPORTS
|
|
|
2b429e |
#define DVAPI DV_EXPORT_API
|
|
|
2b429e |
#define DVVAR DV_EXPORT_VAR
|
|
|
2b429e |
#else
|
|
|
2b429e |
#define DVAPI DV_IMPORT_API
|
|
|
2b429e |
#define DVVAR DV_IMPORT_VAR
|
|
|
2b429e |
#endif
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//===================================================================
|
|
|
2b429e |
|
|
|
2b429e |
// Forward Declarations
|
|
|
2b429e |
|
|
|
2b429e |
class TTrack;
|
|
|
49945e |
class TTrackPoint;
|
|
|
d8eddc |
class TTrackTangent;
|
|
|
da847a |
class TTrackTransform;
|
|
|
2b429e |
class TTrackHandler;
|
|
|
fa009d |
class TSubTrackHandler;
|
|
|
fa009d |
class TMultiTrackHandler;
|
|
|
fa009d |
class TTrackInterpolator;
|
|
|
49945e |
|
|
|
2b429e |
typedef TSmartPointerT<ttrack> TTrackP;</ttrack>
|
|
|
2b429e |
typedef TSmartPointerT<ttrackhandler> TTrackHandlerP;</ttrackhandler>
|
|
|
fa009d |
typedef TSmartPointerT<tsubtrackhandler> TSubTrackHandlerP;</tsubtrackhandler>
|
|
|
fa009d |
typedef TSmartPointerT<tmultitrackhandler> TMultiTrackHandlerP;</tmultitrackhandler>
|
|
|
fa009d |
typedef TSmartPointerT<ttrackinterpolator> TTrackInterpolatorP;</ttrackinterpolator>
|
|
|
49945e |
|
|
|
49945e |
typedef std::vector<ttrackpoint> TTrackPointList;</ttrackpoint>
|
|
|
d8eddc |
typedef std::vector<ttracktangent> TTrackTangentList;</ttracktangent>
|
|
|
da847a |
typedef std::vector<ttracktransform> TTrackTransformList;</ttracktransform>
|
|
|
efa14d |
typedef std::vector<ttrackp> TTrackList;</ttrackp>
|
|
|
2b429e |
|
|
|
2b429e |
//===================================================================
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
16421e |
// export template implementations for win32
|
|
|
16421e |
//*****************************************************************************************
|
|
|
16421e |
|
|
|
16421e |
#ifdef _WIN32
|
|
|
16421e |
template class DVAPI TSmartPointerT<ttrack>;</ttrack>
|
|
|
16421e |
template class DVAPI TSmartPointerT<ttrackhandler>;</ttrackhandler>
|
|
|
fa009d |
template class DVAPI TSmartPointerT<tsubtrackhandler>;</tsubtrackhandler>
|
|
|
fa009d |
template class DVAPI TSmartPointerT<tmultitrackhandler>;</tmultitrackhandler>
|
|
|
fa009d |
template class DVAPI TSmartPointerT<ttrackinterpolator>;</ttrackinterpolator>
|
|
|
16421e |
#endif
|
|
|
16421e |
|
|
|
16421e |
|
|
|
16421e |
//*****************************************************************************************
|
|
|
2b429e |
// TTrackPoint definition
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
6be163 |
class DVAPI TTrackPoint {
|
|
|
2b429e |
public:
|
|
|
2b429e |
TPointD position;
|
|
|
2b429e |
double pressure;
|
|
|
2b429e |
TPointD tilt;
|
|
|
2b429e |
|
|
|
2b429e |
double originalIndex;
|
|
|
2b429e |
double time;
|
|
|
2b429e |
double length;
|
|
|
2b429e |
|
|
|
2b429e |
bool final;
|
|
|
2b429e |
|
|
|
2b429e |
explicit TTrackPoint(
|
|
|
2b429e |
const TPointD &position = TPointD(),
|
|
|
2b429e |
double pressure = 0.5,
|
|
|
2b429e |
const TPointD &tilt = TPointD(),
|
|
|
2b429e |
double originalIndex = 0.0,
|
|
|
2b429e |
double time = 0.0,
|
|
|
2b429e |
double length = 0.0,
|
|
|
2b429e |
bool final = false
|
|
|
2b429e |
):
|
|
|
2b429e |
position(position),
|
|
|
2b429e |
pressure(pressure),
|
|
|
2b429e |
tilt(tilt),
|
|
|
2b429e |
originalIndex(originalIndex),
|
|
|
2b429e |
time(time),
|
|
|
2b429e |
length(length),
|
|
|
2b429e |
final(final)
|
|
|
2b429e |
{ }
|
|
|
2b429e |
};
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
d8eddc |
// TTrackTangent definition
|
|
|
d8eddc |
//*****************************************************************************************
|
|
|
d8eddc |
|
|
|
6be163 |
class DVAPI TTrackTangent {
|
|
|
d8eddc |
public:
|
|
|
d8eddc |
TPointD position;
|
|
|
d8eddc |
double pressure;
|
|
|
d8eddc |
TPointD tilt;
|
|
|
d8eddc |
|
|
|
d8eddc |
inline explicit TTrackTangent(
|
|
|
d8eddc |
const TPointD &position = TPointD(),
|
|
|
d8eddc |
double pressure = 0.0,
|
|
|
d8eddc |
const TPointD &tilt = TPointD()
|
|
|
d8eddc |
):
|
|
|
d8eddc |
position(position),
|
|
|
d8eddc |
pressure(pressure),
|
|
|
d8eddc |
tilt(tilt)
|
|
|
d8eddc |
{ }
|
|
|
d8eddc |
};
|
|
|
d8eddc |
|
|
|
d8eddc |
|
|
|
d8eddc |
//*****************************************************************************************
|
|
|
2b429e |
// TTrackHandler definition
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
da847a |
class DVAPI TTrackTransform {
|
|
|
da847a |
public:
|
|
|
da847a |
TAffine transform;
|
|
|
da847a |
TAffine tiltTransform;
|
|
|
da847a |
double pressureScale;
|
|
|
da847a |
double pressureOffset;
|
|
|
da847a |
|
|
|
da847a |
inline TTrackTransform(
|
|
|
da847a |
const TAffine &transform,
|
|
|
da847a |
const TAffine &tiltTransform,
|
|
|
da847a |
double pressureScale = 1,
|
|
|
da847a |
double pressureOffset = 0
|
|
|
da847a |
):
|
|
|
da847a |
transform(transform),
|
|
|
da847a |
tiltTransform(tiltTransform),
|
|
|
da847a |
pressureScale(pressureScale),
|
|
|
da847a |
pressureOffset(pressureOffset) { }
|
|
|
da847a |
|
|
|
da847a |
inline explicit TTrackTransform(
|
|
|
da847a |
const TAffine &transform,
|
|
|
da847a |
double pressureScale = 1,
|
|
|
da847a |
double pressureOffset = 0
|
|
|
da847a |
):
|
|
|
da847a |
transform(transform),
|
|
|
da847a |
tiltTransform(makeTiltTransform(transform)),
|
|
|
da847a |
pressureScale(pressureScale),
|
|
|
da847a |
pressureOffset(pressureOffset) { }
|
|
|
da847a |
|
|
|
da847a |
inline explicit TTrackTransform(
|
|
|
da847a |
double pressureScale = 1,
|
|
|
da847a |
double pressureOffset = 0
|
|
|
da847a |
):
|
|
|
da847a |
pressureScale(pressureScale),
|
|
|
da847a |
pressureOffset(pressureOffset) { }
|
|
|
da847a |
|
|
|
da847a |
inline TTrackPoint apply(TTrackPoint p) const {
|
|
|
da847a |
p.position = transform * p.position;
|
|
|
da847a |
|
|
|
da847a |
TPointD t = tiltTransform * p.tilt;
|
|
|
da847a |
p.tilt.x = t.x > -1 ? (t.x < 1 ? t.x : 1) : -1;
|
|
|
da847a |
p.tilt.y = t.y > -1 ? (t.y < 1 ? t.y : 1) : -1;
|
|
|
da847a |
|
|
|
da847a |
double pr = p.pressure*pressureScale + pressureOffset;
|
|
|
da847a |
p.pressure = pr > 0 ? (pr < 1 ? pr : 1) : 0;
|
|
|
da847a |
|
|
|
da847a |
return p;
|
|
|
da847a |
}
|
|
|
da847a |
|
|
|
da847a |
inline void recalcTiltTransform()
|
|
|
da847a |
{ tiltTransform = makeTiltTransform(transform); }
|
|
|
da847a |
|
|
|
da847a |
static TAffine makeTiltTransform(const TAffine &a);
|
|
|
da847a |
};
|
|
|
da847a |
|
|
|
da847a |
|
|
|
da847a |
//*****************************************************************************************
|
|
|
da847a |
// TTrackHandler definition
|
|
|
da847a |
//*****************************************************************************************
|
|
|
da847a |
|
|
|
fa009d |
class DVAPI TTrackHandler : public TSmartObject { };
|
|
|
fa009d |
|
|
|
fa009d |
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
// TSubTrackHandler definition
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
|
|
|
fa009d |
class DVAPI TSubTrackHandler: public TTrackHandler {
|
|
|
2b429e |
public:
|
|
|
fa009d |
TTrackP track;
|
|
|
2b429e |
};
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
fa009d |
// TMultiTrackHandler definition
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
fa009d |
class DVAPI TMultiTrackHandler: public TTrackHandler {
|
|
|
2b429e |
public:
|
|
|
fa009d |
std::vector<ttrackp> tracks;</ttrackp>
|
|
|
fa009d |
};
|
|
|
fa009d |
|
|
|
fa009d |
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
// TTrackInterpolator definition
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
fa009d |
class DVAPI TTrackInterpolator : public TSmartObject {
|
|
|
fa009d |
public:
|
|
|
fa009d |
TTrack &track;
|
|
|
fa009d |
inline explicit TTrackInterpolator(TTrack &track);
|
|
|
fa009d |
virtual TTrackPoint interpolate(double index) = 0;
|
|
|
2b429e |
};
|
|
|
2b429e |
|
|
|
2b429e |
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
// TTrack definition
|
|
|
2b429e |
//*****************************************************************************************
|
|
|
2b429e |
|
|
|
2b429e |
class DVAPI TTrack : public TSmartObject {
|
|
|
2b429e |
public:
|
|
|
2b429e |
typedef long long Id;
|
|
|
2b429e |
|
|
|
2b429e |
private:
|
|
|
49945e |
static Id m_lastId;
|
|
|
2b429e |
|
|
|
2b429e |
public:
|
|
|
2b429e |
const Id id;
|
|
|
efa14d |
const TInputState::DeviceId deviceId;
|
|
|
efa14d |
const TInputState::TouchId touchId;
|
|
|
efa14d |
const TInputState::KeyHistory::Holder keyHistory;
|
|
|
efa14d |
const TInputState::ButtonHistory::Holder buttonHistory;
|
|
|
49945e |
const bool hasPressure;
|
|
|
49945e |
const bool hasTilt;
|
|
|
2b429e |
|
|
|
fa009d |
const TTrack* const original;
|
|
|
fa009d |
const double timeOffset;
|
|
|
fa009d |
const double rootTimeOffset;
|
|
|
fa009d |
|
|
|
c3c215 |
mutable TTrackHandlerP handler;
|
|
|
c3c215 |
mutable int pointsRemoved;
|
|
|
c3c215 |
mutable int pointsAdded;
|
|
|
f278a5 |
mutable int fixedPointsAdded;
|
|
|
2b429e |
|
|
|
2b429e |
private:
|
|
|
fa009d |
friend class TTrackInterpolator;
|
|
|
fa009d |
TTrackInterpolatorP interpolator;
|
|
|
49945e |
TTrackPointList m_points;
|
|
|
49945e |
const TTrackPoint m_none;
|
|
|
f278a5 |
int m_pointsFixed;
|
|
|
2b429e |
|
|
|
2b429e |
public:
|
|
|
2b429e |
|
|
|
2b429e |
explicit TTrack(
|
|
|
efa14d |
TInputState::DeviceId deviceId = TInputState::DeviceId(),
|
|
|
efa14d |
TInputState::TouchId touchId = TInputState::TouchId(),
|
|
|
efa14d |
const TInputState::KeyHistory::Holder &keyHistory = TInputState::KeyHistory::Holder(),
|
|
|
49945e |
const TInputState::ButtonHistory::Holder &buttonHistory = TInputState::ButtonHistory::Holder(),
|
|
|
49945e |
bool hasPressure = false,
|
|
|
fa009d |
bool hasTilt = false,
|
|
|
fa009d |
double timeOffset = 0
|
|
|
2b429e |
);
|
|
|
2b429e |
|
|
|
fa009d |
explicit TTrack(const TTrack &original, double timeOffset = 0);
|
|
|
fa009d |
|
|
|
fa009d |
const TTrackInterpolatorP& getInterpolator() const
|
|
|
fa009d |
{ return interpolator; }
|
|
|
fa009d |
void removeInterpolator()
|
|
|
fa009d |
{ interpolator.reset(); }
|
|
|
2b429e |
|
|
|
2b429e |
inline TTimerTicks ticks() const
|
|
|
2b429e |
{ return keyHistory.ticks(); }
|
|
|
2b429e |
inline bool changed() const
|
|
|
f278a5 |
{ return pointsRemoved || pointsAdded || fixedPointsAdded; }
|
|
|
2b429e |
|
|
|
2b429e |
const TTrack* root() const;
|
|
|
2b429e |
int level() const;
|
|
|
2b429e |
|
|
|
2b429e |
inline int clampIndex(int index) const
|
|
|
2b429e |
{ return std::min(std::max(index, 0), size() - 1); }
|
|
|
fa009d |
inline double clampIndexFloat(double index) const
|
|
|
fa009d |
{ return std::min(std::max(index, 0.0), (double)(size() - 1)); }
|
|
|
2b429e |
inline int floorIndexNoClamp(double index) const
|
|
|
9f0c16 |
{ return (int)floor(index + TConsts::epsilon); }
|
|
|
2b429e |
inline int floorIndex(double index) const
|
|
|
2b429e |
{ return clampIndex(floorIndexNoClamp(index)); }
|
|
|
2b429e |
inline int ceilIndexNoClamp(double index) const
|
|
|
fa009d |
{ return floorIndexNoClamp(index) + 1; }
|
|
|
2b429e |
inline int ceilIndex(double index) const
|
|
|
2b429e |
{ return clampIndex(ceilIndexNoClamp(index)); }
|
|
|
2b429e |
|
|
|
7e9eb1 |
int floorIndex(double index, double *outFrac) const;
|
|
|
2b429e |
|
|
|
7e9eb1 |
inline const TTrackPoint& floorPoint(double index, double *outFrac = NULL) const
|
|
|
2b429e |
{ return point(floorIndex(index, outFrac)); }
|
|
|
2b429e |
inline const TTrackPoint& ceilPoint(double index) const
|
|
|
2b429e |
{ return point(ceilIndex(index)); }
|
|
|
2b429e |
|
|
|
2b429e |
inline const TTrackPoint& point(int index) const
|
|
|
49945e |
{ return empty() ? m_none : m_points[clampIndex(index)]; }
|
|
|
2b429e |
|
|
|
2b429e |
inline int size() const
|
|
|
49945e |
{ return (int)m_points.size(); }
|
|
|
f278a5 |
inline int fixedSize() const
|
|
|
f278a5 |
{ return m_pointsFixed; }
|
|
|
f278a5 |
inline int previewSize() const
|
|
|
f278a5 |
{ return size() - fixedSize(); }
|
|
|
2b429e |
inline bool empty() const
|
|
|
49945e |
{ return m_points.empty(); }
|
|
|
2b429e |
inline const TTrackPoint& front() const
|
|
|
2b429e |
{ return point(0); }
|
|
|
2b429e |
inline const TTrackPoint& back() const
|
|
|
2b429e |
{ return point(size() - 1); }
|
|
|
2b429e |
inline bool finished() const
|
|
|
49945e |
{ return !m_points.empty() && back().final; }
|
|
|
f278a5 |
inline bool fixedFinished() const
|
|
|
f278a5 |
{ return finished() && !previewSize(); }
|
|
|
2b429e |
inline const TTrackPoint& operator[] (int index) const
|
|
|
2b429e |
{ return point(index); }
|
|
|
49945e |
inline const TTrackPointList& points() const
|
|
|
49945e |
{ return m_points; }
|
|
|
2b429e |
|
|
|
00337d |
inline void resetRemoved() const
|
|
|
00337d |
{ pointsRemoved = 0; }
|
|
|
00337d |
inline void resetAdded() const
|
|
|
00337d |
{ pointsAdded = 0; }
|
|
|
f278a5 |
inline void resetFixedAdded() const
|
|
|
f278a5 |
{ fixedPointsAdded = 0; }
|
|
|
00337d |
inline void resetChanges() const
|
|
|
f278a5 |
{ resetRemoved(); resetAdded(); resetFixedAdded(); }
|
|
|
00337d |
|
|
|
f278a5 |
void push_back(const TTrackPoint &point, bool fixed);
|
|
|
2b429e |
void pop_back(int count = 1);
|
|
|
f278a5 |
void fix_points(int count = 1);
|
|
|
2b429e |
|
|
|
2b429e |
inline void truncate(int count)
|
|
|
2b429e |
{ pop_back(size() - count); }
|
|
|
f278a5 |
inline void fix_to(int count)
|
|
|
f278a5 |
{ fix_points(count - fixedSize()); }
|
|
|
f278a5 |
inline void fix_all()
|
|
|
f278a5 |
{ fix_to(size()); }
|
|
|
2b429e |
|
|
|
49945e |
inline const TTrackPoint& current() const
|
|
|
49945e |
{ return point(size() - pointsAdded); }
|
|
|
7a5892 |
inline const TTrackPoint& previous() const
|
|
|
7a5892 |
{ return point(size() - pointsAdded - 1); }
|
|
|
7a5892 |
inline const TTrackPoint& next() const
|
|
|
7a5892 |
{ return point(size() - pointsAdded + 1); }
|
|
|
7a5892 |
|
|
|
49945e |
inline TInputState::KeyState::Holder getKeyState(double time) const
|
|
|
49945e |
{ return keyHistory.get(time); }
|
|
|
d8eddc |
inline TInputState::KeyState::Holder getKeyState(const TTrackPoint &point) const
|
|
|
fa009d |
{ return getKeyState(rootTimeOffset + point.time); }
|
|
|
49945e |
inline TInputState::KeyState::Holder getCurrentKeyState() const
|
|
|
fa009d |
{ return getKeyState(rootTimeOffset + current().time); }
|
|
|
49945e |
inline TInputState::ButtonState::Holder getButtonState(double time) const
|
|
|
49945e |
{ return buttonHistory.get(time); }
|
|
|
d8eddc |
inline TInputState::ButtonState::Holder getButtonState(const TTrackPoint &point) const
|
|
|
fa009d |
{ return getButtonState(rootTimeOffset + point.time); }
|
|
|
49945e |
inline TInputState::ButtonState::Holder getCurrentButtonState() const
|
|
|
fa009d |
{ return getButtonState(rootTimeOffset + current().time); }
|
|
|
2b429e |
|
|
|
2b429e |
private:
|
|
|
2b429e |
template<double ttrackpoint::*field=""></double>
|
|
|
2b429e |
double binarySearch(double value) const {
|
|
|
2b429e |
// points_[a].value <= value < points_[b].value
|
|
|
49945e |
if (m_points.empty()) return 0.0;
|
|
|
2b429e |
int a = 0;
|
|
|
49945e |
double aa = m_points[a].*Field;
|
|
|
9f0c16 |
if (value - aa <= 0.5*TConsts::epsilon) return (double)a;
|
|
|
49945e |
int b = (int)m_points.size() - 1;
|
|
|
49945e |
double bb = m_points[b].*Field;
|
|
|
9f0c16 |
if (bb - value <= 0.5*TConsts::epsilon) return (double)b;
|
|
|
2b429e |
while(true) {
|
|
|
2b429e |
int c = (a + b)/2;
|
|
|
2b429e |
if (a == c) break;
|
|
|
49945e |
double cc = m_points[c].*Field;
|
|
|
9f0c16 |
if (cc - value > 0.5*TConsts::epsilon)
|
|
|
2b429e |
{ b = c; bb = cc; } else { a = c; aa = cc; }
|
|
|
2b429e |
}
|
|
|
9f0c16 |
return bb - aa >= 0.5*TConsts::epsilon ? (double)a + (value - aa)/(bb - aa) : (double)a;
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
2b429e |
public:
|
|
|
2b429e |
inline double indexByOriginalIndex(double originalIndex) const
|
|
|
2b429e |
{ return binarySearch<&TTrackPoint::originalIndex>(originalIndex); }
|
|
|
2b429e |
inline double indexByTime(double time) const
|
|
|
2b429e |
{ return binarySearch<&TTrackPoint::time>(time); }
|
|
|
2b429e |
inline double indexByLength(double length) const
|
|
|
2b429e |
{ return binarySearch<&TTrackPoint::length>(length); }
|
|
|
2b429e |
|
|
|
2b429e |
inline double originalIndexByIndex(double index) const {
|
|
|
2b429e |
double frac;
|
|
|
7e9eb1 |
const TTrackPoint &p0 = floorPoint(index, &frac);
|
|
|
2b429e |
const TTrackPoint &p1 = ceilPoint(index);
|
|
|
2b429e |
return interpolationLinear(p0.originalIndex, p1.originalIndex, frac);
|
|
|
2b429e |
}
|
|
|
2b429e |
inline double timeByIndex(double index) const {
|
|
|
2b429e |
double frac;
|
|
|
7e9eb1 |
const TTrackPoint &p0 = floorPoint(index, &frac);
|
|
|
2b429e |
const TTrackPoint &p1 = ceilPoint(index);
|
|
|
2b429e |
return interpolationLinear(p0.time, p1.time, frac);
|
|
|
2b429e |
}
|
|
|
2b429e |
inline double lengthByIndex(double index) const {
|
|
|
2b429e |
double frac;
|
|
|
7e9eb1 |
const TTrackPoint &p0 = floorPoint(index, &frac);
|
|
|
2b429e |
const TTrackPoint &p1 = ceilPoint(index);
|
|
|
2b429e |
return interpolationLinear(p0.length, p1.length, frac);
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
fa009d |
inline TTrackPoint calcPoint(double index) const
|
|
|
fa009d |
{ return interpolator ? interpolator->interpolate(index) : interpolateLinear(index); }
|
|
|
2b429e |
TPointD calcTangent(double index, double distance = 0.1) const;
|
|
|
49945e |
double rootIndexByIndex(double index) const;
|
|
|
49945e |
TTrackPoint calcRootPoint(double index) const;
|
|
|
2b429e |
|
|
|
fa009d |
inline TTrackPoint pointFromOriginal(const TTrackPoint &originalPoint, double originalIndex) const {
|
|
|
fa009d |
TTrackPoint p = originalPoint;
|
|
|
fa009d |
p.originalIndex = original ? original->clampIndexFloat(originalIndex) : originalIndex;
|
|
|
fa009d |
p.time -= timeOffset;
|
|
|
fa009d |
return p;
|
|
|
fa009d |
}
|
|
|
fa009d |
|
|
|
fa009d |
inline TTrackPoint pointFromOriginal(int originalIndex) const
|
|
|
fa009d |
{ return original ? pointFromOriginal(original->point(originalIndex), originalIndex) : TTrackPoint(); }
|
|
|
fa009d |
|
|
|
fa009d |
inline TTrackPoint calcPointFromOriginal(double originalIndex) const
|
|
|
fa009d |
{ return original ? pointFromOriginal(original->calcPoint(originalIndex), originalIndex) : TTrackPoint(); }
|
|
|
fa009d |
|
|
|
2b429e |
inline TTrackPoint interpolateLinear(double index) const {
|
|
|
2b429e |
double frac;
|
|
|
7e9eb1 |
const TTrackPoint &p0 = floorPoint(index, &frac);
|
|
|
2b429e |
const TTrackPoint &p1 = ceilPoint(index);
|
|
|
2b429e |
return interpolationLinear(p0, p1, frac);
|
|
|
2b429e |
}
|
|
|
2b429e |
|
|
|
2b429e |
template<typename t=""></typename>
|
|
|
2b429e |
static inline T interpolationLinear(const T &p0, const T &p1, double l)
|
|
|
2b429e |
{ return p0*(1.0 - l) + p1*l; }
|
|
|
2b429e |
|
|
|
d8eddc |
template<typename t=""></typename>
|
|
|
d8eddc |
static T interpolationSpline(const T &p0, const T &p1, const T &t0, const T &t1, double l) {
|
|
|
d8eddc |
double ll = l*l;
|
|
|
d8eddc |
double lll = ll*l;
|
|
|
d8eddc |
return p0*( 2.0*lll - 3.0*ll + 1.0)
|
|
|
d8eddc |
+ p1*(-2.0*lll + 3.0*ll )
|
|
|
d8eddc |
+ t0*( lll - 2.0*ll + l )
|
|
|
d8eddc |
+ t1*( lll - 1.0*ll );
|
|
|
d8eddc |
}
|
|
|
d8eddc |
|
|
|
2b429e |
static inline TTrackPoint interpolationLinear(const TTrackPoint &p0, const TTrackPoint &p1, double l) {
|
|
|
9f0c16 |
if (l <= TConsts::epsilon) return p0;
|
|
|
9f0c16 |
if (l >= 1.0 - TConsts::epsilon) return p1;
|
|
|
2b429e |
return TTrackPoint(
|
|
|
2b429e |
interpolationLinear(p0.position , p1.position , l),
|
|
|
2b429e |
interpolationLinear(p0.pressure , p1.pressure , l),
|
|
|
2b429e |
interpolationLinear(p0.tilt , p1.tilt , l),
|
|
|
2b429e |
interpolationLinear(p0.originalIndex , p1.originalIndex , l),
|
|
|
2b429e |
interpolationLinear(p0.time , p1.time , l),
|
|
|
7dd550 |
interpolationLinear(p0.length , p1.length , l),
|
|
|
7dd550 |
p0.final && p1.final );
|
|
|
2b429e |
}
|
|
|
d8eddc |
|
|
|
d8eddc |
static inline TTrackPoint interpolationSpline(
|
|
|
d8eddc |
const TTrackPoint &p0,
|
|
|
d8eddc |
const TTrackPoint &p1,
|
|
|
d8eddc |
const TTrackTangent &t0,
|
|
|
d8eddc |
const TTrackTangent &t1,
|
|
|
d8eddc |
double l )
|
|
|
d8eddc |
{
|
|
|
9f0c16 |
if (l <= TConsts::epsilon) return p0;
|
|
|
9f0c16 |
if (l >= 1.0 - TConsts::epsilon) return p1;
|
|
|
d8eddc |
return TTrackPoint(
|
|
|
d8eddc |
interpolationSpline(p0.position , p1.position , t0.position , t1.position , l),
|
|
|
9f0c16 |
interpolationLinear(p0.pressure , p1.pressure , l),
|
|
|
f278a5 |
//interpolationSpline(p0.pressure , p1.pressure , t0.pressure , t1.pressure , l),
|
|
|
9f0c16 |
interpolationLinear(p0.tilt , p1.tilt , l),
|
|
|
f278a5 |
//interpolationSpline(p0.tilt , p1.tilt , t0.tilt , t1.tilt , l),
|
|
|
d8eddc |
interpolationLinear(p0.originalIndex , p1.originalIndex , l),
|
|
|
d8eddc |
interpolationLinear(p0.time , p1.time , l),
|
|
|
7dd550 |
interpolationLinear(p0.length , p1.length , l),
|
|
|
7dd550 |
p0.final && p1.final );
|
|
|
d8eddc |
}
|
|
|
2b429e |
};
|
|
|
2b429e |
|
|
|
16421e |
|
|
|
fa009d |
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
// TTrackInterpolator implemantation
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
|
|
|
fa009d |
inline TTrackInterpolator::TTrackInterpolator(TTrack &track):
|
|
|
fa009d |
track(track) { track.interpolator = this; }
|
|
|
fa009d |
|
|
|
fa009d |
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
// TTrackIntrOrig definition
|
|
|
fa009d |
//*****************************************************************************************
|
|
|
fa009d |
|
|
|
fa009d |
class DVAPI TTrackIntrOrig : public TTrackInterpolator {
|
|
|
fa009d |
public:
|
|
|
fa009d |
using TTrackInterpolator::TTrackInterpolator;
|
|
|
fa009d |
TTrackPoint interpolate(double index) override;
|
|
|
fa009d |
};
|
|
|
fa009d |
|
|
|
fa009d |
|
|
|
2b429e |
#endif
|