Skip to content

Commit

Permalink
Fix perspective overlays not always covering the entire view (#1790)
Browse files Browse the repository at this point in the history
* Fix perspective overlays not always covering the entire view

* Fix perspective overlays with active canvas rotation
  • Loading branch information
J5lx authored Oct 1, 2023
1 parent d3be339 commit 58eb218
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 132 deletions.
3 changes: 1 addition & 2 deletions core_lib/src/canvaspainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,8 @@ void CanvasPainter::renderPostLayers(QPainter& painter, const QRect& blitRect)
}
}

void CanvasPainter::setPaintSettings(const Object* object, int currentLayer, int frame, QRect rect, TiledBuffer* tiledBuffer)
void CanvasPainter::setPaintSettings(const Object* object, int currentLayer, int frame, TiledBuffer* tiledBuffer)
{
Q_UNUSED(rect)
Q_ASSERT(object);
mObject = object;

Expand Down
2 changes: 1 addition & 1 deletion core_lib/src/canvaspainter.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class CanvasPainter
void setTransformedSelection(QRect selection, QTransform transform);
void ignoreTransformedSelection();

void setPaintSettings(const Object* object, int currentLayer, int frame, QRect rect, TiledBuffer* tilledBuffer);
void setPaintSettings(const Object* object, int currentLayer, int frame, TiledBuffer* tilledBuffer);
void paint(const QRect& blitRect);
void paintCached(const QRect& blitRect);
void resetLayerCache();
Expand Down
10 changes: 5 additions & 5 deletions core_lib/src/interface/scribblearea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ void ScribbleArea::paintEvent(QPaintEvent* event)
}
else
{
prepCanvas(currentFrame, event->rect());
prepCanvas(currentFrame);
prepCameraPainter(currentFrame);
prepOverlays(currentFrame);

Expand Down Expand Up @@ -1118,7 +1118,7 @@ void ScribbleArea::paintEvent(QPaintEvent* event)

paintCanvasCursor(painter);

mOverlayPainter.paint(painter);
mOverlayPainter.paint(painter, rect());

// paints the selection outline
if (mEditor->select()->somethingSelected())
Expand Down Expand Up @@ -1196,7 +1196,7 @@ void ScribbleArea::prepCameraPainter(int frame)
mCameraPainter.setOnionSkinPainterOptions(onionSkinOptions);
}

void ScribbleArea::prepCanvas(int frame, QRect rect)
void ScribbleArea::prepCanvas(int frame)
{
Object* object = mEditor->object();

Expand Down Expand Up @@ -1231,12 +1231,12 @@ void ScribbleArea::prepCanvas(int frame, QRect rect)
mCanvasPainter.setViewTransform(vm->getView(), vm->getViewInverse());
mCanvasPainter.setTransformedSelection(sm->mySelectionRect().toRect(), sm->selectionTransform());

mCanvasPainter.setPaintSettings(object, mEditor->layers()->currentLayerIndex(), frame, rect, &mTiledBuffer);
mCanvasPainter.setPaintSettings(object, mEditor->layers()->currentLayerIndex(), frame, &mTiledBuffer);
}

void ScribbleArea::drawCanvas(int frame, QRect rect)
{
prepCanvas(frame, rect);
prepCanvas(frame);
prepCameraPainter(frame);
prepOverlays(frame);
mCanvasPainter.paint(rect);
Expand Down
2 changes: 1 addition & 1 deletion core_lib/src/interface/scribblearea.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public slots:

void prepOverlays(int frame);
void prepCameraPainter(int frame);
void prepCanvas(int frame, QRect rect);
void prepCanvas(int frame);
void drawCanvas(int frame, QRect rect);
void settingUpdated(SETTING setting);
void paintSelectionVisuals(QPainter &painter);
Expand Down
134 changes: 44 additions & 90 deletions core_lib/src/overlaypainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include "layercamera.h"
#include "camera.h"
#include "layer.h"
#include "util.h"

Q_CONSTEXPR static qreal LINELENGTHFACTOR = 2.0;
Q_CONSTEXPR static int LEFTANGLEOFFSET = 90;
Q_CONSTEXPR static int RIGHTANGLEOFFSET = -90;
Q_CONSTEXPR static int LEFT_ANGLE_OFFSET = 90;
Q_CONSTEXPR static int RIGHT_ANGLE_OFFSET = -90;
Q_CONSTEXPR static int HANDLE_WIDTH = 12;

OverlayPainter::OverlayPainter()
Expand All @@ -33,7 +33,7 @@ void OverlayPainter::setViewTransform(const QTransform view)
mViewTransform = view;
}

void OverlayPainter::paint(QPainter &painter)
void OverlayPainter::paint(QPainter &painter, const QRect& viewport)
{
if (mCameraLayer == nullptr) { return; }

Expand Down Expand Up @@ -65,17 +65,18 @@ void OverlayPainter::paint(QPainter &painter)
paintOverlaySafeAreas(painter, *camera, camTransform, cameraRect);
}

const QRect mappedViewport = mViewTransform.inverted().mapRect(viewport);
if (mOptions.bPerspective1)
{
paintOverlayPerspectiveOnePoint(painter, camTransform, cameraRect);
paintOverlayPerspectiveOnePoint(painter, mappedViewport, camTransform);
}
if (mOptions.bPerspective2)
if (mOptions.bPerspective2 || mOptions.bPerspective3)
{
paintOverlayPerspectiveTwoPoints(painter, *camera, camTransform, cameraRect);
paintOverlayPerspectiveTwoPoints(painter, mappedViewport, *camera, camTransform);
}
if (mOptions.bPerspective3)
{
paintOverlayPerspectiveThreePoints(painter, *camera, camTransform, cameraRect);
paintOverlayPerspectiveThreePoints(painter, mappedViewport, *camera, camTransform);
}

if (mOptions.bGrid)
Expand Down Expand Up @@ -211,7 +212,7 @@ void OverlayPainter::paintOverlaySafeAreas(QPainter &painter, const Camera& came

QTransform t = scale.inverted() * rot * trans;
painter.setTransform(t, true);
painter.drawText(QPoint(), QObject::tr("Safe Action area %1 %").arg(action));
painter.drawText(QPoint(), tr("Safe Action area %1 %").arg(action));
painter.restore();
}
}
Expand All @@ -238,103 +239,71 @@ void OverlayPainter::paintOverlaySafeAreas(QPainter &painter, const Camera& came

QTransform t = scale.inverted() * rot * trans;
painter.setTransform(t, true);
painter.drawText(QPoint(), QObject::tr("Safe Title area %1 %").arg(title));
painter.drawText(QPoint(), tr("Safe Title area %1 %").arg(title));
painter.restore();
}
}
painter.restore();
}

void OverlayPainter::paintOverlayPerspectiveOnePoint(QPainter& painter, const QTransform& camTransform, const QRect& camRect) const
void OverlayPainter::paintOverlayPerspectiveOnePoint(QPainter& painter, const QRect& viewport, const QTransform& camTransform) const
{
painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);

qreal degrees = static_cast<qreal>(mOptions.nOverlayAngle);
if (degrees == 7.0) { degrees = 7.5; }
int repeats = static_cast<int>(360 / degrees);
QLineF angleLine;

QPointF singlePoint = camTransform.inverted().map(mOptions.mSinglePerspPoint);
if (singlePoint == QPointF(0, 0))
{
// TODO: bug in Qt prevents points from being (0,0)...
singlePoint = QPointF(0.1, 0.1);
}
QLineF angleLine(singlePoint.x(), singlePoint.y(), singlePoint.x() + 1, singlePoint.y());

angleLine.setP1(singlePoint);
QVector<QLineF> lines;
for (int i = 0; i < repeats; i++)
for (qreal angle = 0; angle < 180; angle += degrees)
{
angleLine.setAngle(i * degrees);
angleLine.setLength(camRect.width() * 2.0);
lines.append(angleLine);
angleLine.setAngle(angle);
lines.append(clipLine(angleLine, viewport, -qInf(), qInf()));
}
painter.drawLines(lines);

painter.setWorldMatrixEnabled(false);

singlePoint = mViewTransform.map(singlePoint);
painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawLines(lines);

if (mOptions.bShowHandle) {
singlePoint = mViewTransform.map(singlePoint);
painter.setWorldMatrixEnabled(false);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setPen(mPalette.color(QPalette::HighlightedText));
painter.setBrush(mPalette.color(QPalette::Highlight));
painter.drawEllipse(QRectF(singlePoint.x()-HANDLE_WIDTH*.5, singlePoint.y()-HANDLE_WIDTH*.5, HANDLE_WIDTH, HANDLE_WIDTH));
}

painter.restore();

}

void OverlayPainter::paintOverlayPerspectiveTwoPoints(QPainter& painter, const Camera& camera, const QTransform& camTransform, const QRect& camRect) const
void OverlayPainter::paintOverlayPerspectiveTwoPoints(QPainter& painter, const QRect& viewport, const Camera& camera, const QTransform& camTransform) const
{
painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);

qreal degrees = static_cast<qreal>(mOptions.nOverlayAngle);
if (degrees == 7.0) { degrees = 7.5; }
int repeats = static_cast<int>(180 / degrees);

QPointF leftPoint = camTransform.inverted().map(mOptions.mLeftPerspPoint);
QPointF rightPoint = camTransform.inverted().map(mOptions.mRightPerspPoint);
if (leftPoint == QPointF(0.0, 0.0))
{
// TODO: bug in Qt prevents points from being (0,0)...
leftPoint = QPointF(0.1, 0.1);
}
QLineF angleLineLeft(leftPoint.x(), leftPoint.y(), leftPoint.x() + 1, leftPoint.y());
QLineF angleLineRight(rightPoint.x(), rightPoint.y(), rightPoint.x() + 1, rightPoint.y());

if (rightPoint == QPointF(0.0, 0.0))
{
// TODO: bug in Qt prevents points from being (0,0)...
rightPoint = QPointF(0.1, 0.1);
}

QLineF angleLineLeft;
QLineF angleLineRight;
angleLineLeft.setAngle(LEFTANGLEOFFSET);
angleLineLeft.setP1(leftPoint);
angleLineLeft.setLength(camRect.width() * LINELENGTHFACTOR);
angleLineRight.setAngle(RIGHTANGLEOFFSET);
angleLineRight.setP1(rightPoint);
angleLineRight.setLength(camRect.width() * LINELENGTHFACTOR);
QVector<QLineF> lines;
for (int i = 0; i <= repeats; i++)
for (qreal angle = 0; angle <= 180; angle += degrees)
{
angleLineLeft.setAngle((LEFTANGLEOFFSET - i * degrees) + camera.rotation());
angleLineRight.setAngle((RIGHTANGLEOFFSET - i * degrees) + camera.rotation());
lines.append(angleLineRight);
lines.append(angleLineLeft);
angleLineLeft.setAngle(LEFT_ANGLE_OFFSET - angle + camera.rotation());
angleLineRight.setAngle(RIGHT_ANGLE_OFFSET - angle + camera.rotation());
lines.append(clipLine(angleLineLeft, viewport, 0, qInf()));
lines.append(clipLine(angleLineRight, viewport, 0, qInf()));
}

painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawLines(lines);

painter.setWorldMatrixEnabled(false);

leftPoint = mViewTransform.map(leftPoint);
rightPoint = mViewTransform.map(rightPoint);

if (mOptions.bShowHandle) {
leftPoint = mViewTransform.map(leftPoint);
rightPoint = mViewTransform.map(rightPoint);
painter.setWorldMatrixEnabled(false);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setPen(mPalette.color(QPalette::HighlightedText));
painter.setBrush(mPalette.color(QPalette::Highlight));
Expand All @@ -345,44 +314,29 @@ void OverlayPainter::paintOverlayPerspectiveTwoPoints(QPainter& painter, const C
painter.restore();
}

void OverlayPainter::paintOverlayPerspectiveThreePoints(QPainter& painter, const Camera& camera, const QTransform& camTransform, const QRect& camRect) const
void OverlayPainter::paintOverlayPerspectiveThreePoints(QPainter& painter, const QRect& viewport, const Camera& camera, const QTransform& camTransform) const
{
if (!mOptions.bPerspective2)
paintOverlayPerspectiveTwoPoints(painter, camera, camTransform, camRect);

painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);

qreal degrees = static_cast<qreal>(mOptions.nOverlayAngle);
if (degrees == 7.0) { degrees = 7.5; }
int repeats = static_cast<int>(180 / degrees);

QPointF middlePoint = camTransform.inverted().map(mOptions.mMiddlePerspPoint);
if (middlePoint == QPointF(0.0, 0.0))
{
// TODO: bug in Qt prevents points from being (0,0)...
middlePoint = QPointF(0.1, 0.1);
}
QLineF angleLine(middlePoint.x(), middlePoint.y(), middlePoint.x() + 1, middlePoint.y());

const int middleAngleOffset = mOptions.mLeftPerspPoint.y() < mOptions.mMiddlePerspPoint.y() ? 180 : 0;

QLineF angleLine;
angleLine.setAngle(middleAngleOffset);
angleLine.setP1(middlePoint);
angleLine.setLength(camRect.width() * LINELENGTHFACTOR);
QVector<QLineF> lines;
for (int i = 0; i <= repeats; i++)
for (qreal angle = 0; angle <= 180; angle += degrees)
{
angleLine.setAngle((middleAngleOffset - i * degrees) + camera.rotation());
lines.append(angleLine);
angleLine.setAngle(middleAngleOffset - angle + camera.rotation());
lines.append(clipLine(angleLine, viewport, 0, qInf()));
}
painter.drawLines(lines);

painter.setWorldMatrixEnabled(false);

middlePoint = mViewTransform.map(middlePoint);
painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawLines(lines);

if (mOptions.bShowHandle) {
middlePoint = mViewTransform.map(middlePoint);
painter.setWorldMatrixEnabled(false);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setPen(mPalette.color(QPalette::HighlightedText));
painter.setBrush(mPalette.color(QPalette::Highlight));
Expand Down
10 changes: 4 additions & 6 deletions core_lib/src/overlaypainter.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ struct OverlayPainterOptions
QPointF mLeftPerspPoint;
QPointF mRightPerspPoint;
QPointF mMiddlePerspPoint;

QPainter::CompositionMode cmBufferBlendMode = QPainter::CompositionMode_SourceOver;
};

class OverlayPainter
Expand All @@ -47,7 +45,7 @@ class OverlayPainter

void preparePainter(const LayerCamera* cameraLayer, const QPalette& palette);

void paint(QPainter& painter);
void paint(QPainter& painter, const QRect& viewport);
private:
void initializePainter(QPainter& painter);

Expand All @@ -56,9 +54,9 @@ class OverlayPainter
void paintOverlayThirds(QPainter& painter, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlayGolden(QPainter& painter, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlaySafeAreas(QPainter& painter, const Camera& camera, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlayPerspectiveOnePoint(QPainter& painter, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlayPerspectiveTwoPoints(QPainter& painter, const Camera& camera, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlayPerspectiveThreePoints(QPainter& painter, const Camera& camera, const QTransform& camTransform, const QRect& camRect) const;
void paintOverlayPerspectiveOnePoint(QPainter& painter, const QRect& viewport, const QTransform& camTransform) const;
void paintOverlayPerspectiveTwoPoints(QPainter& painter, const QRect& viewport, const Camera& camera, const QTransform& camTransform) const;
void paintOverlayPerspectiveThreePoints(QPainter& painter, const QRect& viewport, const Camera& camera, const QTransform& camTransform) const;

int round100(double f, int gridSize) const;

Expand Down
Loading

0 comments on commit 58eb218

Please sign in to comment.