From: Thomas Geymayer Date: Mon, 31 Mar 2014 11:24:33 +0000 (+0200) Subject: Canvas: do not write bounding box to property tree. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=d332da06057f923858097a607ecf868e81c00d0d;p=simgear.git Canvas: do not write bounding box to property tree. - Prevent writing to property tree in wrong thread. - Add Element::getBoundingBox and Element::getTightBoundingBox as uniform way to retrieve bounding boxes of all canvas elements. - Update path bounding boxe in update traversal. --- diff --git a/simgear/canvas/Canvas.cxx b/simgear/canvas/Canvas.cxx index 5f13e28c..9873ba6d 100644 --- a/simgear/canvas/Canvas.cxx +++ b/simgear/canvas/Canvas.cxx @@ -452,8 +452,7 @@ namespace canvas //---------------------------------------------------------------------------- void Canvas::valueChanged(SGPropertyNode* node) { - if( boost::starts_with(node->getNameString(), "status") - || node->getParent()->getNameString() == "bounding-box" ) + if( boost::starts_with(node->getNameString(), "status") ) return; _render_dirty = true; diff --git a/simgear/canvas/elements/CanvasElement.cxx b/simgear/canvas/elements/CanvasElement.cxx index 373632fc..bdbcf902 100644 --- a/simgear/canvas/elements/CanvasElement.cxx +++ b/simgear/canvas/elements/CanvasElement.cxx @@ -189,6 +189,7 @@ namespace canvas // Trigger matrix update getMatrix(); + // TODO limit bounding box to scissor if( _attributes_dirty & SCISSOR_COORDS ) { if( _scissor && _scissor->_coord_reference != GLOBAL ) @@ -296,9 +297,11 @@ namespace canvas // Drawables have a bounding box... if( _drawable ) return _drawable->getBound().contains(osg::Vec3f(local_pos, 0)); - else + else if( _transform.valid() ) // ... for other elements, i.e. groups only a bounding sphere is available return _transform->getBound().contains(osg::Vec3f(parent_pos, 0)); + else + return false; } @@ -534,22 +537,23 @@ namespace canvas } //---------------------------------------------------------------------------- - void Element::setBoundingBox(const osg::BoundingBox& bb) + osg::BoundingBox Element::getBoundingBox() const { - if( _bounding_box.empty() ) - { - SGPropertyNode* bb_node = _node->getChild("bounding-box", 0, true); - _bounding_box.resize(4); - _bounding_box[0] = bb_node->getChild("min-x", 0, true); - _bounding_box[1] = bb_node->getChild("min-y", 0, true); - _bounding_box[2] = bb_node->getChild("max-x", 0, true); - _bounding_box[3] = bb_node->getChild("max-y", 0, true); - } + if( _drawable ) + return _drawable->getBound(); + + osg::BoundingBox bb; - _bounding_box[0]->setFloatValue(bb._min.x()); - _bounding_box[1]->setFloatValue(bb._min.y()); - _bounding_box[2]->setFloatValue(bb._max.x()); - _bounding_box[3]->setFloatValue(bb._max.y()); + if( _transform.valid() ) + bb.expandBy(_transform->getBound()); + + return bb; + } + + //---------------------------------------------------------------------------- + osg::BoundingBox Element::getTightBoundingBox() const + { + return getTransformedBounds(getMatrix()); } //---------------------------------------------------------------------------- @@ -569,6 +573,9 @@ namespace canvas //---------------------------------------------------------------------------- osg::Matrix Element::getMatrix() const { + if( !_transform ) + return osg::Matrix::identity(); + if( !(_attributes_dirty & TRANSFORM) ) return _transform->getMatrix(); diff --git a/simgear/canvas/elements/CanvasElement.hxx b/simgear/canvas/elements/CanvasElement.hxx index dc5e1bf7..63649a86 100644 --- a/simgear/canvas/elements/CanvasElement.hxx +++ b/simgear/canvas/elements/CanvasElement.hxx @@ -164,9 +164,16 @@ namespace canvas void setClipFrame(ReferenceFrame rf); /** - * Write the given bounding box to the property tree + * Get bounding box (may not be as tight as bounding box returned by + * #getTightBounds) */ - void setBoundingBox(const osg::BoundingBox& bb); + osg::BoundingBox getBoundingBox() const; + + /** + * Get tight bounding box (child points are transformed to elements + * coordinate space before calculating the bounding box). + */ + osg::BoundingBox getTightBoundingBox() const; /** * Get bounding box with children/drawables transformed by passed matrix @@ -227,9 +234,8 @@ namespace canvas osg::observer_ptr _transform; std::vector _transform_types; - Style _style; - std::vector _bounding_box; - RelativeScissor *_scissor; + Style _style; + RelativeScissor *_scissor; typedef std::vector Listener; typedef std::map ListenerMap; @@ -237,7 +243,7 @@ namespace canvas ListenerMap _listener; typedef std::map StyleSetters; - static StyleSetters _style_setters; + static StyleSetters _style_setters; static void staticInit(); diff --git a/simgear/canvas/elements/CanvasImage.cxx b/simgear/canvas/elements/CanvasImage.cxx index 84d64573..28fd2f49 100644 --- a/simgear/canvas/elements/CanvasImage.cxx +++ b/simgear/canvas/elements/CanvasImage.cxx @@ -271,7 +271,6 @@ namespace canvas _vertices->dirty(); _attributes_dirty &= ~DEST_SIZE; _geom->dirtyBound(); - setBoundingBox(_geom->getBound()); } if( _attributes_dirty & SRC_RECT ) diff --git a/simgear/canvas/elements/CanvasPath.cxx b/simgear/canvas/elements/CanvasPath.cxx index 27c847a7..07d06bab 100644 --- a/simgear/canvas/elements/CanvasPath.cxx +++ b/simgear/canvas/elements/CanvasPath.cxx @@ -381,14 +381,11 @@ namespace canvas // vgPathBounds doesn't take stroke width into account float ext = 0.5 * _stroke_width; - osg::BoundingBox bb + return osg::BoundingBox ( min[0] - ext, min[1] - ext, -0.1, min[0] + size[0] + ext, min[1] + size[1] + ext, 0.1 ); - _path_element->setBoundingBox(bb); - - return bb; } private: @@ -463,7 +460,12 @@ namespace canvas } if( _attributes_dirty & BOUNDING_BOX ) + { dirtyBound(); + + // Recalculate bounding box now (prevent race condition) + getBound(); + } } struct PathUpdateCallback: diff --git a/simgear/canvas/elements/CanvasText.cxx b/simgear/canvas/elements/CanvasText.cxx index f73a6ce8..eb399e16 100644 --- a/simgear/canvas/elements/CanvasText.cxx +++ b/simgear/canvas/elements/CanvasText.cxx @@ -179,18 +179,17 @@ namespace canvas osg::BoundingBox Text::TextOSG::computeBound() const { osg::BoundingBox bb = osgText::Text::computeBound(); - if( !bb.valid() ) - return bb; #if OSG_VERSION_LESS_THAN(3,1,0) - // TODO bounding box still doesn't seem always right (eg. with center - // horizontal alignment not completely accurate) - bb._min.y() += _offset.y(); - bb._max.y() += _offset.y(); + if( bb.valid() ) + { + // TODO bounding box still doesn't seem always right (eg. with center + // horizontal alignment not completely accurate) + bb._min.y() += _offset.y(); + bb._max.y() += _offset.y(); + } #endif - _text_element->setBoundingBox(bb); - return bb; }