Commit 4b7cab76 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Fix speed smoothing algorithm not to generate blobs during the stroke

There were the following problems:

1) KisPaintingInformationBuilder::hover() geneated distance noise
   while the user was painting on screen. Now it doesn't add sample
   points when the stroke is started, only while hovering.

2) KisSpeedSmoother now has longer buffer. 10 samples was too low value
   for tablets emitting events every 7 ms. 512 should be enough for
   everyone!

3) Now there is a minimal smoothing time range. It is set to 15 ms.

BUG:363364,375360
parent fb017c98
......@@ -142,10 +142,13 @@ KisPaintInformation KisPaintingInformationBuilder::createPaintingInformation(KoP
}
KisPaintInformation KisPaintingInformationBuilder::hover(const QPointF &imagePoint,
const KoPointerEvent *event)
const KoPointerEvent *event,
bool isStrokeStarted)
{
qreal perspective = calculatePerspective(imagePoint);
qreal speed = m_speedSmoother->getNextSpeed(imageToView(imagePoint));
qreal speed = !isStrokeStarted ?
m_speedSmoother->getNextSpeed(imageToView(imagePoint)) :
m_speedSmoother->lastSpeed();
if (event) {
return KisPaintInformation::createHoveringModeInfo(imagePoint,
......
......@@ -46,7 +46,8 @@ public:
int timeElapsed);
KisPaintInformation hover(const QPointF &imagePoint,
const KoPointerEvent *event);
const KoPointerEvent *event,
bool isStrokeStarted);
qreal pressureToCurve(qreal pressure);
......
......@@ -25,8 +25,9 @@
#include "kis_debug.h"
#include "kis_global.h"
#define MAX_SMOOTH_HISTORY 10
#define MAX_SMOOTH_HISTORY 512
#define MAX_TIME_DIFF 500
#define MIN_TIME_DIFF 15
#define MAX_TRACKING_DISTANCE 300
#define MIN_TRACKING_DISTANCE 5
......@@ -73,6 +74,11 @@ KisSpeedSmoother::~KisSpeedSmoother()
{
}
qreal KisSpeedSmoother::lastSpeed() const
{
return m_d->lastSpeed;
}
qreal KisSpeedSmoother::getNextSpeed(const QPointF &pt)
{
if (m_d->lastPoint.isNull()) {
......@@ -92,22 +98,26 @@ qreal KisSpeedSmoother::getNextSpeed(const QPointF &pt)
const qreal currentTime = it->time;
qreal totalDistance = 0;
qreal startTime = currentTime;
qreal totalTime = 0.0;
int itemsSearched = 0;
for (; it != end; ++it) {
if (currentTime - it->time > MAX_TIME_DIFF) {
break;
}
itemsSearched++;
totalDistance += it->distance;
startTime = it->time;
totalTime = currentTime - it->time;
if (totalDistance > MAX_TRACKING_DISTANCE) {
break;
if (totalTime > MIN_TIME_DIFF) {
if (totalTime > MAX_TIME_DIFF) {
break;
}
if (totalDistance > MAX_TRACKING_DISTANCE) {
break;
}
}
}
qreal totalTime = currentTime - startTime;
if (totalTime > 0 && totalDistance > MIN_TRACKING_DISTANCE) {
qreal speed = totalDistance / totalTime;
......@@ -118,3 +128,12 @@ qreal KisSpeedSmoother::getNextSpeed(const QPointF &pt)
return m_d->lastSpeed;
}
void KisSpeedSmoother::clear()
{
m_d->timer.restart();
m_d->distances.clear();
m_d->distances.push_back(Private::DistancePoint(0.0, 0.0));
m_d->lastPoint = QPointF();
m_d->lastSpeed = 0.0;
}
......@@ -30,7 +30,9 @@ public:
KisSpeedSmoother();
~KisSpeedSmoother();
qreal lastSpeed() const;
qreal getNextSpeed(const QPointF &pt);
void clear();
private:
struct Private;
......
......@@ -170,7 +170,7 @@ QPainterPath KisToolFreehandHelper::paintOpOutline(const QPointF &savedCursorPos
KisPaintOpSettings::OutlineMode mode) const
{
KisPaintOpSettingsSP settings = globalSettings;
KisPaintInformation info = m_d->infoBuilder->hover(savedCursorPos, event);
KisPaintInformation info = m_d->infoBuilder->hover(savedCursorPos, event, !m_d->strokeInfos.isEmpty());
QPointF prevPoint = m_d->lastCursorPos.pushThroughHistory(savedCursorPos, currentZoom());
qreal startAngle = KisAlgebra2D::directionBetweenPoints(prevPoint, savedCursorPos, 0);
KisDistanceInformation distanceInfo(prevPoint, startAngle);
......
......@@ -138,7 +138,7 @@ bool KisLiquifyPaintHelper::endPaint(KoPointerEvent *event)
void KisLiquifyPaintHelper::hoverPaint(KoPointerEvent *event)
{
QPointF imagePoint = m_d->converter->documentToImage(event->pos());
KisPaintInformation pi = m_d->infoBuilder->hover(imagePoint, event);
KisPaintInformation pi = m_d->infoBuilder->hover(imagePoint, event, m_d->paintOp);
m_d->updatePreviousPaintInfo(pi);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment