Canvas news: Difference between revisions

Jump to navigation Jump to search
13,015 bytes removed ,  26 August 2017
m
→‎Canvas & Slave Cameras: collapsible didn't work here ...
m (→‎Canvas & Slave Cameras: https://forum.flightgear.org/viewtopic.php?f=71&t=23929#p317448)
m (→‎Canvas & Slave Cameras: collapsible didn't work here ...)
Line 118: Line 118:
   |script_version = 0.40  
   |script_version = 0.40  
   }}</ref>
   }}</ref>
{{collapsible script
| type  = C++ diff
| title  = Proof of concept implementing slaved camera views rendering to a FBO/RTT
| script = From 9637fb0ac157d3df21feb60b279a7c8ccb8adf57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20de=20l=27Hamaide?= <cl-----e---ma----ez@hotmail.fr>
Date: Tue, 23 Feb 2016 21:42:11 +0100
Subject: [PATCH] Implement CameraDisplay instrument
---
src/Cockpit/CMakeLists.txt            |  4 +-
src/Cockpit/CameraDisplay.cxx          | 239 +++++++++++++++++++++++++++++++++
src/Cockpit/CameraDisplay.hxx          |  73 ++++++++++
src/Cockpit/cockpitDisplayManager.cxx  |  6 +-
src/Instrumentation/instrument_mgr.cxx |  3 +-
5 files changed, 322 insertions(+), 3 deletions(-)
create mode 100644 src/Cockpit/CameraDisplay.cxx
create mode 100644 src/Cockpit/CameraDisplay.hxx
diff --git a/src/Cockpit/CMakeLists.txt b/src/Cockpit/CMakeLists.txt
index 42b03ba..6d722ea 100644
--- a/src/Cockpit/CMakeLists.txt
+++ b/src/Cockpit/CMakeLists.txt
@@ -11,6 +11,7 @@ set(SOURCES
    render_area_2d.cxx
    wxradar.cxx
    NavDisplay.cxx
+    CameraDisplay.cxx
    )
   
set(HEADERS
@@ -24,7 +25,8 @@ set(HEADERS
    render_area_2d.hxx
    wxradar.hxx
    NavDisplay.hxx
+    CameraDisplay.hxx
    )
-flightgear_component(Cockpit "${SOURCES}" "${HEADERS}")
\ No newline at end of file
+flightgear_component(Cockpit "${SOURCES}" "${HEADERS}")
diff --git a/src/Cockpit/CameraDisplay.cxx b/src/Cockpit/CameraDisplay.cxx
new file mode 100644
index 0000000..51c1d0a
--- /dev/null
+++ b/src/Cockpit/CameraDisplay.cxx
@@ -0,0 +1,239 @@
+// camera display texture
+//
+// Written by Clément de l'Hamaide
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <osg/ImageStream>
+
+#include <Main/fg_props.hxx>
+#include <Viewer/viewmgr.hxx>
+#include <Scenery/scenery.hxx>
+#include <Viewer/renderer.hxx>
+
+#include <simgear/scene/material/EffectGeode.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
+
+#include "CameraDisplay.hxx"
+#include "panel.hxx"
+
+
+
+class FindAndReplaceStaticTextureVisitor : public osg::NodeVisitor
+{
+  public:
+    FindAndReplaceStaticTextureVisitor( const char* name, osg::Texture2D* new_texture ) :
+      osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+      _tex_name( osgDB::getSimpleFileName(name) ),
+      _new_texture(new_texture)
+    {}
+
+    virtual void apply(osg::Geode& node)
+    {
+      simgear::EffectGeode* eg = dynamic_cast<simgear::EffectGeode*>(&node);
+      if( !eg )
+        return;
+      simgear::Effect* eff = eg->getEffect();
+      if (!eff)
+          return;
+      osg::StateSet* ss = eff->getDefaultStateSet();
+      if( !ss )
+        return;
+
+      for( size_t unit = 0; unit < ss->getNumTextureAttributeLists(); ++unit ) {
+        osg::Texture2D* tex = dynamic_cast<osg::Texture2D*>( ss->getTextureAttribute(unit, osg::StateAttribute::TEXTURE) );
+        if( !tex || !tex->getImage() || tex == _new_texture )
+          continue;
+
+        if( !_tex_name.empty() ) {
+          std::string tex_name = tex->getImage()->getFileName();
+          std::string tex_name_simple = osgDB::getSimpleFileName(tex_name);
+          if( !osgDB::equalCaseInsensitive(_tex_name, tex_name_simple) )
+            continue;
+        }
+
+        // insert a new group between the geode an it's parent which overrides the texture
+        osg::ref_ptr<osg::Group> group = new osg::Group;
+        group->setName("canvas texture group");
+        group->addChild(eg);
+        osg::ref_ptr<osg::Group> parent = node.getParent(0);
+        parent->removeChild(eg);
+        parent->addChild(group);
+
+        osg::StateSet* stateSet = group->getOrCreateStateSet();
+        stateSet->setTextureAttribute( unit, _new_texture, osg::StateAttribute::OVERRIDE );
+        stateSet->setTextureMode( unit, GL_TEXTURE_2D, osg::StateAttribute::ON );
+
+        SG_LOG(SG_INSTR, SG_DEBUG, "CameraDislay: replaced texture '" << _tex_name << "'" << " for object '" << parent->getName() << "'");
+        return;
+      }
+    }
+
+  protected:
+    std::string _tex_name;
+    osg::Texture2D    *_new_texture;
+};
+
+
+
+CameraDisplay::CameraDisplay(SGPropertyNode *node) :
+  _num(node->getIntValue("number", 0)),
+  _viewNum(node->getIntValue("view-number", 0)),
+  _enabled(true),
+  _initialized(false),
+  _name(node->getStringValue("name", "cd")),
+  _texturePath(node->getStringValue("texture-path",
+  "Aircraft/Instruments/Textures/camera-display.rgb"))
+{}
+
+
+CameraDisplay::~CameraDisplay()
+{
+  if( !_initialized )
+    return;
+}
+
+
+void CameraDisplay::bind()
+{
+  _instrument_node = fgGetNode("/instrumentation/camera-display", _num, true);
+  _name_node      = _instrument_node->getChild( "name", 0, true);
+  _texture_node    = _instrument_node->getChild( "texture", 0, true);
+  _enabled_node    = _instrument_node->getChild( "enabled", 0, true );
+  _view_node      = _instrument_node->getChild( "view-number", 0, true );
+
+  _view_node->setIntValue(_viewNum);
+  _name_node->setStringValue(_name);
+  _enabled_node->setBoolValue(_enabled);
+  _texture_node->setStringValue(_texturePath);
+
+  _view_node->addChangeListener(this);
+  _enabled_node->addChangeListener(this);
+}
+
+
+void CameraDisplay::init()
+{
+  if(_initialized)
+    return;
+
+  if ( !fgGetNode("/sim/view", _viewNum, false) ) {
+    SG_LOG(SG_INSTR, SG_DEBUG, "CameraDisplay: can't find view-number " << _viewNum);
+    return;
+  }
+
+  std::string path = _texture_node->getStringValue();
+  SGPath tpath = globals->resolve_aircraft_path( path );
+  if (!tpath.exists()) {
+    SG_LOG(SG_INSTR, SG_WARN, "CameraDisplay: display texture not found:" << path);
+    return;
+  }
+
+  _initialized = true;
+}
+
+
+void CameraDisplay::postinit()
+{
+  if( !_initialized )
+    return;
+
+  setView( _view_node->getIntValue() );
+
+  //TODO: setup an osg::Texture
+  //      setup an osg::Camera
+  //      attach the osg::Camera to the osg::Texture2D
+  //        in a way the camera draw on the osg::Texture2D
+  //      attach the osg::Texture2D to the 3D model
+  //        in a way the current 3D model texture being replaced by the osg::Texure2D
+#if 1
+  int tex_width = 512, tex_height = 512;
+  _texture = new osg::Texture2D;
+  _texture->setTextureSize( tex_width, tex_height );
+  _texture->setInternalFormat( GL_RGBA );
+  _texture->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
+  _texture->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
+
+  FindAndReplaceStaticTextureVisitor ftv( _texture_node->getStringValue(), _texture.get() );
+  globals->get_scenery()->get_aircraft_branch()->accept(ftv);
+
+  _camera = new osg::Camera;
+  _camera->setViewport( 0, 0, tex_width, tex_height );
+  _camera->setClearColor( osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) );
+  _camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+  _camera->setRenderOrder( osg::Camera::PRE_RENDER );
+  _camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
+  _camera->attach( osg::Camera::COLOR_BUFFER, _texture.get() );
+  _camera->setReferenceFrame( osg::Camera::ABSOLUTE_RF );
+  _camera->addChild( globals->get_scenery()->get_scene_graph() );
+  _camera->setProjectionMatrixAsPerspective(/*fov*/ 85.0, /*ratio*/ 1.88, /*near*/ 0.1, /*far*/ 120000.0);
+  globals->get_renderer()->addCamera(_camera, false);
+#endif
+}
+
+
+void CameraDisplay::update(double dt)
+{
+  if( !_initialized || !_enabled )
+    return;
+#if 1
+  if( _view != globals->get_current_view() )
+    _view->update(dt);
+
+  osg::Vec3f position( toOsg(_view->getViewPosition()) );
+  osg::Quat orientation( toOsg(_view->getViewOrientation()) );
+  osg::Matrix viewMatrix( osg::Matrix::translate(-position) * osg::Matrix::rotate(orientation.inverse()) );
+
+  _camera->setViewMatrix( viewMatrix );
+#endif
+}
+
+
+void CameraDisplay::valueChanged(SGPropertyNode *node)
+{
+  if(!_initialized)
+    return;
+
+  if (node == _enabled_node) {
+    _enabled = node->getBoolValue();
+    return;
+  }
+
+  if (node == _view_node) {
+    _view = globals->get_viewmgr()->get_view( node->getIntValue() );
+    setView( node->getIntValue() );
+    return;
+  }
+}
+
+
+void CameraDisplay::setView(int v)
+{
+  std::vector<SGPropertyNode_ptr> viewList = fgGetNode("/sim", true)->getChildren("view");
+  for (unsigned int i = 0; i < viewList.size(); i++) {
+    if( viewList[i]->getIndex() == v ) {
+      _view = globals->get_viewmgr()->get_view(i);
+      break;
+    }
+  }
+}
+
diff --git a/src/Cockpit/CameraDisplay.hxx b/src/Cockpit/CameraDisplay.hxx
new file mode 100644
index 0000000..69e432a
--- /dev/null
+++ b/src/Cockpit/CameraDisplay.hxx
@@ -0,0 +1,73 @@
+// camera display texture
+//
+// Written by Clément de l'Hamaide
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//
+
+#ifndef _INST_CAMDISPLAY_HXX
+#define _INST_CAMDISPLAY_HXX
+
+#include <Viewer/view.hxx>
+
+#include "od_gauge.hxx"
+
+/*
+ * CameraDisplay class
+ *
+ * A subsystem instrument who reproduces a camera and its display
+ */
+
+class CameraDisplay : public SGSubsystem, public SGPropertyChangeListener
+{
+  public:
+    CameraDisplay(SGPropertyNode *node);
+    virtual ~CameraDisplay();
+    virtual void bind();
+    virtual void init();
+    virtual void postinit();
+    virtual void update(double dt);
+    virtual void valueChanged(SGPropertyNode *node);
+    void setView(int v);
+  protected:
+
+
+  private:
+    int _num;
+    int _viewNum;
+    bool _enabled;
+    bool _initialized;
+    FGODGauge *_odg;
+    std::string _name;
+    std::string _texturePath;
+    flightgear::View *_view;
+    SGPropertyNode_ptr _name_node;
+    SGPropertyNode_ptr _view_node;
+    SGPropertyNode_ptr _enabled_node;
+    SGPropertyNode_ptr _texture_node;
+    SGPropertyNode_ptr _instrument_node;
+    osg::ref_ptr<osg::Camera> _camera;
+    osg::ref_ptr<osg::Texture2D> _texture;
+    osg::Matrix _viewMatrix;
+    /*osg::Camera *_camera;
+    osg::Texture2D *_texture;*/
+};
+
+#endif
diff --git a/src/Cockpit/cockpitDisplayManager.cxx b/src/Cockpit/cockpitDisplayManager.cxx
index 18e6e7d..0a46ff8 100644
--- a/src/Cockpit/cockpitDisplayManager.cxx
+++ b/src/Cockpit/cockpitDisplayManager.cxx
@@ -37,6 +37,7 @@
#include "NavDisplay.hxx"
#include "groundradar.hxx"
#include "wxradar.hxx"
+#include "CameraDisplay.hxx"
namespace flightgear
{
@@ -112,7 +113,10 @@ bool CockpitDisplayManager::build (SGPropertyNode* config_props)
     
        } else if ( name == "navigation-display" ) {
            set_subsystem( id, new NavDisplay( node ) );
-         
+
+        } else if ( name == "camera-display" ) {
+            set_subsystem( id, new CameraDisplay( node ) );
+
        } else {
            // probably a regular instrument
            continue;
diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx
index 751f6c7..3bd1dfa 100644
--- a/src/Instrumentation/instrument_mgr.cxx
+++ b/src/Instrumentation/instrument_mgr.cxx
@@ -209,7 +209,8 @@ bool FGInstrumentMgr::build (SGPropertyNode* config_props)
        } else if (( name == "groundradar" ) ||
                    ( name == "radar" ) ||
                    ( name == "air-ground-radar" ) ||
-                  ( name == "navigation-display" ))
+                  ( name == "navigation-display" ) ||
+                  ( name == "camera-display" ))
        {
        // these instruments are handled by the CockpitDisplayManager
        // catch them here so we can still warn about bogus names in
--
1.9.1
| lang = diff
}}


=== G1000 & MapStructure improvements ===
=== G1000 & MapStructure improvements ===

Navigation menu