From 115cdd268e6c3bee9527958c594e58604e30532e Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 31 Oct 2021 14:09:06 +0100 Subject: [PATCH] #5795: Only run tests in evaluateViewDependent() if the visibility of any face actually changed. This can be the case either by forcing a brush to be visible or by its material filter status. --- libs/scene/Node.h | 2 +- radiantcore/brush/BrushNode.cpp | 24 +++++++++++++++++++----- radiantcore/brush/BrushNode.h | 9 ++++++++- radiantcore/brush/Face.cpp | 9 ++++++++- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/libs/scene/Node.h b/libs/scene/Node.h index 5b5e80ea7e..16442fff27 100644 --- a/libs/scene/Node.h +++ b/libs/scene/Node.h @@ -196,7 +196,7 @@ class Node : protected: // Set the "forced visible" flag, only to be used internally by subclasses - void setForcedVisibility(bool forceVisible, bool includeChildren) override; + virtual void setForcedVisibility(bool forceVisible, bool includeChildren) override; // Method for subclasses to check whether this node is forcedly visible bool isForcedVisible() const; diff --git a/radiantcore/brush/BrushNode.cpp b/radiantcore/brush/BrushNode.cpp index f1837162cf..c61f26a834 100644 --- a/radiantcore/brush/BrushNode.cpp +++ b/radiantcore/brush/BrushNode.cpp @@ -15,6 +15,7 @@ BrushNode::BrushNode() : scene::SelectableNode(), m_brush(*this), + _faceVisibilityChanged(true), _selectedPoints(GL_POINTS), _faceCentroidPointsCulled(GL_POINTS), m_viewChanged(false), @@ -42,6 +43,7 @@ BrushNode::BrushNode(const BrushNode& other) : LitObject(other), Transformable(other), m_brush(*this, other.m_brush), + _faceVisibilityChanged(true), _selectedPoints(GL_POINTS), _faceCentroidPointsCulled(GL_POINTS), m_viewChanged(false), @@ -355,7 +357,7 @@ void BrushNode::renderComponents(RenderableCollector& collector, const VolumeTes if (volume.fill() && GlobalSelectionSystem().ComponentMode() == selection::ComponentSelectionMode::Face) { - evaluateViewDependent(volume, l2w); + updateWireframeVisibility(volume, l2w); collector.addRenderable(*m_brush.m_state_point, _faceCentroidPointsCulled, l2w); } else @@ -418,11 +420,23 @@ std::size_t BrushNode::getHighlightFlags() return isGroupMember() ? (Highlight::Selected | Highlight::GroupMember) : Highlight::Selected; } -void BrushNode::evaluateViewDependent(const VolumeTest& volume, const Matrix4& localToWorld) const +void BrushNode::onFaceVisibilityChanged() { - if (!m_viewChanged) return; + _faceVisibilityChanged = true; +} + +void BrushNode::setForcedVisibility(bool forceVisible, bool includeChildren) +{ + Node::setForcedVisibility(forceVisible, includeChildren); + + _faceVisibilityChanged = true; +} + +void BrushNode::updateWireframeVisibility(const VolumeTest& volume, const Matrix4& localToWorld) const +{ + if (!_faceVisibilityChanged) return; - m_viewChanged = false; + _faceVisibilityChanged = false; // Array of booleans to indicate which faces are visible static bool faces_visible[brush::c_brush_maxFaces]; @@ -503,7 +517,7 @@ void BrushNode::renderWireframe(RenderableCollector& collector, const VolumeTest { //renderCommon(collector, volume); - evaluateViewDependent(volume, localToWorld); + updateWireframeVisibility(volume, localToWorld); if (m_render_wireframe.m_size != 0) { diff --git a/radiantcore/brush/BrushNode.h b/radiantcore/brush/BrushNode.h index 587ba7ff85..f2d5da7d4e 100644 --- a/radiantcore/brush/BrushNode.h +++ b/radiantcore/brush/BrushNode.h @@ -42,6 +42,8 @@ class BrushNode : typedef std::vector VertexInstances; VertexInstances m_vertexInstances; + mutable bool _faceVisibilityChanged; + mutable RenderableWireframe m_render_wireframe; // Renderable array of vertex and edge points @@ -168,10 +170,15 @@ class BrushNode : // Should only be used by the internal Brush object bool facesAreForcedVisible(); + // Will be invoked if one of this brush's faces updates its visibility status + void onFaceVisibilityChanged(); + void onPostUndo() override; void onPostRedo() override; protected: + virtual void setForcedVisibility(bool forceVisible, bool includeChildren) override; + // Gets called by the Transformable implementation whenever // scale, rotation or translation is changed. void _onTransformationChanged() override; @@ -192,7 +199,7 @@ class BrushNode : const Matrix4& localToWorld) const; void renderClipPlane(RenderableCollector& collector, const VolumeTest& volume) const; - void evaluateViewDependent(const VolumeTest& volume, const Matrix4& localToWorld) const; + void updateWireframeVisibility(const VolumeTest& volume, const Matrix4& localToWorld) const; }; // class BrushNode typedef std::shared_ptr BrushNodePtr; diff --git a/radiantcore/brush/Face.cpp b/radiantcore/brush/Face.cpp index 6e49f50ce7..9f87930f3f 100644 --- a/radiantcore/brush/Face.cpp +++ b/radiantcore/brush/Face.cpp @@ -724,7 +724,14 @@ bool Face::isVisible() const void Face::updateFaceVisibility() { - _faceIsVisible = contributes() && getFaceShader().getGLShader()->getMaterial()->isVisible(); + auto newValue = contributes() && getFaceShader().getGLShader()->getMaterial()->isVisible(); + + // Notify the owning brush if the value changes + if (newValue != _faceIsVisible) + { + _faceIsVisible = newValue; + _owner.getBrushNode().onFaceVisibilityChanged(); + } } sigc::signal& Face::signal_texdefChanged()