]> git.mxchange.org Git - simgear.git/commitdiff
Canvas::Element: expose combined transformation matrix
authorThomas Geymayer <tomgey@gmail.com>
Thu, 6 Feb 2014 16:55:51 +0000 (17:55 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Thu, 6 Feb 2014 16:55:51 +0000 (17:55 +0100)
simgear/canvas/elements/CanvasElement.cxx
simgear/canvas/elements/CanvasElement.hxx

index b6e830569db5453395d148f4f7a703691614cf6d..34088814abade7cebbb11d5890295b34daaa30d6 100644 (file)
@@ -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 ),
index 93108255483152a9d28d1bb025610a352834fd5d..e56a943ca5813da8ed75ad006f9ae50c07fdc41b 100644 (file)
@@ -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;