From b6e280f14d41d091663f795e5a4445dab7e7a53d Mon Sep 17 00:00:00 2001 From: milek7 Date: Sat, 12 Jan 2019 01:40:22 +0100 Subject: [PATCH] lazy bounding radius computing for shape_node (avoids O(n^2) deserialization) --- scene.cpp | 4 ++-- scenenode.cpp | 12 ++++++++++-- scenenode.h | 7 ++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scene.cpp b/scene.cpp index 5d937723..cdc06b43 100644 --- a/scene.cpp +++ b/scene.cpp @@ -259,7 +259,7 @@ basic_cell::insert( shape_node Shape ) { // re-calculate cell radius, in case shape geometry extends outside the cell's boundaries m_area.radius = std::max( m_area.radius, - glm::length( m_area.center - Shape.data().area.center ) + Shape.data().area.radius ); + glm::length( m_area.center - Shape.data().area.center ) + Shape.radius() ); auto const &shapedata { Shape.data() }; auto &shapes = ( @@ -1230,7 +1230,7 @@ basic_region::insert( shape_node Shape, scratch_data &Scratchpad, bool const Tra // move the data into appropriate section(s) for( auto &shape : shapes ) { // with the potential splitting done we can calculate each chunk's bounding radius - shape.compute_radius(); + shape.invalidate_radius(); if( point_inside( shape.m_data.area.center ) ) { // NOTE: nodes placed outside of region boundaries are discarded section( shape.m_data.area.center ).insert( shape ); diff --git a/scenenode.cpp b/scenenode.cpp index bdd99b41..2bc0674b 100644 --- a/scenenode.cpp +++ b/scenenode.cpp @@ -407,8 +407,7 @@ shape_node::merge( shape_node &Shape ) { m_data.vertices.insert( std::end( m_data.vertices ), std::begin( Shape.m_data.vertices ), std::end( Shape.m_data.vertices ) ); - // NOTE: we could recalculate radius with something other than brute force, but it'll do - compute_radius(); + invalidate_radius(); return true; } @@ -442,7 +441,16 @@ shape_node::compute_radius() { m_data.area.radius = static_cast( std::sqrt( squaredradius ) ); } +void shape_node::invalidate_radius() { + m_data.area.radius = -1.0f; +} +float shape_node::radius() { + if (m_data.area.radius == -1.0f) + compute_radius(); + + return m_data.area.radius; +} // sends content of the struct to provided stream void diff --git a/scenenode.h b/scenenode.h index 2bd0d2c2..65be6507 100644 --- a/scenenode.h +++ b/scenenode.h @@ -126,7 +126,10 @@ public: create_geometry( gfx::geometrybank_handle const &Bank ); // calculates shape's bounding radius void - compute_radius(); + compute_radius(); + // invalidates shape's bounding radius + void + invalidate_radius(); // set visibility void visible( bool State ); @@ -136,6 +139,8 @@ public: // data access shapenode_data const & data() const; + // get bounding radius + float radius(); private: // members