add a command to print information about visible objects in the scene
This commit is contained in:
parent
86b906e84e
commit
38e1600bed
5 changed files with 240 additions and 0 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -29,11 +29,18 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -81,4 +81,9 @@ protected:
|
|||
bool fgDumpSceneGraphToFile(const char* filename);
|
||||
bool fgDumpTerrainBranchToFile(const char* filename);
|
||||
|
||||
namespace flightgear
|
||||
{
|
||||
bool printVisibleSceneInfo(FGRenderer* renderer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue