]> git.mxchange.org Git - flightgear.git/commitdiff
Canvas: Support z-index inside Groups/Maps
authorThomas Geymayer <tomgey@gmail.com>
Wed, 26 Sep 2012 15:58:52 +0000 (17:58 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Wed, 26 Sep 2012 16:09:06 +0000 (18:09 +0200)
src/Canvas/canvas.cxx
src/Canvas/elements/group.cxx
src/Canvas/elements/group.hxx
src/Canvas/elements/map.cxx

index 595370ab5c29e70de862bde1b7a77ef888190033..943f21809295335b8aa66b0fda371684fdb8f226 100644 (file)
@@ -170,9 +170,14 @@ void Canvas::update(double delta_time_sec)
     _texture.useImageCoords(true);
     _texture.useStencil(true);
     _texture.allocRT(_camera_callback);
-    _texture.getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 1.0f));
-    _texture.getCamera()->addChild(_root_group->getMatrixTransform());
-    _texture.getCamera()->setFinalDrawCallback(new DrawCallback(this));
+
+    osg::Camera* camera = _texture.getCamera();
+    camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 1.0f));
+    camera->addChild(_root_group->getMatrixTransform());
+    camera->setFinalDrawCallback(new DrawCallback(this));
+
+    // Ensure objects are drawn in order of traversal
+    camera->getOrCreateStateSet()->setBinName("TraversalOrderBin");
 
     if( _texture.serviceable() )
     {
index 7cd9119e7414456179fb0bd567aaa63c5d010f99..ddd789921ee531cd65fcb8599e36fa6dad5b889b 100644 (file)
@@ -147,4 +147,68 @@ namespace canvas
     }
   }
 
+  //----------------------------------------------------------------------------
+  void Group::childChanged(SGPropertyNode* node)
+  {
+    if(    node->getParent()->getParent() == _node
+        && node->getNameString() == "z-index" )
+      return handleZIndexChanged(node->getParent(), node->getIntValue());
+  }
+
+  //----------------------------------------------------------------------------
+  void Group::handleZIndexChanged(SGPropertyNode* node, int z_index)
+  {
+    ChildFinder pred(node);
+    ChildList::iterator child =
+      std::find_if(_children.begin(), _children.end(), pred);
+
+    if( child == _children.end() )
+      return;
+
+    osg::Node* tf = child->second->getMatrixTransform();
+    int index = _transform->getChildIndex(tf),
+        index_new = index;
+
+    ChildList::iterator next = child;
+    ++next;
+
+    while(    next != _children.end()
+           && next->first->getIntValue("z-index", 0) < z_index )
+    {
+      ++index_new;
+      ++next;
+    }
+
+    if( index_new != index )
+    {
+      _children.insert(next, *child);
+    }
+    else
+    {
+      ChildList::iterator prev = child;
+      while(    prev != _children.begin()
+             && (--prev)->first->getIntValue("z-index", 0) > z_index)
+      {
+        --index_new;
+      }
+
+      if( index == index_new )
+        return;
+
+      _children.insert(prev, *child);
+    }
+
+    _transform->removeChild(index);
+    _transform->insertChild(index_new, tf);
+
+    _children.erase(child);
+
+    SG_LOG
+    (
+      SG_GENERAL,
+      SG_INFO,
+      "canvas::Group: Moved element " << index << " to position " << index_new
+    );
+  }
+
 } // namespace canvas
index 84cafa5b5e4627f1cfae14b11ebb9d28037ae872..17d4f8910ae3ace397dae3aa68b9cc56d37084dc 100644 (file)
@@ -51,6 +51,9 @@ namespace canvas
 
       virtual void childAdded(SGPropertyNode * child);
       virtual void childRemoved(SGPropertyNode * child);
+      virtual void childChanged(SGPropertyNode * child);
+
+      void handleZIndexChanged(SGPropertyNode* node, int z_index);
   };
 
 }  // namespace canvas
index a06ebfe230a44776db583681e85e7bdea13d8fc3..503e815439304170e802dcdac74cc5f156cb8f15 100644 (file)
@@ -178,7 +178,7 @@ namespace canvas
   void Map::childChanged(SGPropertyNode * child)
   {
     if( child->getParent() != _node )
-      return;
+      return Group::childChanged(child);
 
     if(    child->getNameString() == "ref-lat"
         || child->getNameString() == "ref-lon" )
@@ -189,7 +189,7 @@ namespace canvas
     else if( child->getNameString() == "range" )
       _projection->setRange(child->getDoubleValue());
     else
-      return;
+      return Group::childChanged(child);
 
     _projection_dirty = true;
   }