| |
| |
| #include <tools/modifiers/modifiersmooth.h> |
| #include <algorithm> |
| |
| |
| |
| |
| |
| |
| |
| TModifierSmooth::Modifier::Modifier(TTrackHandler &handler, int radius): |
| TTrackModifier(handler), |
| radius(std::max(radius, 0)), |
| smoothedTrack() |
| { } |
| |
| |
| TTrackPoint |
| TModifierSmooth::Modifier::calcPoint(double originalIndex) { |
| return smoothedTrack |
| ? smoothedTrack->interpolateLinear(originalIndex) |
| : TTrackModifier::calcPoint(originalIndex); |
| } |
| |
| |
| |
| |
| |
| |
| |
| TModifierSmooth::TModifierSmooth(int radius): m_radius() |
| { setRadius(radius); } |
| |
| |
| void |
| TModifierSmooth::setRadius(int radius) |
| { m_radius = std::max(0, radius); } |
| |
| |
| void |
| TModifierSmooth::modifyTrack( |
| const TTrack &track, |
| TTrackList &outTracks ) |
| { |
| if (!m_radius) { |
| TInputModifier::modifyTrack(track, outTracks); |
| return; |
| } |
| |
| if (!track.handler) { |
| track.handler = new TTrackHandler(track); |
| Modifier *modifier = new Modifier(*track.handler, m_radius); |
| modifier->smoothedTrack = new TTrack(modifier); |
| track.handler->tracks.push_back(modifier->smoothedTrack); |
| } |
| |
| if (track.handler->tracks.empty()) |
| return; |
| |
| TTrack &subTrack = *track.handler->tracks.front(); |
| outTracks.push_back(track.handler->tracks.front()); |
| |
| if (!track.changed()) |
| return; |
| |
| Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer()); |
| if (!modifier) |
| return; |
| int radius = modifier->radius; |
| |
| |
| int start = std::max(0, track.size() - track.pointsAdded); |
| subTrack.truncate(start); |
| |
| |
| |
| int size = track.size() + 2*radius; |
| double k = 1.0/(2*radius + 1); |
| TTrackTangent accum; |
| for(int i = start - 2*radius; i < size; ++i) { |
| |
| const TTrackPoint &p1 = track[i]; |
| accum.position += p1.position; |
| accum.pressure += p1.pressure; |
| accum.tilt += p1.tilt; |
| if (i < start) |
| continue; |
| |
| int oi = track.clampIndex(i - radius); |
| const TTrackPoint &p = track[oi]; |
| subTrack.push_back( |
| TTrackPoint( |
| accum.position*k, |
| accum.pressure*k, |
| accum.tilt*k, |
| oi, |
| p.time, |
| 0, |
| p.final ), |
| false ); |
| |
| const TTrackPoint &p0 = track[i - 2*radius]; |
| accum.position -= p0.position; |
| accum.pressure -= p0.pressure; |
| accum.tilt -= p0.tilt; |
| } |
| |
| |
| if (track.fixedFinished()) { |
| subTrack.fix_all(); |
| } else |
| if (track.fixedSize()) { |
| subTrack.fix_to(track.fixedSize()); |
| } |
| |
| track.resetChanges(); |
| } |
| |
| |