# include <config.h>
#endif
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+
#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>
#include <osg/LightModel>
#include <osg/LightSource>
#include <osg/Material>
+#include <osg/Math>
#include <osg/NodeCallback>
#include <osg/Notify>
#include <osg/PolygonMode>
#include <osg/PolygonOffset>
-#include <osg/ShadeModel>
+#include <osg/Program>
#include <osg/Version>
#include <osg/TexEnv>
-#include <osgUtil/SceneView>
-#include <osgUtil/UpdateVisitor>
-#include <osgUtil/IntersectVisitor>
#include <osgUtil/LineSegmentIntersector>
#include <osg/io_utils>
#include <osgDB/WriteFile>
-#include <osgDB/ReadFile>
-#include <sstream>
#include <simgear/math/SGMath.hxx>
-#include <simgear/screen/extensions.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/model/animation.hxx>
#include <simgear/scene/model/placement.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
+#include <simgear/scene/util/SGSceneUserData.hxx>
#include <simgear/scene/tgdb/GroundLightManager.hxx>
#include <simgear/scene/tgdb/pt_lights.hxx>
+#include <simgear/structure/OSGUtils.hxx>
#include <simgear/props/props.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/ephemeris/ephemeris.hxx>
#include <Time/light.hxx>
#include <Time/light.hxx>
-#include <Aircraft/aircraft.hxx>
#include <Cockpit/panel.hxx>
-#include <Cockpit/cockpit.hxx>
-#include <Cockpit/hud.hxx>
#include <Model/panelnode.hxx>
#include <Model/modelmgr.hxx>
#include <Model/acmodel.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/redout.hxx>
-#include <Scenery/tilemgr.hxx>
#include <GUI/new_gui.hxx>
-#include <Instrumentation/instrument_mgr.hxx>
#include <Instrumentation/HUD/HUD.hxx>
#include <Environment/precipitation_mgr.hxx>
-#include <Include/general.hxx>
#include "splash.hxx"
#include "renderer.hxx"
#include "main.hxx"
#include "CameraGroup.hxx"
-#include "ViewPartitionNode.hxx"
-
-// XXX Make this go away when OSG 2.2 is released.
-#if (FG_OSG_VERSION >= 21004)
-#define UPDATE_VISITOR_IN_VIEWER 1
-#endif
+#include "FGEventHandler.hxx"
+#include <Main/viewer.hxx>
+#include <Main/viewmgr.hxx>
+using namespace osg;
+using namespace simgear;
using namespace flightgear;
class FGHintUpdateCallback : public osg::StateAttribute::Callback {
{
// Dynamic stuff, do not store geometry
setUseDisplayList(false);
+ setDataVariance(Object::DYNAMIC);
osg::StateSet* stateSet = getOrCreateStateSet();
stateSet->setRenderBinDetails(1001, "RenderBin");
{
// Dynamic stuff, do not store geometry
setUseDisplayList(false);
+ setDataVariance(Object::DYNAMIC);
osg::StateSet* stateSet = getOrCreateStateSet();
stateSet->setRenderBinDetails(1000, "RenderBin");
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(~0u);
- fgCockpitUpdate(&state);
-
- FGInstrumentMgr *instr = static_cast<FGInstrumentMgr*>(globals->get_subsystem("instrumentation"));
- HUD *hud = static_cast<HUD*>(instr->get_subsystem("hud"));
+ HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
hud->draw(state);
// update the panel subsystem
class FGLightSourceUpdateCallback : public osg::NodeCallback {
public:
+
+ /**
+ * @param isSun true if the light is the actual sun i.e., for
+ * illuminating the moon.
+ */
+ FGLightSourceUpdateCallback(bool isSun = false) : _isSun(isSun) {}
+ FGLightSourceUpdateCallback(const FGLightSourceUpdateCallback& nc,
+ const CopyOp& op)
+ : NodeCallback(nc, op), _isSun(nc._isSun)
+ {}
+ META_Object(flightgear,FGLightSourceUpdateCallback);
+
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
assert(dynamic_cast<osg::LightSource*>(node));
osg::Light* light = lightSource->getLight();
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
- light->setAmbient(l->scene_ambient().osg());
- light->setDiffuse(l->scene_diffuse().osg());
- light->setSpecular(l->scene_specular().osg());
- SGVec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0);
- light->setPosition(position.osg());
- SGVec3f direction(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]);
- light->setDirection(direction.osg());
- light->setSpotExponent(0);
- light->setSpotCutoff(180);
- light->setConstantAttenuation(1);
- light->setLinearAttenuation(0);
- light->setQuadraticAttenuation(0);
+ if (_isSun) {
+ light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
+ light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
+ light->setSpecular(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
+ } else {
+ light->setAmbient(toOsg(l->scene_ambient()));
+ light->setDiffuse(toOsg(l->scene_diffuse()));
+ light->setSpecular(toOsg(l->scene_specular()));
+ }
+ osg::Vec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0);
+ light->setPosition(position);
traverse(node, nv);
}
+private:
+ const bool _isSun;
};
class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback {
#if 0
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
- lightModel->setAmbientIntensity(l->scene_ambient().osg());
+ lightModel->setAmbientIntensity(toOsg(l->scene_ambient());
#else
lightModel->setAmbientIntensity(osg::Vec4(0, 0, 0, 1));
#endif
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
osg::Fog* fog = static_cast<osg::Fog*>(sa);
fog->setMode(osg::Fog::EXP2);
- fog->setColor(updateVisitor->getFogColor().osg());
+ fog->setColor(toOsg(updateVisitor->getFogColor()));
fog->setDensity(updateVisitor->getFogExp2Density());
}
};
static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
-static osg::ref_ptr<ViewPartitionNode> viewPartition = new ViewPartitionNode;
-
FGRenderer::FGRenderer()
{
#ifdef FG_JPEG_SERVER
jpgRenderFrame = FGRenderer::update;
#endif
- manipulator = new FGManipulator;
+ eventHandler = new FGEventHandler;
}
FGRenderer::~FGRenderer()
// Scene doesn't seem to pass the frame stamp to the update
// visitor automatically.
mUpdateVisitor->setFrameStamp(mFrameStamp.get());
-#ifdef UPDATE_VISITOR_IN_VIEWER
viewer->setUpdateVisitor(mUpdateVisitor.get());
-#else
- osgViewer::Scene* scene = viewer->getScene();
- scene->setUpdateVisitor(mUpdateVisitor.get());
-#endif
}
void
//sceneGroup->addChild(thesky->getCloudRoot());
stateSet = sceneGroup->getOrCreateStateSet();
- stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
// need to update the light on every frame
- osg::LightSource* lightSource = new osg::LightSource;
- lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
+ // OSG LightSource objects are rather confusing. OSG only supports
+ // the 10 lights specified by OpenGL itself; if more than one
+ // LightSource in the scene graph have the same light number, it's
+ // indeterminate which values will be used to render geometry that
+ // has that light number enabled. Also, adding children to a
+ // LightSource is just a shortcut for setting up a state set that
+ // has the corresponding OpenGL light enabled: a LightSource will
+ // affect geometry anywhere in the scene graph that has its light
+ // number enabled in a state set.
+ LightSource* lightSource = new LightSource;
+ lightSource->getLight()->setDataVariance(Object::DYNAMIC);
// relative because of CameraView being just a clever transform node
lightSource->setReferenceFrame(osg::LightSource::RELATIVE_RF);
lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
-
- lightSource->addChild(sceneGroup);
- lightSource->addChild(thesky->getPreRoot());
- mRoot->addChild(lightSource);
-
+ lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
+ mRealRoot->addChild(lightSource);
+ // we need a white diffuse light for the phase of the moon
+ osg::LightSource* sunLight = new osg::LightSource;
+ sunLight->getLight()->setDataVariance(Object::DYNAMIC);
+ sunLight->getLight()->setLightNum(1);
+ sunLight->setUpdateCallback(new FGLightSourceUpdateCallback(true));
+ sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF);
+ sunLight->setLocalStateSetModes(osg::StateAttribute::ON);
+ // Hang a StateSet above the sky subgraph in order to turn off
+ // light 0
+ Group* skyGroup = new Group;
+ StateSet* skySS = skyGroup->getOrCreateStateSet();
+ skySS->setMode(GL_LIGHT0, StateAttribute::OFF);
+ skyGroup->addChild(thesky->getPreRoot());
+ sunLight->addChild(skyGroup);
+ mRoot->addChild(sceneGroup);
+ mRoot->addChild(sunLight);
+ // Clouds are added to the scene graph later
stateSet = globals->get_scenery()->get_scene_graph()->getOrCreateStateSet();
- stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
osg::Switch* sw = new osg::Switch;
sw->setUpdateCallback(new FGScenerySwitchCallback);
sw->addChild(mRoot.get());
- viewPartition->addChild(sw);
- viewPartition->addChild(thesky->getCloudRoot());
-
- mRealRoot->addChild(viewPartition.get());
+ mRealRoot->addChild(sw);
+ // The clouds are attached directly to the scene graph root
+ // because, in theory, they don't want the same default state set
+ // as the rest of the scene. This may not be true in practice.
+ mRealRoot->addChild(thesky->getCloudRoot());
mRealRoot->addChild(FGCreateRedoutNode());
+ // Attach empty program to the scene root so that shader programs
+ // don't leak into state sets (effects) that shouldn't have one.
+ stateSet = mRealRoot->getOrCreateStateSet();
+ stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
}
// Update all Visuals (redraws anything graphics related)
void
FGRenderer::update( bool refresh_camera_settings ) {
- bool scenery_loaded = fgGetBool("sim/sceneryloaded")
+ bool scenery_loaded = fgGetBool("sim/sceneryloaded", false)
|| fgGetBool("sim/sceneryloaded-override");
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
- if ( idle_state < 1000 || !scenery_loaded ) {
- fgSetDouble("/sim/startup/splash-alpha", 1.0);
-
- // Keep resetting sim time while the sim is initializing
- // the splash screen is now in the scenegraph
- globals->set_sim_time_sec( 0.0 );
- return;
+ if (!scenery_loaded) {
+ fgSetDouble("/sim/startup/splash-alpha", 1.0);
+ return;
}
// Fade out the splash screen over the first three seconds.
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
distance_attenuation );
- static const SGPropertyNode *groundlevel_nearplane
- = fgGetNode("/sim/current-view/ground-level-nearplane-m");
-
FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
// update fog params
// update view port
resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
-#if 0
- SGVec3d position = current__view->getViewPosition();
- SGQuatd attitude = current__view->getViewOrientation();
-
- FGManipulator *manipulator = globals->get_renderer()->getManipulator();
- manipulator->setPosition(position.osg());
- manipulator->setAttitude(attitude.osg());
-#endif
}
osg::Camera *camera = viewer->getCamera();
if ( fgGetBool("/sim/rendering/textures") ) {
SGVec4f clearColor(l->adj_fog_color());
- camera->setClearColor(clearColor.osg());
+ camera->setClearColor(toOsg(clearColor));
}
} else {
SGVec4f clearColor(l->sky_color());
- camera->setClearColor(clearColor.osg());
+ camera->setClearColor(toOsg(clearColor));
}
// update fog params if visibility has changed
double visibility_meters = fgGetDouble("/environment/visibility-m");
thesky->set_visibility(visibility_meters);
- thesky->modify_vis( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
- ( global_multi_loop * fgGetInt("/sim/speed-up") )
- / (double)fgGetInt("/sim/model-hz") );
+ double altitude_m = fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER;
+ thesky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
// update the sky dome
if ( skyblend ) {
double sun_horiz_eff, moon_horiz_eff;
if (fgGetBool("/sim/rendering/horizon-effect")) {
- sun_horiz_eff = 0.67+pow(0.5+cos(l->get_sun_angle())*2/2, 0.33)/3;
- moon_horiz_eff = 0.67+pow(0.5+cos(l->get_moon_angle())*2/2, 0.33)/3;
+ sun_horiz_eff
+ = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
+ 0.0),
+ 0.33) / 3.0;
+ moon_horiz_eff
+ = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_moon_angle()),
+ 0.0),
+ 0.33)/3.0;
} else {
sun_horiz_eff = moon_horiz_eff = 1.0;
}
- static SGSkyState sstate;
-
- sstate.view_pos = toVec3f(current__view->get_view_pos());
- sstate.zero_elev = toVec3f(current__view->get_zero_elev());
- sstate.view_up = current__view->get_world_up();
- sstate.lon = current__view->getLongitude_deg()
- * SGD_DEGREES_TO_RADIANS;
- sstate.lat = current__view->getLatitude_deg()
- * SGD_DEGREES_TO_RADIANS;
- sstate.alt = current__view->getAltitudeASL_ft()
- * SG_FEET_TO_METER;
+ SGSkyState sstate;
+ sstate.pos = current__view->getViewPosition();
+ sstate.pos_geod = current__view->getPosition();
+ sstate.ori = current__view->getViewOrientation();
sstate.spin = l->get_sun_rotation();
sstate.gst = globals->get_time_params()->getGst();
- sstate.sun_ra = globals->get_ephem()->getSunRightAscension();
- sstate.sun_dec = globals->get_ephem()->getSunDeclination();
sstate.sun_dist = 50000.0 * sun_horiz_eff;
- sstate.moon_ra = globals->get_ephem()->getMoonRightAscension();
- sstate.moon_dec = globals->get_ephem()->getMoonDeclination();
sstate.moon_dist = 40000.0 * moon_horiz_eff;
sstate.sun_angle = l->get_sun_angle();
-
- /*
- SG_LOG( SG_GENERAL, SG_BULK, "thesky->repaint() sky_color = "
- << l->sky_color()[0] << " "
- << l->sky_color()[1] << " "
- << l->sky_color()[2] << " "
- << l->sky_color()[3] );
- SG_LOG( SG_GENERAL, SG_BULK, " fog = "
- << l->fog_color()[0] << " "
- << l->fog_color()[1] << " "
- << l->fog_color()[2] << " "
- << l->fog_color()[3] );
- SG_LOG( SG_GENERAL, SG_BULK,
- " sun_angle = " << l->sun_angle
- << " moon_angle = " << l->moon_angle );
- */
-
- static SGSkyColor scolor;
-
+ SGSkyColor scolor;
scolor.sky_color = SGVec3f(l->sky_color().data());
+ scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data());
scolor.fog_color = SGVec3f(l->adj_fog_color().data());
scolor.cloud_color = SGVec3f(l->cloud_color().data());
scolor.sun_angle = l->get_sun_angle();
scolor.moon_angle = l->get_moon_angle();
- scolor.nplanets = globals->get_ephem()->getNumPlanets();
- scolor.nstars = globals->get_ephem()->getNumStars();
- scolor.planet_data = globals->get_ephem()->getPlanets();
- scolor.star_data = globals->get_ephem()->getStars();
-
- thesky->reposition( sstate, delta_time_sec );
- thesky->repaint( scolor );
-
- /*
- SG_LOG( SG_GENERAL, SG_BULK,
- "thesky->reposition( view_pos = " << view_pos[0] << " "
- << view_pos[1] << " " << view_pos[2] );
- SG_LOG( SG_GENERAL, SG_BULK,
- " zero_elev = " << zero_elev[0] << " "
- << zero_elev[1] << " " << zero_elev[2]
- << " lon = " << cur_fdm_state->get_Longitude()
- << " lat = " << cur_fdm_state->get_Latitude() );
- SG_LOG( SG_GENERAL, SG_BULK,
- " sun_rot = " << l->get_sun_rotation
- << " gst = " << SGTime::cur_time_params->getGst() );
- SG_LOG( SG_GENERAL, SG_BULK,
- " sun ra = " << globals->get_ephem()->getSunRightAscension()
- << " sun dec = " << globals->get_ephem()->getSunDeclination()
- << " moon ra = " << globals->get_ephem()->getMoonRightAscension()
- << " moon dec = " << globals->get_ephem()->getMoonDeclination() );
- */
-
- //OSGFIXME
+
+ double delta_time_sec = fgGetDouble("/sim/time/delta-sec");
+ thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
+ thesky->repaint( scolor, *globals->get_ephem() );
+
+ //OSGFIXME
// shadows->setupShadows(
// current__view->getLongitude_deg(),
// current__view->getLatitude_deg(),
}
// sgEnviro.setLight(l->adj_fog_color());
-#if 0
- double agl = current__view->getAltitudeASL_ft()*SG_FEET_TO_METER
- - current__view->getSGLocation()->get_cur_elev_m();
-
- float scene_nearplane, scene_farplane;
- // XXX Given that the own airplane model is part of the scene
- // graph, should this business be ripped out? The near plane is
- // ignored by setCameraParameters.
- if ( agl > 10.0 ) {
- scene_nearplane = 10.0f;
- scene_farplane = 120000.0f;
- } else {
- scene_nearplane = groundlevel_nearplane->getDoubleValue();
- scene_farplane = 120000.0f;
- }
- setCameraParameters(current__view->get_v_fov(),
- current__view->get_aspect_ratio(),
- scene_nearplane, scene_farplane);
-#endif
// sgEnviro.startOfFrame(current__view->get_view_pos(),
// current__view->get_world_up(),
// current__view->getLongitude_deg(),
l->adj_fog_color(),
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
mUpdateVisitor->setVisibility(actual_visibility);
- viewPartition->setVisibility(actual_visibility);
simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
bool hotspots = fgGetBool("/sim/panel-hotspots");
- osg::Node::NodeMask cullMask = (~simgear::LIGHTS_BITS & ~simgear::PICK_BIT
- & ~simgear::BACKGROUND_BIT);
+ osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
cullMask |= simgear::GroundLightManager::instance()
->getLightNodeMask(mUpdateVisitor.get());
if (hotspots)
cullMask |= simgear::PICK_BIT;
- camera->setCullMask(cullMask);
- // XXX
- for (int i = 0; i < viewer->getNumSlaves(); ++i)
- viewer->getSlave(i)._camera->setCullMask(cullMask);
+ CameraGroup::getDefault()->setCameraCullMasks(cullMask);
}
}
}
-void FGRenderer::setCameraParameters(float vfov, float aspectRatio,
- float zNear, float zFar)
-{
- zNear = .1;
- osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
- viewer->getCamera()->setProjectionMatrixAsPerspective(vfov,
- 1.0f / aspectRatio,
- zNear, zFar);
-
-}
bool
FGRenderer::pick(std::vector<SGSceneryPick>& pickList,
const osgGA::GUIEventAdapter* ea)
{
- osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
// wipe out the return ...
pickList.clear();
typedef osgUtil::LineSegmentIntersector::Intersections Intersections;
if (!pickCallback)
continue;
SGSceneryPick sceneryPick;
- sceneryPick.info.local = SGVec3d(hit->getLocalIntersectPoint());
- sceneryPick.info.wgs84 = SGVec3d(hit->getWorldIntersectPoint());
+ sceneryPick.info.local = toSG(hit->getLocalIntersectPoint());
+ sceneryPick.info.wgs84 = toSG(hit->getWorldIntersectPoint());
sceneryPick.callback = pickCallback;
pickList.push_back(sceneryPick);
}
return !pickList.empty();
}
+void
+FGRenderer::setViewer(osgViewer::Viewer* viewer_)
+{
+ viewer = viewer_;
+}
+
+void
+FGRenderer::setEventHandler(FGEventHandler* eventHandler_)
+{
+ eventHandler = eventHandler_;
+}
+
void
FGRenderer::addCamera(osg::Camera* camera, bool useSceneData)
{
{
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