diff --git a/Plugins/ZShell/Blobs/blobgroup.cpp b/Plugins/ZShell/Blobs/blobgroup.cpp index e77cf05..62eef10 100644 --- a/Plugins/ZShell/Blobs/blobgroup.cpp +++ b/Plugins/ZShell/Blobs/blobgroup.cpp @@ -85,6 +85,8 @@ void BlobGroup::markShapeDirty(BlobShape* source) { const QRectF otherRect(static_cast(shape->m_cachedPaddedX), static_cast(shape->m_cachedPaddedY), static_cast(shape->m_cachedPaddedW), static_cast(shape->m_cachedPaddedH)); if (srcRect.intersects(otherRect)) { + shape->setExpandedRect(srcRect); + shape->m_hasExpandedRect = true; shape->polish(); shape->update(); } diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index d872714..69d9ea6 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -69,26 +69,6 @@ void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeome QQuickItem::geometryChange(newGeometry, oldGeometry); updateCenteredDeformMatrix(); if (m_group) { - // Update cached values so markShapeDirty uses current geometry - const QPointF scenePos = mapToScene(QPointF(0, 0)); - if (isInvertedRect()) { - m_cachedPaddedX = static_cast(scenePos.x()); - m_cachedPaddedY = static_cast(scenePos.y()); - m_cachedPaddedW = static_cast(width()); - m_cachedPaddedH = static_cast(height()); - m_localPaddedRect = QRectF(0, 0, width(), height()); - } else { - const float hw = static_cast(width()) * 0.5f; - const float hh = static_cast(height()) * 0.5f; - const float totalPad = static_cast(m_group->smoothing()) + deformPadding(m_deformMatrix, hw, hh); - m_cachedPaddedX = static_cast(scenePos.x()) - totalPad; - m_cachedPaddedY = static_cast(scenePos.y()) - totalPad; - m_cachedPaddedW = static_cast(width()) + 2.0f * totalPad; - m_cachedPaddedH = static_cast(height()) + 2.0f * totalPad; - m_localPaddedRect = QRectF(static_cast(-totalPad), static_cast(-totalPad), - width() + 2.0 * static_cast(totalPad), height() + 2.0 * static_cast(totalPad)); - } - // Accumulate sub-pixel drift so slow movements don't desync the shader m_pendingDx += static_cast(newGeometry.x() - oldGeometry.x()); m_pendingDy += static_cast(newGeometry.y() - oldGeometry.y()); @@ -138,6 +118,8 @@ void BlobShape::updatePolish() { if (!m_group) return; + m_hasExpandedRect = false; + // Ensure all shapes have up-to-date physics (only once per frame) m_group->ensurePhysicsUpdated(); @@ -186,18 +168,20 @@ void BlobShape::updatePolish() { const QPointF otherScene = other->mapToScene(QPointF(0, 0)); - bool include = false; - if (isInvertedRect()) { - include = true; - } else { - const float otherHW = static_cast(other->width()) * 0.5f; - const float otherHH = static_cast(other->height()) * 0.5f; - const float otherPad = pad + deformPadding(other->m_deformMatrix, otherHW, otherHH); - const QRectF otherPadded(otherScene.x() - static_cast(otherPad), - otherScene.y() - static_cast(otherPad), other->width() + 2.0 * static_cast(otherPad), - other->height() + 2.0 * static_cast(otherPad)); - include = myPadded.intersects(otherPadded); - } +bool include = false; + if (isInvertedRect()) { + include = true; + } else if (m_hasExpandedRect) { + include = m_expandedRect.intersects(otherPadded); + } else { + const float otherHW = static_cast(other->width()) * 0.5f; + const float otherHH = static_cast(other->height()) * 0.5f; + const float otherPad = pad + deformPadding(other->m_deformMatrix, otherHW, otherHH); + const QRectF otherPadded(otherScene.x() - static_cast(otherPad), + otherScene.y() - static_cast(otherPad), other->width() + 2.0 * static_cast(otherPad), + other->height() + 2.0 * static_cast(otherPad)); + include = myPadded.intersects(otherPadded); + } if (include) { if (other == this) diff --git a/Plugins/ZShell/Blobs/blobshape.hpp b/Plugins/ZShell/Blobs/blobshape.hpp index aa1d018..02c18c7 100644 --- a/Plugins/ZShell/Blobs/blobshape.hpp +++ b/Plugins/ZShell/Blobs/blobshape.hpp @@ -67,10 +67,20 @@ virtual void updatePhysics() { } virtual void registerWithGroup(); -virtual void unregisterFromGroup(); -void updateCenteredDeformMatrix(); + virtual void unregisterFromGroup(); + void updateCenteredDeformMatrix(); -BlobGroup* m_group = nullptr; + void setExpandedRect(const QRectF& rect) { + m_expandedRect = rect; + } + const QRectF& expandedRect() const { + return m_expandedRect; + } + bool hasExpandedRect() const { + return m_hasExpandedRect; + } + + BlobGroup* m_group = nullptr; qreal m_radius = 0; QMatrix4x4 m_deformMatrix; // identity by default QMatrix4x4 m_centeredDeformMatrix; @@ -88,5 +98,8 @@ float m_pendingDy = 0; bool m_cachedHasInverted = false; float m_cachedInvertedRadius = 0; float m_cachedInvertedOuter[4] = {}; -float m_cachedInvertedInner[4] = {}; + float m_cachedInvertedInner[4] = {}; + + QRectF m_expandedRect; + bool m_hasExpandedRect = false; };