Canvas view camera element: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{FGCquote
  |It would make sense to integrate all efforts ([[CompositeViewer Support|CompositeViewer]], [[Canvas]] and [[Compositor]]) to create a [[Canvas_Development#Elements|Canvas Element]] that can render an [[Canvas_Development#Supporting_Cameras|arbitrary view]].
Some time ago I wrote what I think are the required steps to get something like cockpit mirrors working: [[#Roadmap]]
The main showstopper was having [[CompositeViewer Support]], but since that effort is underway, all the parts are there for someone willing to dive in.
  |{{cite web |url=https://sourceforge.net/p/flightgear/mailman/message/37089780/
    |title=<nowiki>Independent view windows</nowiki>
    |author=<nowiki>Fernando García Liñán </nowiki>
    |date=<nowiki>2020-08-20 14:27:58</nowiki>
  }}
}}
{{infobox subsystem
{{infobox subsystem
|name        = Canvas Camera Views
|name        = Canvas Camera Views
Line 22: Line 35:


== Proof of Concept ==
== Proof of Concept ==
{{Note|This is inspired by the long standing idea to render camera views to a texture for use as tailcams, gear views etc <ref>https://forum.flightgear.org/viewtopic.php?f=71&t=23929</ref>, it's based on code originally provided by F-JJTH<ref>https://forum.flightgear.org/viewtopic.php?f=71&t=23929#p317448</ref>, and subsequently reworked by Icecode GL and Hooray to integrate it with the Canvas system back in 2017<ref>https://forum.flightgear.org/viewtopic.php?f=47&t=32846&p=318046</ref>}}
{{Note|This is inspired by the long standing idea to render camera views to a texture for use as tailcams, gear views etc <ref>https://forum.flightgear.org/viewtopic.php?f=71&t=23929</ref>, it's based on code originally provided by F-JJTH<ref>https://forum.flightgear.org/viewtopic.php?f=71&t=23929#p317448</ref>, and subsequently reworked by Icecode GL and Hooray to integrate it with the Canvas system back in 2017<ref>https://forum.flightgear.org/viewtopic.php?f=47&t=32846&p=318046</ref>
At the time, the main issue was that the new view element needed to be explicitly updated, but that should no longer be the case thanks to James' work on the setPixel() API <ref>https://sourceforge.net/p/flightgear/mailman/message/36926486/</ref> which also means that sc::Image now has a <code>dirtyPixels()</code> API which we can reuse <ref>https://sourceforge.net/p/flightgear/simgear/ci/ad3621e23b4056e1be7e8d9eb8dd4d513455add8/</ref>
Due to the adoption of the [[Compositor]] framework, this will probably need to reworked to be properly integrated.
Furthermore, beginning in mid 2020 Julian Smith has started working on optional [[CompositeViewer Support]] so that independent scene views can be rendered.  }}


SimGear:
SimGear:
Line 249: Line 265:


FlightGear
FlightGear
<syntaxhighlight lang="diff">    diff --git a/src/Canvas/FGCanvasSystemAdapter.cxx b/src/Canvas/FGCanvasSystemAdapter.cxx
<syntaxhighlight lang="diff">     
    index 72b20747e..9e04dbd14 100644
diff --git a/src/Canvas/FGCanvasSystemAdapter.cxx b/src/Canvas/FGCanvasSystemAdapter.cxx
    --- a/src/Canvas/FGCanvasSystemAdapter.cxx
index 72b20747e..9e04dbd14 100644
    +++ b/src/Canvas/FGCanvasSystemAdapter.cxx
--- a/src/Canvas/FGCanvasSystemAdapter.cxx
    @@ -23,9 +23,18 @@
+++ b/src/Canvas/FGCanvasSystemAdapter.cxx
    #include <Network/HTTPClient.hxx>
@@ -23,9 +23,18 @@
    #include <Viewer/renderer.hxx>
#include <Network/HTTPClient.hxx>
   
#include <Viewer/renderer.hxx>
    +
 
    +#include <Viewer/view.hxx>
+
    +#include <Viewer/viewmgr.hxx>
+#include <Viewer/view.hxx>
    +#include <simgear/scene/util/OsgMath.hxx>
+#include <Viewer/viewmgr.hxx>
    +
+#include <simgear/scene/util/OsgMath.hxx>
    +
+
    +
+
    #include <osgDB/ReadFile>
+
    #include <stdexcept>
#include <osgDB/ReadFile>
   
#include <stdexcept>
    +#include <simgear/scene/model/modellib.hxx>
 
    +
+#include <simgear/scene/model/modellib.hxx>
    namespace canvas
+
    {
namespace canvas
      //----------------------------------------------------------------------------
{
    @@ -64,9 +73,9 @@ namespace canvas
//----------------------------------------------------------------------------
      }
@@ -64,9 +73,9 @@ namespace canvas
   
}
      //----------------------------------------------------------------------------
 
    -  void FGCanvasSystemAdapter::addCamera(osg::Camera* camera) const
//----------------------------------------------------------------------------
    +  void FGCanvasSystemAdapter::addCamera(osg::Camera* camera, bool useSceneData) const
-  void FGCanvasSystemAdapter::addCamera(osg::Camera* camera) const
      {
+  void FGCanvasSystemAdapter::addCamera(osg::Camera* camera, bool useSceneData) const
    -    globals->get_renderer()->addCamera(camera, false);
{
    +    globals->get_renderer()->addCamera(camera, useSceneData);
-    globals->get_renderer()->addCamera(camera, false);
      }
+    globals->get_renderer()->addCamera(camera, useSceneData);
   
}
      //----------------------------------------------------------------------------
 
    @@ -100,6 +109,46 @@ namespace canvas
//----------------------------------------------------------------------------
        return 0;
@@ -100,6 +109,46 @@ namespace canvas
      }
return 0;
   
}
    +    //----------------------------------------------------------------------------
 
    +    // From http://wiki.flightgear.org/Howto:Extending_Canvas_to_support_rendering_3D_models#Extending_FGCanvasSystemAdapter
+    //----------------------------------------------------------------------------
    +    osg::Node* FGCanvasSystemAdapter::getModel(const std::string& path) const
+    // From http://wiki.flightgear.org/Howto:Extending_Canvas_to_support_rendering_3D_models#Extending_FGCanvasSystemAdapter
    +    {
+    osg::Node* FGCanvasSystemAdapter::getModel(const std::string& path) const
    +        const char *model_path = "Models/Geometry/glider.ac";
+    {
    +        SGPath p(SGPath::fromUtf8(path));
+        const char *model_path = "Models/Geometry/glider.ac";
    +
+        SGPath p(SGPath::fromUtf8(path));
    +        if( p.isAbsolute() )
+
    +        {
+        if( p.isAbsolute() )
    +            SGPath valid_path = fgValidatePath(p, false);
+        {
    +            if( !valid_path.isNull() )
+            SGPath valid_path = fgValidatePath(p, false);
    +            try {
+            if( !valid_path.isNull() )
    +                std::string fullPath = simgear::SGModelLib::findDataFile(valid_path.local8BitStr());
+            try {
    +                osg::Node * object = simgear::SGModelLib::loadDeferredModel(fullPath, globals->get_props());
+                std::string fullPath = simgear::SGModelLib::findDataFile(valid_path.local8BitStr());
    +                return object;
+                osg::Node * object = simgear::SGModelLib::loadDeferredModel(fullPath, globals->get_props());
    +            } catch (const sg_throwable& t) {
+                return object;
    +                SG_LOG(SG_IO, SG_ALERT, "Error loading " << model_path << ":\n  " << t.getFormattedMessage() << t.getOrigin());
+            } catch (const sg_throwable& t) {
    +                return 0;
+                SG_LOG(SG_IO, SG_ALERT, "Error loading " << model_path << ":\n  " << t.getFormattedMessage() << t.getOrigin());
    +            } // error loading from absolute path
+                return 0;
    +            SG_LOG(SG_IO, SG_ALERT, "canvas::Model: reading '" << path << "' denied");
+            } // error loading from absolute path
    +        } // absolute path handling
+            SG_LOG(SG_IO, SG_ALERT, "canvas::Model: reading '" << path << "' denied");
    +        else
+        } // absolute path handling
    +        {
+        else
    +            SGPath tpath = globals->resolve_resource_path(path);
+        {
    +            if( !tpath.isNull() )
+            SGPath tpath = globals->resolve_resource_path(path);
    +            try {
+            if( !tpath.isNull() )
    +                std::string fullPath = simgear::SGModelLib::findDataFile(path.c_str());
+            try {
    +                osg::Node * object = simgear::SGModelLib::loadDeferredModel(fullPath, globals->get_props());
+                std::string fullPath = simgear::SGModelLib::findDataFile(path.c_str());
    +                return object;
+                osg::Node * object = simgear::SGModelLib::loadDeferredModel(fullPath, globals->get_props());
    +            } catch (const sg_throwable& t) {
+                return object;
    +                SG_LOG(SG_IO, SG_ALERT, "Error loading " << model_path << ":\n  " << t.getFormattedMessage() << t.getOrigin());
+            } catch (const sg_throwable& t) {
    +                return 0;
+                SG_LOG(SG_IO, SG_ALERT, "Error loading " << model_path << ":\n  " << t.getFormattedMessage() << t.getOrigin());
    +            } // error loading from relative path
+                return 0;
    +
+            } // error loading from relative path
    +            SG_LOG(SG_IO, SG_ALERT, "canvas::Model: No such model: '" << path << "'");
+
    +        } // relative path handling
+            SG_LOG(SG_IO, SG_ALERT, "canvas::Model: No such model: '" << path << "'");
    +
+        } // relative path handling
    +        return 0;
+
    +    }
+        return 0;
    +
+    }
      //----------------------------------------------------------------------------
+
      SGSubsystem*
//----------------------------------------------------------------------------
      FGCanvasSystemAdapter::getSubsystem(const std::string& name) const
SGSubsystem*
    @@ -121,4 +170,16 @@ namespace canvas
FGCanvasSystemAdapter::getSubsystem(const std::string& name) const
        return 0;
@@ -121,4 +170,16 @@ namespace canvas
      }
return 0;
   
}
    +  osg::Matrix FGCanvasSystemAdapter::getViewMatrix(int view_number, double dt) const
 
    +  {
+  osg::Matrix FGCanvasSystemAdapter::getViewMatrix(int view_number, double dt) const
    +        flightgear::View *view = globals->get_viewmgr()->get_view(view_number);
+  {
    +        view->update(dt);
+        flightgear::View *view = globals->get_viewmgr()->get_view(view_number);
    +
+        view->update(dt);
    +        osg::Vec3f position( toOsg(view->getViewPosition()) );
+
    +        osg::Quat orientation( toOsg(view->getViewOrientation()) );
+        osg::Vec3f position( toOsg(view->getViewPosition()) );
    +        osg::Matrix viewMatrix( osg::Matrix::translate(-position) * osg::Matrix::rotate(orientation.inverse()) );
+        osg::Quat orientation( toOsg(view->getViewOrientation()) );
    +
+        osg::Matrix viewMatrix( osg::Matrix::translate(-position) * osg::Matrix::rotate(orientation.inverse()) );
    +        return viewMatrix;
+
    +  }
+        return viewMatrix;
    +
+  }
    }
+
    diff --git a/src/Canvas/FGCanvasSystemAdapter.hxx b/src/Canvas/FGCanvasSystemAdapter.hxx
}
    index 4c1fd6210..24ececb41 100644
diff --git a/src/Canvas/FGCanvasSystemAdapter.hxx b/src/Canvas/FGCanvasSystemAdapter.hxx
    --- a/src/Canvas/FGCanvasSystemAdapter.hxx
index 4c1fd6210..24ececb41 100644
    +++ b/src/Canvas/FGCanvasSystemAdapter.hxx
--- a/src/Canvas/FGCanvasSystemAdapter.hxx
    @@ -28,11 +28,13 @@ namespace canvas
+++ b/src/Canvas/FGCanvasSystemAdapter.hxx
      {
@@ -28,11 +28,13 @@ namespace canvas
        public:
{
          virtual simgear::canvas::FontPtr getFont(const std::string& name) const;
public:
    -      virtual void addCamera(osg::Camera* camera) const;
virtual simgear::canvas::FontPtr getFont(const std::string& name) const;
    +      virtual void addCamera(osg::Camera* camera, bool useSceneData = false) const;
-      virtual void addCamera(osg::Camera* camera) const;
          virtual void removeCamera(osg::Camera* camera) const;
+      virtual void addCamera(osg::Camera* camera, bool useSceneData = false) const;
          virtual osg::ref_ptr<osg::Image> getImage(const std::string& path) const;
virtual void removeCamera(osg::Camera* camera) const;
    +      virtual osg::Node* getModel(const std::string& path) const;
virtual osg::ref_ptr<osg::Image> getImage(const std::string& path) const;
          virtual SGSubsystem* getSubsystem(const std::string& name) const;
+      virtual osg::Node* getModel(const std::string& path) const;
          virtual simgear::HTTP::Client* getHTTPClient() const;
virtual SGSubsystem* getSubsystem(const std::string& name) const;
    +      virtual osg::Matrix getViewMatrix(int view_number, double dt) const;
virtual simgear::HTTP::Client* getHTTPClient() const;
      };
+      virtual osg::Matrix getViewMatrix(int view_number, double dt) const;
    }
};
   
}
    diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx
 
    index d9e8f351f..b9b3fc6a0 100644
diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx
    --- a/src/Viewer/renderer.cxx
index d9e8f351f..b9b3fc6a0 100644
    +++ b/src/Viewer/renderer.cxx
--- a/src/Viewer/renderer.cxx
    @@ -1845,6 +1845,8 @@ FGRenderer::setEventHandler(FGEventHandler* eventHandler_)
+++ b/src/Viewer/renderer.cxx
    void
@@ -1845,6 +1845,8 @@ FGRenderer::setEventHandler(FGEventHandler* eventHandler_)
    FGRenderer::addCamera(osg::Camera* camera, bool useSceneData)
void
    {
FGRenderer::addCamera(osg::Camera* camera, bool useSceneData)
    +    if (useSceneData)
{
    +        camera->addChild(globals->get_scenery()->get_scene_graph());
+    if (useSceneData)
        _viewerSceneRoot->addChild(camera);
+        camera->addChild(globals->get_scenery()->get_scene_graph());
    }
_viewerSceneRoot->addChild(camera);
}
 


</syntaxhighlight>
</syntaxhighlight>


 
fgdata
<syntaxhighlight lang="diff">diff --git a/Nasal/canvas/api.nas b/Nasal/canvas/api.nas
<syntaxhighlight lang="diff">
diff --git a/Nasal/canvas/api.nas b/Nasal/canvas/api.nas
index 3f7f5a17..433a41f9 100644
index 3f7f5a17..433a41f9 100644
--- a/Nasal/canvas/api.nas
--- a/Nasal/canvas/api.nas

Navigation menu