|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
#ifndef NDEBUG
|
|
|
7e9eb1 |
|
|
|
d8eddc |
#include <tools modifiers="" modifiertest.h=""></tools>
|
|
|
7e9eb1 |
|
|
|
d8eddc |
// std includes
|
|
|
d8eddc |
#include <cmath></cmath>
|
|
|
7e9eb1 |
|
|
|
fa009d |
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
fa009d |
// TModifierTest::Interpolator implementation
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
|
|
|
fa009d |
TTrackPoint TModifierTest::Interpolator::interpolateFromOriginal(double originalIndex) {
|
|
|
fa009d |
Handler *handler = track.original
|
|
|
fa009d |
? dynamic_cast<handler*>(track.original->handler.getPointer())</handler*>
|
|
|
fa009d |
: nullptr;
|
|
|
fa009d |
if (!handler)
|
|
|
fa009d |
return track.interpolateLinear(track.indexByOriginalIndex(originalIndex));
|
|
|
fa009d |
|
|
|
fa009d |
TTrackPoint p = track.calcPointFromOriginal(originalIndex);
|
|
|
fa009d |
|
|
|
fa009d |
double frac;
|
|
|
fa009d |
int i0 = track.original->floorIndex(originalIndex, &frac);
|
|
|
fa009d |
int i1 = track.original->ceilIndex(originalIndex);
|
|
|
fa009d |
|
|
|
fa009d |
double angle = TTrack::interpolationLinear(
|
|
|
fa009d |
handler->angles[i0], handler->angles[i1], frac );
|
|
|
fa009d |
double a = angle*speed + this->angle;
|
|
|
fa009d |
|
|
|
fa009d |
double kr = 1 - 1/(angle + 1);
|
|
|
fa009d |
double s = sin(a);
|
|
|
fa009d |
double r = radius*p.pressure*kr*s;
|
|
|
fa009d |
|
|
|
fa009d |
double d = fabs(2.0*radius);
|
|
|
fa009d |
if (fabs(speed) > TConsts::epsilon)
|
|
|
fa009d |
d /= fabs(speed);
|
|
|
fa009d |
|
|
|
fa009d |
TPointD tangent = track.original->calcTangent(originalIndex, d);
|
|
|
fa009d |
p.position.x -= tangent.y * r;
|
|
|
fa009d |
p.position.y += tangent.x * r;
|
|
|
fa009d |
p.pressure *= fabs(s);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
return p;
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
fa009d |
|
|
|
fa009d |
TTrackPoint TModifierTest::Interpolator::interpolate(double index) {
|
|
|
fa009d |
return interpolateFromOriginal(track.originalIndexByIndex(index));
|
|
|
fa009d |
}
|
|
|
fa009d |
|
|
|
fa009d |
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
// TModifierTest implementation
|
|
|
7e9eb1 |
//*****************************************************************************************
|
|
|
7e9eb1 |
|
|
|
fa009d |
TModifierTest::TModifierTest(int count, double radius, double speed)
|
|
|
fa009d |
: count(count), radius(radius), speed(speed) {}
|
|
|
7e9eb1 |
|
|
shun-iwasawa |
ec85ad |
void TModifierTest::modifyTrack(const TTrack &track,
|
|
shun-iwasawa |
ec85ad |
TTrackList &outTracks) {
|
|
shun-iwasawa |
ec85ad |
const double segmentSize = 2.0 * M_PI / 10.0;
|
|
|
7e9eb1 |
|
|
|
fa009d |
if ( !track.handler
|
|
|
fa009d |
&& track.getKeyState(track.front().time).isPressed(TKey::alt) )
|
|
|
fa009d |
{
|
|
|
fa009d |
Handler *handler = new Handler(this->radius);
|
|
|
fa009d |
track.handler = handler;
|
|
|
fa009d |
for (int i = 0; i < count; ++i) {
|
|
|
fa009d |
handler->tracks.push_back(new TTrack(track));
|
|
|
fa009d |
TTrack &subTrack = *handler->tracks.back();
|
|
|
fa009d |
new Interpolator(subTrack, i*2*M_PI/(double)count, radius, 0.25);
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
}
|
|
|
fa009d |
|
|
|
fa009d |
Handler *handler = dynamic_cast<handler*>(track.handler.getPointer());</handler*>
|
|
|
fa009d |
if (!handler)
|
|
|
fa009d |
return TInputModifier::modifyTrack(track, outTracks);
|
|
|
fa009d |
|
|
|
fa009d |
outTracks.insert(outTracks.end(), handler->tracks.begin(), handler->tracks.end());
|
|
|
fa009d |
if (!track.changed())
|
|
|
7e9eb1 |
return;
|
|
|
7e9eb1 |
|
|
|
fa009d |
double radius = handler->radius;
|
|
|
c3c215 |
int start = track.size() - track.pointsAdded;
|
|
|
7e9eb1 |
if (start < 0) start = 0;
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// remove angles
|
|
|
fa009d |
handler->angles.resize(start);
|
|
|
fa009d |
|
|
|
7e9eb1 |
// add angles
|
|
|
fa009d |
for(int i = start; i < track.size(); ++i) {
|
|
|
fa009d |
if (i) {
|
|
|
fa009d |
const TTrackPoint &p0 = track[i - 1];
|
|
|
fa009d |
const TTrackPoint &p1 = track[i];
|
|
|
fa009d |
double dl = p1.length - p0.length;
|
|
|
fa009d |
double da = p1.pressure > TConsts::epsilon
|
|
|
fa009d |
? dl / (radius * p1.pressure)
|
|
|
fa009d |
: 0.0;
|
|
|
fa009d |
handler->angles.push_back(handler->angles.back() + da);
|
|
|
7e9eb1 |
} else {
|
|
|
7e9eb1 |
handler->angles.push_back(0.0);
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
}
|
|
|
fa009d |
|
|
|
7e9eb1 |
// process sub-tracks
|
|
|
fa009d |
for(TTrackList::const_iterator ti = handler->tracks.begin(); ti != handler->tracks.end(); ++ti) {
|
|
|
fa009d |
TTrack &subTrack = **ti;
|
|
|
fa009d |
Interpolator *intr = dynamic_cast<interpolator*>(subTrack.getInterpolator().getPointer());</interpolator*>
|
|
|
fa009d |
if (!intr)
|
|
|
fa009d |
continue;
|
|
|
fa009d |
|
|
|
9f0c16 |
double currentSegmentSize = segmentSize;
|
|
|
fa009d |
if (fabs(intr->speed) > TConsts::epsilon)
|
|
|
fa009d |
currentSegmentSize /= fabs(intr->speed);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// remove points
|
|
|
fa009d |
int subStart = start > 0
|
|
|
fa009d |
? subTrack.floorIndex(subTrack.indexByOriginalIndex(start - 1)) + 1
|
|
|
fa009d |
: 0;
|
|
|
00337d |
subTrack.truncate(subStart);
|
|
|
7e9eb1 |
|
|
|
7e9eb1 |
// add points
|
|
shun-iwasawa |
ec85ad |
for (int i = start; i < track.size(); ++i) {
|
|
|
7e9eb1 |
if (i > 0) {
|
|
shun-iwasawa |
ec85ad |
double prevAngle = handler->angles[i - 1];
|
|
|
7e9eb1 |
double nextAngle = handler->angles[i];
|
|
shun-iwasawa |
ec85ad |
if (fabs(nextAngle - prevAngle) > 1.5 * currentSegmentSize) {
|
|
shun-iwasawa |
ec85ad |
double step = currentSegmentSize / fabs(nextAngle - prevAngle);
|
|
shun-iwasawa |
ec85ad |
double end = 1.0 - 0.5 * step;
|
|
shun-iwasawa |
ec85ad |
for (double frac = step; frac < end; frac += step)
|
|
shun-iwasawa |
ec85ad |
subTrack.push_back(
|
|
|
fa009d |
intr->interpolateFromOriginal(i - 1 + frac), false );
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
}
|
|
|
fa009d |
subTrack.push_back(intr->interpolateFromOriginal(i), false);
|
|
|
7e9eb1 |
}
|
|
|
f278a5 |
|
|
|
f278a5 |
// fix points
|
|
|
fa009d |
if (track.fixedFinished())
|
|
|
fa009d |
subTrack.fix_all();
|
|
|
f278a5 |
if (track.fixedSize())
|
|
|
f278a5 |
subTrack.fix_to(
|
|
|
f278a5 |
subTrack.floorIndex(subTrack.indexByOriginalIndex(track.fixedSize() - 1)) + 1 );
|
|
|
7e9eb1 |
}
|
|
|
fa009d |
|
|
|
00337d |
track.resetChanges();
|
|
|
7e9eb1 |
}
|
|
|
7e9eb1 |
|
|
|
f278a5 |
#endif
|