Extend Canvas to retrieve bounding box of groups
This commit is contained in:
@@ -316,6 +316,12 @@ namespace canvas
|
|||||||
_bounding_box[3]->setFloatValue(bb._max.y());
|
_bounding_box[3]->setFloatValue(bb._max.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
osg::BoundingBox Element::getTransformedBounds(const osg::Matrix& m) const
|
||||||
|
{
|
||||||
|
return osg::BoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Element::Element( const CanvasWeakPtr& canvas,
|
Element::Element( const CanvasWeakPtr& canvas,
|
||||||
const SGPropertyNode_ptr& node,
|
const SGPropertyNode_ptr& node,
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ namespace canvas
|
|||||||
*/
|
*/
|
||||||
void setBoundingBox(const osg::BoundingBox& bb);
|
void setBoundingBox(const osg::BoundingBox& bb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bounding box with children/drawables transformed by passed matrix
|
||||||
|
*/
|
||||||
|
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
enum Attributes
|
enum Attributes
|
||||||
|
|||||||
@@ -132,6 +132,28 @@ namespace canvas
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
osg::BoundingBox Group::getTransformedBounds(const osg::Matrix& m) const
|
||||||
|
{
|
||||||
|
osg::BoundingBox bb;
|
||||||
|
|
||||||
|
BOOST_FOREACH( ChildList::value_type child, _children )
|
||||||
|
{
|
||||||
|
if( !child.second->getMatrixTransform()->getNodeMask() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bb.expandBy
|
||||||
|
(
|
||||||
|
child.second->getTransformedBounds
|
||||||
|
(
|
||||||
|
child.second->getMatrixTransform()->getMatrix() * m
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Group::childAdded(SGPropertyNode* child)
|
void Group::childAdded(SGPropertyNode* child)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace canvas
|
|||||||
|
|
||||||
virtual bool traverse(EventVisitor& visitor);
|
virtual bool traverse(EventVisitor& visitor);
|
||||||
|
|
||||||
|
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef std::map<std::string, ElementFactory> ChildFactories;
|
typedef std::map<std::string, ElementFactory> ChildFactories;
|
||||||
|
|||||||
@@ -32,6 +32,25 @@ namespace canvas
|
|||||||
typedef std::vector<VGubyte> CmdList;
|
typedef std::vector<VGubyte> CmdList;
|
||||||
typedef std::vector<VGfloat> CoordList;
|
typedef std::vector<VGfloat> CoordList;
|
||||||
|
|
||||||
|
|
||||||
|
static const VGubyte shCoordsPerCommand[] = {
|
||||||
|
0, /* VG_CLOSE_PATH */
|
||||||
|
2, /* VG_MOVE_TO */
|
||||||
|
2, /* VG_LINE_TO */
|
||||||
|
1, /* VG_HLINE_TO */
|
||||||
|
1, /* VG_VLINE_TO */
|
||||||
|
4, /* VG_QUAD_TO */
|
||||||
|
6, /* VG_CUBIC_TO */
|
||||||
|
2, /* VG_SQUAD_TO */
|
||||||
|
4, /* VG_SCUBIC_TO */
|
||||||
|
5, /* VG_SCCWARC_TO */
|
||||||
|
5, /* VG_SCWARC_TO */
|
||||||
|
5, /* VG_LCCWARC_TO */
|
||||||
|
5 /* VG_LCWARC_TO */
|
||||||
|
};
|
||||||
|
static const VGubyte shNumCommands = sizeof(shCoordsPerCommand)
|
||||||
|
/ sizeof(shCoordsPerCommand[0]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to split and convert comma/whitespace separated floating point
|
* Helper to split and convert comma/whitespace separated floating point
|
||||||
* values
|
* values
|
||||||
@@ -255,6 +274,91 @@ namespace canvas
|
|||||||
glPopClientAttrib();
|
glPopClientAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::BoundingBox getTransformedBounds(const osg::Matrix& mat) const
|
||||||
|
{
|
||||||
|
osg::BoundingBox bb;
|
||||||
|
|
||||||
|
osg::Vec2f cur; // VG "Current point" (in local coordinates)
|
||||||
|
VGubyte cmd_index = 0;
|
||||||
|
for( size_t i = 0, ci = 0;
|
||||||
|
i < _cmds.size() && ci < _coords.size();
|
||||||
|
++i, ci += shCoordsPerCommand[cmd_index] )
|
||||||
|
{
|
||||||
|
VGubyte rel = _cmds[i] & 1,
|
||||||
|
cmd = _cmds[i] & ~1;
|
||||||
|
|
||||||
|
cmd_index = cmd / 2;
|
||||||
|
if( cmd_index >= shNumCommands )
|
||||||
|
return osg::BoundingBox();
|
||||||
|
|
||||||
|
const VGubyte max_coords = 3;
|
||||||
|
osg::Vec2f points[max_coords];
|
||||||
|
VGubyte num_coords = 0;
|
||||||
|
|
||||||
|
switch( cmd )
|
||||||
|
{
|
||||||
|
case VG_CLOSE_PATH:
|
||||||
|
break;
|
||||||
|
case VG_MOVE_TO:
|
||||||
|
case VG_LINE_TO:
|
||||||
|
case VG_SQUAD_TO:
|
||||||
|
// x0, y0
|
||||||
|
points[ num_coords++ ].set(_coords[ci], _coords[ci + 1]);
|
||||||
|
break;
|
||||||
|
case VG_HLINE_TO:
|
||||||
|
// x0
|
||||||
|
points[ num_coords++ ].set( _coords[ci] + (rel ? cur.x() : 0),
|
||||||
|
cur.y() );
|
||||||
|
// We have handled rel/abs already, so no need to do it again...
|
||||||
|
rel = 0;
|
||||||
|
break;
|
||||||
|
case VG_VLINE_TO:
|
||||||
|
// y0
|
||||||
|
points[ num_coords++ ].set( cur.x(),
|
||||||
|
_coords[ci] + (rel ? cur.y() : 0) );
|
||||||
|
// We have handled rel/abs already, so no need to do it again...
|
||||||
|
rel = 0;
|
||||||
|
break;
|
||||||
|
case VG_QUAD_TO:
|
||||||
|
case VG_SCUBIC_TO:
|
||||||
|
// x0,y0,x1,y1
|
||||||
|
points[ num_coords++ ].set(_coords[ci ], _coords[ci + 1]);
|
||||||
|
points[ num_coords++ ].set(_coords[ci + 2], _coords[ci + 3]);
|
||||||
|
break;
|
||||||
|
case VG_CUBIC_TO:
|
||||||
|
// x0,y0,x1,y1,x2,y2
|
||||||
|
points[ num_coords++ ].set(_coords[ci ], _coords[ci + 1]);
|
||||||
|
points[ num_coords++ ].set(_coords[ci + 2], _coords[ci + 3]);
|
||||||
|
points[ num_coords++ ].set(_coords[ci + 4], _coords[ci + 5]);
|
||||||
|
break;
|
||||||
|
case VG_SCCWARC_TO:
|
||||||
|
case VG_SCWARC_TO:
|
||||||
|
case VG_LCCWARC_TO:
|
||||||
|
case VG_LCWARC_TO:
|
||||||
|
// rh,rv,rot,x0,y0
|
||||||
|
points[ num_coords++ ].set(_coords[ci + 3], _coords[ci + 4]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SG_LOG(SG_GL, SG_WARN, "Unknown VG command: " << (int)cmd);
|
||||||
|
return osg::BoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(num_coords <= max_coords);
|
||||||
|
for(VGubyte i = 0; i < num_coords; ++i)
|
||||||
|
{
|
||||||
|
if( rel )
|
||||||
|
points[i] += cur;
|
||||||
|
|
||||||
|
bb.expandBy( transformPoint(mat, points[i]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( num_coords > 0 )
|
||||||
|
cur = points[ num_coords - 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the bounding box
|
* Compute the bounding box
|
||||||
*/
|
*/
|
||||||
@@ -309,6 +413,17 @@ namespace canvas
|
|||||||
std::vector<VGfloat> _stroke_dash;
|
std::vector<VGfloat> _stroke_dash;
|
||||||
VGCapStyle _stroke_linecap;
|
VGCapStyle _stroke_linecap;
|
||||||
|
|
||||||
|
osg::Vec3f transformPoint( const osg::Matrix& m,
|
||||||
|
osg::Vec2f pos ) const
|
||||||
|
{
|
||||||
|
return osg::Vec3
|
||||||
|
(
|
||||||
|
m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0),
|
||||||
|
m(0, 1) * pos[0] + m(1, 1) * pos[1] + m(3, 1),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize/Update the OpenVG path
|
* Initialize/Update the OpenVG path
|
||||||
*/
|
*/
|
||||||
@@ -396,6 +511,12 @@ namespace canvas
|
|||||||
Element::update(dt);
|
Element::update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
osg::BoundingBox Path::getTransformedBounds(const osg::Matrix& m) const
|
||||||
|
{
|
||||||
|
return _path->getTransformedBounds(m);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Path::childRemoved(SGPropertyNode* child)
|
void Path::childRemoved(SGPropertyNode* child)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace canvas
|
|||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|
||||||
|
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
enum PathAttributes
|
enum PathAttributes
|
||||||
|
|||||||
Reference in New Issue
Block a user