fix: ignore stale coordinate data for panels + convert wavyline to use new qt 6.12 canvas painter api

This commit is contained in:
2026-10-12 15:54:32 +02:00
parent 3883917228
commit 255db9e533
16 changed files with 222 additions and 185 deletions
+8 -28
View File
@@ -138,11 +138,16 @@ void BlobGroup2::ensureDataBuilt() {
const double extent = static_cast<double>(smoothFactor) * 1.5 +
static_cast<double>(m_shadowRadius);
// Group order, no pruning: the shader sees this list for every pixel.
// Group order, no pruning by proximity: the shader sees this list for every pixel. A
// shape that is not pushing is not in the list at all: shapes here are data for the
// group draw, so leaving a panel at rest out means it cannot define any part of the
// edge. A closing panel is still in the list while its curve runs out, even with no
// size left, which is what keeps the bounce.
// entryShapes maps a shared entry back to the shape it came from.
QVector<BlobShape2*> entryShapes;
for (auto* shape : std::as_const(m_shapes)) {
if (!shape->isMoving()) continue;
if (shape->width() <= 0 || shape->height() <= 0) continue;
if (static_cast<int>(m_data.rects.size()) >= BlobGroupData::kMaxRects)
continue;
@@ -189,9 +194,6 @@ void BlobGroup2::ensureDataBuilt() {
const int count = static_cast<int>(m_data.rects.size());
// Which shape is the source for the bar edge.
resolveSources(entryShapes);
// Exclusion gates only the smooth blend.
for (int i = 0; i < count; ++i) {
int mask = 0;
@@ -254,8 +256,8 @@ void BlobGroup2::ensureDataBuilt() {
ri.radius[3] = std::max(ri.radius[3] * fTl, minR);
}
// Inverted rect. The frame term is evaluated for every pixel in the bounds, so the
// group flag cannot be gated per shape.
// Inverted rect. The frame term is evaluated for every pixel in the bounds,
// so the group flag cannot be gated per shape.
if (!m_invertedRect) return;
auto* inv = static_cast<BlobShape2*>(m_invertedRect);
@@ -302,28 +304,6 @@ void BlobGroup2::ensureDataBuilt() {
2.0 * (static_cast<double>(outerHH) + extent)));
}
// A point on the bar edge can only have one source. A shape that is not pushing is not
// the source: it still fills its own area, but inside the border strip it must not add
// its own outline to a span another shape is already shaping. That is the case that
// matters — one panel at rest next to one that is bouncing — where the edge showed
// several steps instead of one smooth indent of the closing panel. Only one shape can be
// pushing at a time, so the flag is just that, and the shader gates the strip with it.
void BlobGroup2::resolveSources(const QVector<BlobShape2*>& entryShapes) {
const int count = static_cast<int>(m_data.rects.size());
// With nothing pushing there is no span being shaped, so a shape at rest keeps its
// own outline and nothing is gated.
bool anyPushing = false;
for (int i = 0; i < count; ++i)
if (entryShapes[i]->isMoving()) {
anyPushing = true;
break;
}
for (int i = 0; i < count; ++i)
m_data.rects[i].source = !anyPushing || entryShapes[i]->isMoving();
}
void BlobGroup2::fillMaterial(BlobMaterial* material) {
material->m_paddedX = static_cast<float>(m_bounds.x());
material->m_paddedY = static_cast<float>(m_bounds.y());