Skip to content

Commit 38bea0d

Browse files
authored
Merge pull request #134 from scratchcpp/touching_cpu_texture
Use CPU texture in contains methods
2 parents 748d9b8 + 934d23a commit 38bea0d

File tree

5 files changed

+72
-26
lines changed

5 files changed

+72
-26
lines changed

src/cputexturemanager.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ const std::vector<QPoint> &CpuTextureManager::getTextureConvexHullPoints(const T
5151
return it->second;
5252
}
5353

54+
bool CpuTextureManager::textureContainsPoint(const Texture &texture, const QPointF &localPoint)
55+
{
56+
// https://github.com/scratchfoundation/scratch-render/blob/7b823985bc6fe92f572cc3276a8915e550f7c5e6/src/Silhouette.js#L219-L226
57+
return getPointAlpha(texture, localPoint.x(), localPoint.y()) > 0;
58+
}
59+
5460
void CpuTextureManager::removeTexture(const Texture &texture)
5561
{
5662
if (!texture.isValid())
@@ -131,3 +137,12 @@ bool CpuTextureManager::addTexture(const Texture &texture)
131137

132138
return true;
133139
}
140+
141+
int CpuTextureManager::getPointAlpha(const Texture &texture, int x, int y)
142+
{
143+
if ((x < 0 || x >= texture.width()) || (y < 0 || y >= texture.height()))
144+
return 0;
145+
146+
GLubyte *pixels = getTextureData(texture);
147+
return pixels[(y * texture.width() + x) * 4 + 3];
148+
}

src/cputexturemanager.h

+3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ class CpuTextureManager
2020
GLubyte *getTextureData(const Texture &texture);
2121
const std::vector<QPoint> &getTextureConvexHullPoints(const Texture &texture);
2222

23+
bool textureContainsPoint(const Texture &texture, const QPointF &localPoint);
24+
2325
void removeTexture(const Texture &texture);
2426

2527
private:
2628
bool addTexture(const Texture &texture);
29+
int getPointAlpha(const Texture &texture, int x, int y);
2730

2831
std::unordered_map<GLuint, GLubyte *> m_textureData;
2932
std::unordered_map<GLuint, std::vector<QPoint>> m_convexHullPoints;

src/renderedtarget.cpp

+1-14
Original file line numberDiff line numberDiff line change
@@ -814,20 +814,7 @@ void RenderedTarget::updateHullPoints()
814814

815815
bool RenderedTarget::containsLocalPoint(const QPointF &point) const
816816
{
817-
if (!boundingRect().contains(point))
818-
return false;
819-
820-
const std::vector<QPoint> &points = hullPoints();
821-
QPoint intPoint = point.toPoint();
822-
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()); });
823-
824-
if (it == points.end()) {
825-
// The point is beyond the last point in the convex hull
826-
return false;
827-
}
828-
829-
// Check if the point is equal to the one found
830-
return *it == intPoint;
817+
return textureManager()->textureContainsPoint(m_cpuTexture, point);
831818
}
832819

833820
QPointF RenderedTarget::transformPoint(double scratchX, double scratchY, double originX, double originY, double rot) const

test/renderedtarget/renderedtarget_test.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,12 @@ TEST_F(RenderedTargetTest, CpuRendering)
394394
ASSERT_TRUE(target.contains({ 1, 2 }));
395395
ASSERT_FALSE(target.contains({ 2, 2 }));
396396
ASSERT_TRUE(target.contains({ 3, 2 }));
397-
ASSERT_FALSE(target.contains({ 3.5, 2.1 }));
397+
ASSERT_TRUE(target.contains({ 3.5, 2.1 }));
398398

399399
ASSERT_TRUE(target.contains({ 1, 3 }));
400400
ASSERT_TRUE(target.contains({ 2, 3 }));
401401
ASSERT_TRUE(target.contains({ 3, 3 }));
402-
ASSERT_FALSE(target.contains({ 3.3, 3.5 }));
402+
ASSERT_TRUE(target.contains({ 3.3, 3.5 }));
403403

404404
// Test contains() with horizontal mirroring
405405
target.updateRotationStyle(Sprite::RotationStyle::LeftRight);
@@ -408,9 +408,9 @@ TEST_F(RenderedTargetTest, CpuRendering)
408408
ASSERT_TRUE(target.contains({ -1, 1 }));
409409
ASSERT_FALSE(target.contains({ -2, 2 }));
410410
ASSERT_TRUE(target.contains({ -3, 2 }));
411-
ASSERT_FALSE(target.contains({ -3.5, 2.1 }));
411+
ASSERT_TRUE(target.contains({ -3.5, 2.1 }));
412412
ASSERT_TRUE(target.contains({ -2, 3 }));
413-
ASSERT_FALSE(target.contains({ -3.3, 3.5 }));
413+
ASSERT_TRUE(target.contains({ -3.3, 3.5 }));
414414

415415
// Test containsScratchPoint()
416416
target.updateDirection(0);
@@ -425,15 +425,15 @@ TEST_F(RenderedTargetTest, CpuRendering)
425425
ASSERT_TRUE(target.containsScratchPoint(-226, 164)); // [2, 1]
426426
ASSERT_TRUE(target.containsScratchPoint(-225, 164)); // [3, 1]
427427

428-
ASSERT_TRUE(target.containsScratchPoint(-227, 163)); // [1, 2]
429-
ASSERT_FALSE(target.containsScratchPoint(-226, 163)); // [2, 2]
430-
ASSERT_TRUE(target.containsScratchPoint(-225, 163)); // [3, 2]
431-
ASSERT_FALSE(target.containsScratchPoint(-224.5, 162.9)); // [3.5, 2.1]
428+
ASSERT_TRUE(target.containsScratchPoint(-227, 163)); // [1, 2]
429+
ASSERT_FALSE(target.containsScratchPoint(-226, 163)); // [2, 2]
430+
ASSERT_TRUE(target.containsScratchPoint(-225, 163)); // [3, 2]
431+
ASSERT_TRUE(target.containsScratchPoint(-224.5, 162.9)); // [3.5, 2.1]
432432

433-
ASSERT_TRUE(target.containsScratchPoint(-227, 162)); // [1, 3]
434-
ASSERT_TRUE(target.containsScratchPoint(-226, 162)); // [2, 3]
435-
ASSERT_TRUE(target.containsScratchPoint(-225, 162)); // [3, 3]
436-
ASSERT_FALSE(target.containsScratchPoint(-224.7, 161.5)); // [3.3, 3.5]
433+
ASSERT_TRUE(target.containsScratchPoint(-227, 162)); // [1, 3]
434+
ASSERT_TRUE(target.containsScratchPoint(-226, 162)); // [2, 3]
435+
ASSERT_TRUE(target.containsScratchPoint(-225, 162)); // [3, 3]
436+
ASSERT_TRUE(target.containsScratchPoint(-224.7, 161.5)); // [3.3, 3.5]
437437

438438
// Test colorAtScratchPoint()
439439
ASSERT_EQ(target.colorAtScratchPoint(-228, 165), 0); // [0, 0]

test/texture/cputexturemanager_test.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,44 @@ TEST_F(CpuTextureManagerTest, TextureDataAndHullPoints)
129129
// Cleanup
130130
context.doneCurrent();
131131
}
132+
133+
TEST_F(CpuTextureManagerTest, TextureContainsPoint)
134+
{
135+
// Create OpenGL context
136+
QOpenGLContext context;
137+
QOffscreenSurface surface;
138+
createContextAndSurface(&context, &surface);
139+
140+
// Paint
141+
QNanoPainter painter;
142+
ImagePainter imgPainter(&painter, "image.png");
143+
144+
// Read texture data
145+
Texture texture(imgPainter.fbo()->texture(), imgPainter.fbo()->size());
146+
147+
// Test
148+
CpuTextureManager manager;
149+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 0, 0 }));
150+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 1, 0 }));
151+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 2, 0 }));
152+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 3, 0 }));
153+
154+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 0, 1 }));
155+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 1, 1 }));
156+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 1.4, 1.25 }));
157+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 2, 1 }));
158+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 3, 1 }));
159+
160+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 1, 2 }));
161+
ASSERT_FALSE(manager.textureContainsPoint(texture, { 2, 2 }));
162+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 3, 2 }));
163+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 3.5, 2.1 }));
164+
165+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 1, 3 }));
166+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 2, 3 }));
167+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 3, 3 }));
168+
ASSERT_TRUE(manager.textureContainsPoint(texture, { 3.3, 3.5 }));
169+
170+
// Cleanup
171+
context.doneCurrent();
172+
}

0 commit comments

Comments
 (0)