Canvas::Element: expose combined transformation matrix
This commit is contained in:
@@ -167,66 +167,8 @@ namespace canvas
|
||||
// Don't do anything if element is hidden
|
||||
return;
|
||||
|
||||
if( _transform_dirty )
|
||||
{
|
||||
osg::Matrix m;
|
||||
for( size_t i = 0; i < _transform_types.size(); ++i )
|
||||
{
|
||||
// Skip unused indizes...
|
||||
if( _transform_types[i] == TT_NONE )
|
||||
continue;
|
||||
|
||||
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
|
||||
|
||||
// Build up the matrix representation of the current transform node
|
||||
osg::Matrix tf;
|
||||
switch( _transform_types[i] )
|
||||
{
|
||||
case TT_MATRIX:
|
||||
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
|
||||
tf_node->getDoubleValue("m[1]", 0),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[6]", 0),
|
||||
|
||||
tf_node->getDoubleValue("m[2]", 0),
|
||||
tf_node->getDoubleValue("m[3]", 1),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[7]", 0),
|
||||
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
|
||||
tf_node->getDoubleValue("m[4]", 0),
|
||||
tf_node->getDoubleValue("m[5]", 0),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[8]", 1) );
|
||||
break;
|
||||
case TT_TRANSLATE:
|
||||
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
|
||||
tf_node->getDoubleValue("t[1]", 0),
|
||||
0 ) );
|
||||
break;
|
||||
case TT_ROTATE:
|
||||
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
|
||||
break;
|
||||
case TT_SCALE:
|
||||
{
|
||||
float sx = tf_node->getDoubleValue("s[0]", 1);
|
||||
// sy defaults to sx...
|
||||
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m.postMult( tf );
|
||||
}
|
||||
_transform->setMatrix(m);
|
||||
_transform_dirty = false;
|
||||
_attributes_dirty |= SCISSOR_COORDS;
|
||||
}
|
||||
// Trigger matrix update
|
||||
getMatrix();
|
||||
|
||||
if( _attributes_dirty & SCISSOR_COORDS )
|
||||
{
|
||||
@@ -364,7 +306,7 @@ namespace canvas
|
||||
_transform_types.resize( child->getIndex() + 1 );
|
||||
|
||||
_transform_types[ child->getIndex() ] = TT_NONE;
|
||||
_transform_dirty = true;
|
||||
_attributes_dirty |= TRANSFORM;
|
||||
return;
|
||||
}
|
||||
else if( parent->getParent() == _node
|
||||
@@ -385,7 +327,7 @@ namespace canvas
|
||||
else if( name == "s" )
|
||||
type = TT_SCALE;
|
||||
|
||||
_transform_dirty = true;
|
||||
_attributes_dirty |= TRANSFORM;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -418,7 +360,7 @@ namespace canvas
|
||||
while( !_transform_types.empty() && _transform_types.back() == TT_NONE )
|
||||
_transform_types.pop_back();
|
||||
|
||||
_transform_dirty = true;
|
||||
_attributes_dirty |= TRANSFORM;
|
||||
return;
|
||||
}
|
||||
else if( StyleInfo const* style = getStyleInfo(child->getNameString()) )
|
||||
@@ -460,7 +402,7 @@ namespace canvas
|
||||
else if( parent->getParent() == _node
|
||||
&& parent->getNameString() == NAME_TRANSFORM )
|
||||
{
|
||||
_transform_dirty = true;
|
||||
_attributes_dirty |= TRANSFORM;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -583,6 +525,73 @@ namespace canvas
|
||||
return transformed;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
osg::Matrix Element::getMatrix() const
|
||||
{
|
||||
if( !(_attributes_dirty & TRANSFORM) )
|
||||
return _transform->getMatrix();
|
||||
|
||||
osg::Matrix m;
|
||||
for( size_t i = 0; i < _transform_types.size(); ++i )
|
||||
{
|
||||
// Skip unused indizes...
|
||||
if( _transform_types[i] == TT_NONE )
|
||||
continue;
|
||||
|
||||
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
|
||||
|
||||
// Build up the matrix representation of the current transform node
|
||||
osg::Matrix tf;
|
||||
switch( _transform_types[i] )
|
||||
{
|
||||
case TT_MATRIX:
|
||||
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
|
||||
tf_node->getDoubleValue("m[1]", 0),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[6]", 0),
|
||||
|
||||
tf_node->getDoubleValue("m[2]", 0),
|
||||
tf_node->getDoubleValue("m[3]", 1),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[7]", 0),
|
||||
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
|
||||
tf_node->getDoubleValue("m[4]", 0),
|
||||
tf_node->getDoubleValue("m[5]", 0),
|
||||
0,
|
||||
tf_node->getDoubleValue("m[8]", 1) );
|
||||
break;
|
||||
case TT_TRANSLATE:
|
||||
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
|
||||
tf_node->getDoubleValue("t[1]", 0),
|
||||
0 ) );
|
||||
break;
|
||||
case TT_ROTATE:
|
||||
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
|
||||
break;
|
||||
case TT_SCALE:
|
||||
{
|
||||
float sx = tf_node->getDoubleValue("s[0]", 1);
|
||||
// sy defaults to sx...
|
||||
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m.postMult( tf );
|
||||
}
|
||||
_transform->setMatrix(m);
|
||||
_attributes_dirty &= ~TRANSFORM;
|
||||
_attributes_dirty |= SCISSOR_COORDS;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Element::StyleSetters Element::_style_setters;
|
||||
|
||||
@@ -595,7 +604,6 @@ namespace canvas
|
||||
_canvas( canvas ),
|
||||
_parent( parent ),
|
||||
_attributes_dirty( 0 ),
|
||||
_transform_dirty( false ),
|
||||
_transform( new osg::MatrixTransform ),
|
||||
_style( parent_style ),
|
||||
_scissor( 0 ),
|
||||
|
||||
@@ -157,6 +157,11 @@ namespace canvas
|
||||
*/
|
||||
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
|
||||
|
||||
/**
|
||||
* Get the transformation matrix (product of all transforms)
|
||||
*/
|
||||
osg::Matrix getMatrix() const;
|
||||
|
||||
/**
|
||||
* Create an canvas Element
|
||||
*
|
||||
@@ -181,7 +186,8 @@ namespace canvas
|
||||
|
||||
enum Attributes
|
||||
{
|
||||
BLEND_FUNC = 1,
|
||||
TRANSFORM = 1,
|
||||
BLEND_FUNC = TRANSFORM << 1,
|
||||
SCISSOR_COORDS = BLEND_FUNC << 1,
|
||||
LAST_ATTRIBUTE = SCISSOR_COORDS << 1
|
||||
};
|
||||
@@ -200,9 +206,8 @@ namespace canvas
|
||||
CanvasWeakPtr _canvas;
|
||||
Element *_parent;
|
||||
|
||||
uint32_t _attributes_dirty;
|
||||
mutable uint32_t _attributes_dirty;
|
||||
|
||||
bool _transform_dirty;
|
||||
osg::observer_ptr<osg::MatrixTransform> _transform;
|
||||
std::vector<TransformType> _transform_types;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user