Skip to content

Commit 10f535c

Browse files
committed
RenderedTarget: Optimize containsScratchPoint()
1 parent 351561f commit 10f535c

File tree

3 files changed

+41
-28
lines changed

3 files changed

+41
-28
lines changed

src/renderedtarget.cpp

+37-22
Original file line numberDiff line numberDiff line change
@@ -571,34 +571,15 @@ bool RenderedTarget::contains(const QPointF &point) const
571571
translatedPoint = mapFromStageWithOriginPoint(translatedPoint);
572572
translatedPoint /= scaleRatio;
573573

574-
if (!boundingRect().contains(translatedPoint))
575-
return false;
576-
577-
const std::vector<QPoint> &points = hullPoints();
578-
QPoint intPoint = translatedPoint.toPoint();
579-
auto it = std::lower_bound(points.begin(), points.end(), intPoint, [](const QPointF &lhs, const QPointF &rhs) { return (lhs.y() < rhs.y()) || (lhs.y() == rhs.y() && lhs.x() < rhs.x()); });
580-
581-
if (it == points.end()) {
582-
// The point is beyond the last point in the convex hull
583-
return false;
584-
}
585-
586-
// Check if the point is equal to the one found
587-
return *it == intPoint;
574+
return containsLocalPoint(translatedPoint);
588575
}
589576

590577
bool RenderedTarget::containsScratchPoint(double x, double y) const
591578
{
592-
if (!m_engine || !parentItem())
579+
if (!m_engine)
593580
return false;
594581

595-
// contains() expects item coordinates, so translate the Scratch coordinates first
596-
double stageWidth = m_engine->stageWidth();
597-
double stageHeight = m_engine->stageHeight();
598-
x = m_stageScale * (x + stageWidth / 2);
599-
y = m_stageScale * (stageHeight / 2 - y);
600-
601-
return contains(mapFromItem(parentItem(), QPointF(x, y)));
582+
return containsLocalPoint(mapFromScratchToLocal(QPointF(x, y)));
602583
}
603584

604585
bool RenderedTarget::touchingClones(const std::vector<libscratchcpp::Sprite *> &clones) const
@@ -734,6 +715,24 @@ void RenderedTarget::updateHullPoints()
734715
// TODO: Apply graphic effects (#117)
735716
}
736717

718+
bool RenderedTarget::containsLocalPoint(const QPointF &point) const
719+
{
720+
if (!boundingRect().contains(point))
721+
return false;
722+
723+
const std::vector<QPoint> &points = hullPoints();
724+
QPoint intPoint = point.toPoint();
725+
auto it = std::lower_bound(points.begin(), points.end(), intPoint, [](const QPointF &lhs, const QPointF &rhs) { return (lhs.y() < rhs.y()) || (lhs.y() == rhs.y() && lhs.x() < rhs.x()); });
726+
727+
if (it == points.end()) {
728+
// The point is beyond the last point in the convex hull
729+
return false;
730+
}
731+
732+
// Check if the point is equal to the one found
733+
return *it == intPoint;
734+
}
735+
737736
QPointF RenderedTarget::transformPoint(double scratchX, double scratchY, double originX, double originY, double rot) const
738737
{
739738
return transformPoint(scratchX, scratchY, originX, originY, std::sin(rot), std::cos(rot));
@@ -763,6 +762,22 @@ QPointF RenderedTarget::mapFromStageWithOriginPoint(const QPointF &scenePoint) c
763762
return localPoint;
764763
}
765764

765+
QPointF RenderedTarget::mapFromScratchToLocal(const QPointF &point) const
766+
{
767+
QTransform t;
768+
const double textureScale = m_skin->getTextureScale(m_cpuTexture);
769+
const double scale = m_size / textureScale;
770+
const double mirror = m_mirrorHorizontally ? -1 : 1;
771+
const double bitmapRes = m_costume->bitmapResolution();
772+
t.translate(m_costume->rotationCenterX() * textureScale, m_costume->rotationCenterY() * textureScale);
773+
t.rotate(-rotation());
774+
t.scale(bitmapRes * mirror / scale, -bitmapRes / scale);
775+
t.translate(-m_x, -m_y);
776+
777+
QPointF localPoint = t.map(point);
778+
return localPoint;
779+
}
780+
766781
CpuTextureManager *RenderedTarget::textureManager()
767782
{
768783
if (!m_textureManager)

src/renderedtarget.h

+2
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ class RenderedTarget : public IRenderedTarget
118118
void handleSceneMouseMove(qreal x, qreal y);
119119
bool convexHullPointsNeeded() const;
120120
void updateHullPoints();
121+
bool containsLocalPoint(const QPointF &point) const;
121122
QPointF transformPoint(double scratchX, double scratchY, double originX, double originY, double rot) const;
122123
QPointF transformPoint(double scratchX, double scratchY, double originX, double originY, double sinRot, double cosRot) const;
123124
QPointF mapFromStageWithOriginPoint(const QPointF &scenePoint) const;
125+
QPointF mapFromScratchToLocal(const QPointF &point) const;
124126
CpuTextureManager *textureManager();
125127
QRectF touchingBounds() const;
126128
static QRectF candidatesBounds(const QRectF &targetRect, const std::vector<libscratchcpp::Target *> &candidates, std::vector<IRenderedTarget *> &dst);

test/renderedtarget/renderedtarget_test.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ TEST_F(RenderedTargetTest, HullPoints)
328328
target.loadCostumes();
329329
target.updateCostume(costume.get());
330330
target.setStageScale(2);
331-
target.setX(25);
332-
target.setY(30);
331+
target.updateX(-227.5);
332+
target.updateY(165);
333333

334334
// Test hull points
335335
target.setWidth(3);
@@ -361,8 +361,6 @@ TEST_F(RenderedTargetTest, HullPoints)
361361
// Test contains() with horizontal mirroring
362362
target.updateRotationStyle(Sprite::RotationStyle::LeftRight);
363363
target.updateDirection(-45);
364-
target.setX(25);
365-
target.setY(30);
366364
ASSERT_FALSE(target.contains({ 0, 0 }));
367365
ASSERT_TRUE(target.contains({ -1, 1 }));
368366
ASSERT_FALSE(target.contains({ -2, 2 }));
@@ -373,8 +371,6 @@ TEST_F(RenderedTargetTest, HullPoints)
373371

374372
// Test containsScratchPoint()
375373
target.updateDirection(0);
376-
target.setX(25);
377-
target.setY(30);
378374
ASSERT_FALSE(target.containsScratchPoint(-227.5, 165)); // [0, 0]
379375
ASSERT_FALSE(target.containsScratchPoint(-226.5, 165)); // [1, 0]
380376
ASSERT_FALSE(target.containsScratchPoint(-225.5, 165)); // [2, 0]

0 commit comments

Comments
 (0)