1 /*
2 SPDX-FileCopyrightText: 2018 Jean-Baptiste Mardelle <jb@kdenlive.org>
3 This file is part of Kdenlive. See www.kdenlive.org.
4 
5 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
6 */
7 
8 #include "rotohelper.hpp"
9 #include "assets/keyframes/model/keyframemodellist.hpp"
10 #include "core.h"
11 #include "gentime.h"
12 #include "monitor/monitor.h"
13 
14 #include <QSize>
15 #include <utility>
RotoHelper(Monitor * monitor,std::shared_ptr<AssetParameterModel> model,QPersistentModelIndex index,QObject * parent)16 RotoHelper::RotoHelper(Monitor *monitor, std::shared_ptr<AssetParameterModel> model, QPersistentModelIndex index, QObject *parent)
17     : KeyframeMonitorHelper(monitor, std::move(model), std::move(index), parent)
18 {
19 }
20 
slotUpdateFromMonitorData(const QVariantList & v)21 void RotoHelper::slotUpdateFromMonitorData(const QVariantList &v)
22 {
23     const QVariant res = RotoHelper::getSpline(QVariant(v), pCore->getCurrentFrameSize());
24     emit updateKeyframeData(m_indexes.first(), res);
25 }
26 
getSpline(const QVariant & value,const QSize frame)27 QVariant RotoHelper::getSpline(const QVariant &value, const QSize frame)
28 {
29     QList<BPoint> bPoints;
30     const QVariantList points = value.toList();
31     for (int i = 0; i < points.size() / 3; i++) {
32         BPoint b(points.at(3 * i).toPointF(), points.at(3 * i + 1).toPointF(), points.at(3 * i + 2).toPointF());
33         bPoints << b;
34     }
35     QList<QVariant> vlist;
36     foreach (const BPoint &point, bPoints) {
37         QList<QVariant> pl;
38         for (int i = 0; i < 3; ++i) {
39             pl << QVariant(QList<QVariant>() << QVariant(point[i].x() / frame.width()) << QVariant(point[i].y() / frame.height()));
40         }
41         vlist << QVariant(pl);
42     }
43     return vlist;
44 }
45 
refreshParams(int pos)46 void RotoHelper::refreshParams(int pos)
47 {
48     QVariantList centerPoints;
49     QVariantList controlPoints;
50     std::shared_ptr<KeyframeModelList> keyframes = m_model->getKeyframeModel();
51     if (!keyframes->isEmpty()) {
52         QVariant splineData = keyframes->getInterpolatedValue(pos, m_indexes.first());
53         QList<BPoint> p = getPoints(splineData, pCore->getCurrentFrameSize());
54         for (const auto &i : qAsConst(p)) {
55             centerPoints << QVariant(i.p);
56             controlPoints << QVariant(i.h1);
57             controlPoints << QVariant(i.h2);
58         }
59     }
60     if (m_monitor) {
61         m_monitor->setUpEffectGeometry(QRect(), centerPoints, controlPoints);
62     }
63 }
64 
getPoints(const QVariant & value,const QSize frame)65 QList<BPoint> RotoHelper::getPoints(const QVariant &value, const QSize frame)
66 {
67     QList<BPoint> points;
68     QList<QVariant> data = value.toList();
69 
70     // skip tracking flag
71     if (data.count() && data.at(0).canConvert(QVariant::String)) {
72         data.removeFirst();
73     }
74 
75     foreach (const QVariant &bpoint, data) {
76         QList<QVariant> l = bpoint.toList();
77         BPoint p;
78         for (int i = 0; i < 3; ++i) {
79             p[i] = QPointF(l.at(i).toList().at(0).toDouble() * frame.width(), l.at(i).toList().at(1).toDouble() * frame.height());
80         }
81         points << p;
82     }
83     return points;
84 }
85