]> git.mxchange.org Git - flightgear.git/commitdiff
add a command to print information about visible objects in the scene
authorTim Moore <moore@cline.(none)>
Sun, 14 Nov 2010 14:12:58 +0000 (15:12 +0100)
committerTim Moore <moore@cline.(none)>
Sun, 14 Nov 2010 23:09:52 +0000 (00:09 +0100)
src/GUI/gui.h
src/GUI/gui_funcs.cxx
src/Main/fg_commands.cxx
src/Main/renderer.cxx
src/Main/renderer.hxx

index 4ea7b588de5558b77bfe53c870855a1c3d79fda3..d6570c7e41331ca97913bd4b8aff671c76f6fdd6 100644 (file)
@@ -49,6 +49,7 @@ extern void guiErrorMessage(const char *txt, const sg_throwable &throwable);
 extern bool fgDumpSnapShot();
 extern void fgDumpSceneGraph();
 extern void fgDumpTerrainBranch();
+extern void fgPrintVisibleSceneInfoCommand();
 
 extern puFont guiFnt;
 extern fntTexFont *guiFntHandle;
index ff6971549c1aee4ee53375dd35a3f5bff543618c..ccbd0a550223df98b575399a1e2113e9eb917f11 100644 (file)
@@ -555,5 +555,22 @@ void fgDumpTerrainBranch()
     }
 }
 
+void fgPrintVisibleSceneInfoCommand()
+{
+    static const SGPropertyNode *master_freeze
+        = fgGetNode("/sim/freeze/master");
+
+    bool freeze = master_freeze->getBoolValue();
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", true);
+    }
+
+    flightgear::printVisibleSceneInfo(globals->get_renderer());
+
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", false);
+    }
+}
+
     
 
index e3b6be0c0f3817374ad1bdbd59a2f1816d82d893..c3c60fbec236f98a692e0aa3cd8b01ba41444203 100644 (file)
@@ -518,6 +518,13 @@ do_dump_terrain_branch (const SGPropertyNode*)
     return true;
 }
 
+static bool
+do_print_visible_scene_info(const SGPropertyNode*)
+{
+    fgPrintVisibleSceneInfoCommand();
+    return true;
+}
+
 /**
  * Built-in command: hires capture screen.
  */
@@ -1488,6 +1495,7 @@ static struct {
     { "release-cockpit-button", do_release_cockpit_button },
     { "dump-scenegraph", do_dump_scene_graph },
     { "dump-terrainbranch", do_dump_terrain_branch },
+    { "print-visible-scene", do_print_visible_scene_info },
     { "reload-shaders", do_reload_shaders },
     { 0, 0 }                   // zero-terminated
 };
index e16fb3d55821780a91715002edfe7ae047e45481..6eb3d3f688b2bfb9ecb31a839cb04c7d1e35ba0a 100644 (file)
 
 #include <simgear/compiler.h>
 
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <typeinfo>
+
 #include <osg/ref_ptr>
 #include <osg/AlphaFunc>
 #include <osg/BlendFunc>
 #include <osg/Camera>
 #include <osg/CullFace>
+#include <osg/CullStack>
 #include <osg/Depth>
 #include <osg/Fog>
 #include <osg/Group>
@@ -823,5 +830,207 @@ fgDumpNodeToFile(osg::Node* node, const char* filename)
 {
     return osgDB::writeNodeFile(*node, filename);
 }
+
+namespace flightgear
+{
+using namespace osg;
+
+class VisibleSceneInfoVistor : public NodeVisitor, CullStack
+{
+public:
+    VisibleSceneInfoVistor()
+        : NodeVisitor(CULL_VISITOR, TRAVERSE_ACTIVE_CHILDREN)
+    {
+        setCullingMode(CullSettings::SMALL_FEATURE_CULLING
+                       | CullSettings::VIEW_FRUSTUM_CULLING);
+        setComputeNearFarMode(CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    }
+
+    VisibleSceneInfoVistor(const VisibleSceneInfoVistor& rhs)
+    {
+    }
+
+    META_NodeVisitor("flightgear","VisibleSceneInfoVistor")
+
+    typedef std::map<const std::string,int> InfoMap;
+
+    void getNodeInfo(Node* node)
+    {
+        const char* typeName = typeid(*node).name();
+        classInfo[typeName]++;
+        const std::string& nodeName = node->getName();
+        if (!nodeName.empty())
+            nodeInfo[nodeName]++;
+    }
+
+    void dumpInfo()
+    {
+        using namespace std;
+        typedef vector<InfoMap::iterator> FreqVector;
+        cout << "class info:\n";
+        FreqVector classes;
+        for (InfoMap::iterator itr = classInfo.begin(), end = classInfo.end();
+             itr != end;
+             ++itr)
+            classes.push_back(itr);
+        sort(classes.begin(), classes.end(), freqComp);
+        for (FreqVector::iterator itr = classes.begin(), end = classes.end();
+             itr != end;
+             ++itr) {
+            cout << (*itr)->first << " " << (*itr)->second << "\n";
+        }
+        cout << "\nnode info:\n";
+        FreqVector nodes;
+        for (InfoMap::iterator itr = nodeInfo.begin(), end = nodeInfo.end();
+             itr != end;
+             ++itr)
+            nodes.push_back(itr);
+
+        sort (nodes.begin(), nodes.end(), freqComp);
+        for (FreqVector::iterator itr = nodes.begin(), end = nodes.end();
+             itr != end;
+             ++itr) {
+            cout << (*itr)->first << " " << (*itr)->second << "\n";
+        }
+        cout << endl;
+    }
+    
+    void doTraversal(Camera* camera, Node* root, Viewport* viewport)
+    {
+        ref_ptr<RefMatrix> projection
+            = createOrReuseMatrix(camera->getProjectionMatrix());
+        ref_ptr<RefMatrix> mv = createOrReuseMatrix(camera->getViewMatrix());
+        if (!viewport)
+            viewport = camera->getViewport();
+        if (viewport)
+            pushViewport(viewport);
+        pushProjectionMatrix(projection.get());
+        pushModelViewMatrix(mv.get(), Transform::ABSOLUTE_RF);
+        root->accept(*this);
+        popModelViewMatrix();
+        popProjectionMatrix();
+        if (viewport)
+            popViewport();
+        dumpInfo();
+    }
+
+    void apply(Node& node)
+    {
+        if (isCulled(node))
+            return;
+        pushCurrentMask();
+        getNodeInfo(&node);
+        traverse(node);
+        popCurrentMask();
+    }
+    void apply(Group& node)
+    {
+        if (isCulled(node))
+            return;
+        pushCurrentMask();
+        getNodeInfo(&node);
+        traverse(node);
+        popCurrentMask();
+    }
+
+    void apply(Transform& node)
+    {
+        if (isCulled(node))
+            return;
+        pushCurrentMask();
+        ref_ptr<RefMatrix> matrix = createOrReuseMatrix(*getModelViewMatrix());
+        node.computeLocalToWorldMatrix(*matrix,this);
+        pushModelViewMatrix(matrix.get(), node.getReferenceFrame());
+        getNodeInfo(&node);
+        traverse(node);
+        popModelViewMatrix();
+        popCurrentMask();
+    }
+
+    void apply(Camera& camera)
+    {
+        // Save current cull settings
+        CullSettings saved_cull_settings(*this);
+
+        // set cull settings from this Camera
+        setCullSettings(camera);
+        // inherit the settings from above
+        inheritCullSettings(saved_cull_settings, camera.getInheritanceMask());
+
+        // set the cull mask.
+        unsigned int savedTraversalMask = getTraversalMask();
+        bool mustSetCullMask = (camera.getInheritanceMask()
+                                & osg::CullSettings::CULL_MASK) == 0;
+        if (mustSetCullMask)
+            setTraversalMask(camera.getCullMask());
+
+        osg::RefMatrix* projection = 0;
+        osg::RefMatrix* modelview = 0;
+
+        if (camera.getReferenceFrame()==osg::Transform::RELATIVE_RF) {
+            if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY) {
+                projection = createOrReuseMatrix(*getProjectionMatrix()
+                                                 *camera.getProjectionMatrix());
+                modelview = createOrReuseMatrix(*getModelViewMatrix()
+                                                * camera.getViewMatrix());
+            }
+            else {              // pre multiply 
+                projection = createOrReuseMatrix(camera.getProjectionMatrix()
+                                                 * (*getProjectionMatrix()));
+                modelview = createOrReuseMatrix(camera.getViewMatrix()
+                                                * (*getModelViewMatrix()));
+            }
+        } else {
+            // an absolute reference frame
+            projection = createOrReuseMatrix(camera.getProjectionMatrix());
+            modelview = createOrReuseMatrix(camera.getViewMatrix());
+        }
+        if (camera.getViewport())
+            pushViewport(camera.getViewport());
+
+        pushProjectionMatrix(projection);
+        pushModelViewMatrix(modelview, camera.getReferenceFrame());    
+
+        traverse(camera);
+    
+        // restore the previous model view matrix.
+        popModelViewMatrix();
+
+        // restore the previous model view matrix.
+        popProjectionMatrix();
+
+        if (camera.getViewport()) popViewport();
+
+        // restore the previous traversal mask settings
+        if (mustSetCullMask)
+            setTraversalMask(savedTraversalMask);
+
+        // restore the previous cull settings
+        setCullSettings(saved_cull_settings);
+    }
+
+protected:
+    // sort in reverse
+    static bool freqComp(const InfoMap::iterator& lhs, const InfoMap::iterator& rhs)
+    {
+        return lhs->second > rhs->second;
+    }
+    InfoMap classInfo;
+    InfoMap nodeInfo;
+};
+
+bool printVisibleSceneInfo(FGRenderer* renderer)
+{
+    osgViewer::Viewer* viewer = renderer->getViewer();
+    VisibleSceneInfoVistor vsv;
+    Viewport* vp = 0;
+    if (!viewer->getCamera()->getViewport() && viewer->getNumSlaves() > 0) {
+        const View::Slave& slave = viewer->getSlave(0);
+        vp = slave._camera->getViewport();
+    }
+    vsv.doTraversal(viewer->getCamera(), viewer->getSceneData(), vp);
+    return true;
+}
+}
 // end of renderer.cxx
     
index 5fd8e9b36f652fdb91735920215e276017602ca3..2ed51be1a71858eb9f2b63cbf608aa6aeaf5afdf 100644 (file)
@@ -81,4 +81,9 @@ protected:
 bool fgDumpSceneGraphToFile(const char* filename);
 bool fgDumpTerrainBranchToFile(const char* filename);
 
+namespace flightgear
+{
+bool printVisibleSceneInfo(FGRenderer* renderer);
+}
+
 #endif