fix: blobs now allow to be drawn in device pixels to stay sharp
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 25s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 51s
Python / verify (pull_request) Failing after 1m25s
Rust / fmt (pull_request) Successful in 39s
Rust / clippy (pull_request) Successful in 59s

This commit is contained in:
2026-10-30 01:52:33 +01:00
parent 78a9577209
commit c5608dc9b9
30 changed files with 794 additions and 435 deletions
+6 -14
View File
@@ -9,22 +9,13 @@
#include <qquickitem.h>
#include <qrect.h>
#include <qsgnode.h>
#include <qtimer.h>
#include <qvector.h>
class BlobShape2;
class BlobInvertedRect2;
// One shared valuation for a whole group, drawn by one node.
//
// The shapes here are data only: they say where the material should be. The group
// draws a single quad over everything the shader can evaluate, so a pixel cannot
// be evaluated by one shape and missed by another, and no second draw can
// disagree with the first. That is what makes overlapping shapes read as one
// surface - one value, one writer, one alpha per pixel.
struct BlobGroupData {
// The shader reads rectData[80] = 16 entries, and excludeMask is a 32-bit
// mask. The shared list is capped at 16, in group order, so the cap is the
// same list for every pixel.
static constexpr int kMaxRects = 16;
QVector<BlobRectData> rects;
@@ -32,6 +23,7 @@ struct BlobGroupData {
float invertedRadius = 0;
float invertedOuter[4] = {};
float invertedInner[4] = {};
float invertedOuterRadii[4] = {};
};
class BlobGroup2 : public QQuickItem {
@@ -91,10 +83,10 @@ class BlobGroup2 : public QQuickItem {
[[nodiscard]] const BlobGroupData& data() const { return m_data; }
// One draw per group, so a change to any shape changes the value for every
// pixel. Refresh the whole group.
void markDirty();
void requestPhysics();
signals:
void smoothingChanged();
void colorChanged();
@@ -110,6 +102,7 @@ class BlobGroup2 : public QQuickItem {
void ensurePhysicsUpdated();
void ensureDataBuilt();
void fillMaterial(BlobMaterial* material);
void pumpPhysics();
qreal m_smoothing = 32.0;
QColor m_color{0x44, 0x88, 0xff};
@@ -120,9 +113,8 @@ class BlobGroup2 : public QQuickItem {
BlobInvertedRect2* m_invertedRect = nullptr;
bool m_physicsUpdated = false;
bool m_dataBuilt = false;
QTimer m_physicsPump;
BlobGroupData m_data;
// Scene-space union of what the shader can evaluate for any shape. The node
// covers exactly this, so gaps are not possible.
QRectF m_bounds;
};