X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frotoscoping%2Frotowidget.cpp;h=abfef3dd819f7986779c822d25141e238b487f95;hb=2ca22f1bf89dae76745e7b046843190108a74424;hp=937116951d7c714ca40994198a0d51bb49bbea22;hpb=a4e87cef15eb4c1a7134a6a4a6af1b32a810b52c;p=kdenlive diff --git a/src/rotoscoping/rotowidget.cpp b/src/rotoscoping/rotowidget.cpp index 93711695..abfef3dd 100644 --- a/src/rotoscoping/rotowidget.cpp +++ b/src/rotoscoping/rotowidget.cpp @@ -58,6 +58,9 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode if (m_data.canConvert(QVariant::Map)) { + /* + * pass keyframe data to keyframe timeline + */ QList keyframes; QMap map = m_data.toMap(); QMap ::const_iterator i = map.constBegin(); @@ -76,6 +79,7 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode } m_data = QVariant(map); } else { + // static (only one keyframe) m_keyframeWidget->setKeyframes(QList () << 0); } @@ -137,6 +141,9 @@ void RotoWidget::slotUpdateData(int pos, bool editing) int width = m_monitor->render->frameRenderWidth(); int height = m_monitor->render->renderHeight(); + /* + * use the position of the on-monitor points to create a storable list + */ QList spline = m_item->getPoints(); QList vlist; foreach (const BPoint &point, spline) { @@ -148,6 +155,8 @@ void RotoWidget::slotUpdateData(int pos, bool editing) if (m_data.canConvert(QVariant::Map)) { QMap map = m_data.toMap(); + // replace or insert at position + // we have to fill with 0s to maintain the correct order map[QString::number((pos < 0 ? m_keyframeWidget->getPosition() : pos) + m_in).rightJustified(qRound(log10((double)m_out)), '0')] = QVariant(vlist); m_data = QVariant(map); } else { @@ -170,6 +179,7 @@ QString RotoWidget::getSpline() void RotoWidget::slotPositionChanged(int pos, bool seek) { + // do not update while the spline is being edited (points are being dragged) if (m_item->editing()) return; @@ -184,16 +194,22 @@ void RotoWidget::slotPositionChanged(int pos, bool seek) QMap ::const_iterator i = map.constBegin(); int keyframe1, keyframe2; keyframe1 = keyframe2 = i.key().toInt(); + // find keyframes next to pos while (i.key().toInt() < pos && ++i != map.constEnd()) { keyframe1 = keyframe2; keyframe2 = i.key().toInt(); } if (keyframe1 != keyframe2 && pos < keyframe2) { + /* + * in between two keyframes + * -> interpolate + */ QList p1 = getPoints(keyframe1); QList p2 = getPoints(keyframe2); qreal relPos = (pos - keyframe1) / (qreal)(keyframe2 - keyframe1 + 1); + // additionaly points are ignored (same behavior as MLT filter) int count = qMin(p1.count(), p2.count()); for (int i = 0; i < count; ++i) { BPoint bp; @@ -280,8 +296,10 @@ void RotoWidget::slotRemoveKeyframe(int pos) map.remove(QString::number(pos + m_in).rightJustified(qRound(log10((double)m_out)), '0')); m_data = QVariant(map); - if (m_data.toMap().count() == 1) + if (m_data.toMap().count() == 1) { + // only one keyframe -> switch from map to list again m_data = m_data.toMap().begin().value(); + } slotPositionChanged(m_keyframeWidget->getPosition(), false); emit valueChanged();