Lazy-loading of the 2D panel node.
Sink the 2D panel logic into FGPanelNode, simplifying renderer.cxx and a few other places. Also allows potential for unloading / paging of 2.5D panels in the future.
This commit is contained in:
parent
77cd7b39f7
commit
8f10fff8dc
10 changed files with 243 additions and 313 deletions
|
@ -93,28 +93,6 @@ get_aspect_adjust (int xsize, int ysize)
|
|||
float real_aspect = float(xsize) / float(ysize);
|
||||
return (real_aspect / ideal_aspect);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Global functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
fgPanelVisible ()
|
||||
{
|
||||
const FGPanel* current = globals->get_current_panel();
|
||||
if (current == 0)
|
||||
return false;
|
||||
if (current->getVisibility() == 0)
|
||||
return false;
|
||||
if (globals->get_viewmgr()->get_current() != 0)
|
||||
return false;
|
||||
if (current->getAutohide() && globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGTextureManager.
|
||||
|
@ -201,8 +179,6 @@ FGPanel::FGPanel ()
|
|||
: _mouseDown(false),
|
||||
_mouseInstrument(0),
|
||||
_width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
|
||||
// _view_height(int(WIN_H * 0.4232)),
|
||||
_visibility(fgGetNode("/sim/panel/visibility", true)),
|
||||
_x_offset(fgGetNode("/sim/panel/x-offset", true)),
|
||||
_y_offset(fgGetNode("/sim/panel/y-offset", true)),
|
||||
_jitter(fgGetNode("/sim/panel/jitter", true)),
|
||||
|
@ -210,6 +186,7 @@ FGPanel::FGPanel ()
|
|||
_xsize_node(fgGetNode("/sim/startup/xsize", true)),
|
||||
_ysize_node(fgGetNode("/sim/startup/ysize", true)),
|
||||
_enable_depth_test(false),
|
||||
_autohide(true),
|
||||
_drawPanelHotspots("/sim/panel-hotspots")
|
||||
{
|
||||
}
|
||||
|
@ -238,44 +215,6 @@ FGPanel::addInstrument (FGPanelInstrument * instrument)
|
|||
_instruments.push_back(instrument);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the panel.
|
||||
*/
|
||||
void
|
||||
FGPanel::init ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind panel properties.
|
||||
*/
|
||||
void
|
||||
FGPanel::bind ()
|
||||
{
|
||||
fgSetArchivable("/sim/panel/visibility");
|
||||
fgSetArchivable("/sim/panel/x-offset");
|
||||
fgSetArchivable("/sim/panel/y-offset");
|
||||
fgSetArchivable("/sim/panel/jitter");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unbind panel properties.
|
||||
*/
|
||||
void
|
||||
FGPanel::unbind ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FGPanel::update (double dt)
|
||||
{
|
||||
updateMouseDelay(dt);
|
||||
}
|
||||
|
||||
double
|
||||
FGPanel::getAspectScale() const
|
||||
{
|
||||
|
@ -506,26 +445,6 @@ FGPanel::draw(osg::State& state)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the panel's visibility.
|
||||
*/
|
||||
void
|
||||
FGPanel::setVisibility (bool visibility)
|
||||
{
|
||||
_visibility->setBoolValue( visibility );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the panel is visible.
|
||||
*/
|
||||
bool
|
||||
FGPanel::getVisibility () const
|
||||
{
|
||||
return _visibility->getBoolValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the panel's background texture.
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/props/propertyObject.hxx>
|
||||
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/structure/SGBinding.hxx>
|
||||
#include <simgear/math/interpolater.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
@ -118,23 +117,15 @@ private:
|
|||
* redraw themselves when necessary, and will pass mouse clicks on to
|
||||
* the appropriate instruments for processing.
|
||||
*/
|
||||
class FGPanel : public SGSubsystem
|
||||
class FGPanel : public SGReferenced
|
||||
{
|
||||
public:
|
||||
|
||||
FGPanel ();
|
||||
virtual ~FGPanel ();
|
||||
|
||||
// Update the panel (every frame).
|
||||
virtual void init ();
|
||||
virtual void bind ();
|
||||
virtual void unbind ();
|
||||
virtual void draw (osg::State& state);
|
||||
virtual void update (double);
|
||||
|
||||
//void update (osg::State& state);
|
||||
//virtual void update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
|
||||
|
||||
virtual void updateMouseDelay(double dt);
|
||||
|
||||
// transfer pointer ownership!!!
|
||||
|
@ -146,11 +137,6 @@ public:
|
|||
// Background multiple textures.
|
||||
virtual void setMultiBackground (osg::Texture2D* texture, int idx);
|
||||
|
||||
// Make the panel visible or invisible.
|
||||
virtual bool getVisibility () const;
|
||||
virtual void setVisibility (bool visibility);
|
||||
|
||||
// Full width of panel.
|
||||
virtual void setWidth (int width) { _width = width; }
|
||||
virtual int getWidth () const { return _width; }
|
||||
|
||||
|
@ -201,7 +187,6 @@ private:
|
|||
int _height;
|
||||
// int _view_height;
|
||||
|
||||
SGPropertyNode_ptr _visibility;
|
||||
SGPropertyNode_ptr _x_offset;
|
||||
SGPropertyNode_ptr _y_offset;
|
||||
SGPropertyNode_ptr _jitter;
|
||||
|
@ -584,22 +569,7 @@ public:
|
|||
FGSwitchLayer ();
|
||||
virtual void draw (osg::State& state);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Test whether the panel should be visible.
|
||||
*/
|
||||
bool fgPanelVisible ();
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif // __PANEL_HXX
|
||||
|
||||
// end of panel.hxx
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include <simgear/misc/interpolator.hxx>
|
||||
#include <simgear/io/HTTPRequest.hxx>
|
||||
|
||||
#include <Cockpit/panel.hxx>
|
||||
#include <Cockpit/panel_io.hxx>
|
||||
#include <FDM/flight.hxx>
|
||||
#include <GUI/gui.h>
|
||||
#include <GUI/new_gui.hxx>
|
||||
|
@ -399,48 +397,15 @@ do_save (const SGPropertyNode * arg)
|
|||
static bool
|
||||
do_panel_load (const SGPropertyNode * arg)
|
||||
{
|
||||
string panel_path =
|
||||
arg->getStringValue("path", fgGetString("/sim/panel/path"));
|
||||
if (panel_path.empty()) {
|
||||
return false;
|
||||
string panel_path = arg->getStringValue("path");
|
||||
if (!panel_path.empty()) {
|
||||
// write to the standard property, which will force a load
|
||||
fgSetString("/sim/panel/path", panel_path.c_str());
|
||||
}
|
||||
|
||||
FGPanel * new_panel = fgReadPanel(panel_path);
|
||||
if (new_panel == 0) {
|
||||
SG_LOG(SG_INPUT, SG_ALERT,
|
||||
"Error reading new panel from " << panel_path);
|
||||
return false;
|
||||
}
|
||||
SG_LOG(SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path);
|
||||
globals->get_current_panel()->unbind();
|
||||
globals->set_current_panel( new_panel );
|
||||
globals->get_current_panel()->bind();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Built-in command: pass a mouse click to the panel.
|
||||
*
|
||||
* button: the mouse button number, zero-based.
|
||||
* is-down: true if the button is down, false if it is up.
|
||||
* x-pos: the x position of the mouse click.
|
||||
* y-pos: the y position of the mouse click.
|
||||
*/
|
||||
static bool
|
||||
do_panel_mouse_click (const SGPropertyNode * arg)
|
||||
{
|
||||
if (globals->get_current_panel() != 0)
|
||||
return globals->get_current_panel()
|
||||
->doMouseAction(arg->getIntValue("button"),
|
||||
arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
|
||||
arg->getIntValue("x-pos"),
|
||||
arg->getIntValue("y-pos"));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Built-in command: (re)load preferences.
|
||||
*
|
||||
|
@ -1519,7 +1484,6 @@ static struct {
|
|||
{ "load", do_load },
|
||||
{ "save", do_save },
|
||||
{ "panel-load", do_panel_load },
|
||||
{ "panel-mouse-click", do_panel_mouse_click },
|
||||
{ "preferences-load", do_preferences_load },
|
||||
{ "view-cycle", do_view_cycle },
|
||||
{ "screen-capture", do_screen_capture },
|
||||
|
|
|
@ -1196,20 +1196,11 @@ bool fgInitSubsystems() {
|
|||
// Add a new 2D panel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
string panel_path(fgGetString("/sim/panel/path"));
|
||||
if (!panel_path.empty()) {
|
||||
FGPanel* p = fgReadPanel(panel_path);
|
||||
if (p) {
|
||||
globals->set_current_panel(p);
|
||||
p->init();
|
||||
p->bind();
|
||||
SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
|
||||
} else {
|
||||
SG_LOG( SG_INPUT, SG_ALERT,
|
||||
"Error reading new panel from " << panel_path );
|
||||
}
|
||||
}
|
||||
|
||||
fgSetArchivable("/sim/panel/visibility");
|
||||
fgSetArchivable("/sim/panel/x-offset");
|
||||
fgSetArchivable("/sim/panel/y-offset");
|
||||
fgSetArchivable("/sim/panel/jitter");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the controls subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <Airports/runways.hxx>
|
||||
#include <ATCDCL/ATISmgr.hxx>
|
||||
#include <Autopilot/route_mgr.hxx>
|
||||
#include <Cockpit/panel.hxx>
|
||||
#include <GUI/FGFontCache.hxx>
|
||||
#include <GUI/gui.h>
|
||||
#include <Model/acmodel.hxx>
|
||||
|
@ -134,7 +133,6 @@ FGGlobals::FGGlobals() :
|
|||
mag( NULL ),
|
||||
matlib( NULL ),
|
||||
route_mgr( NULL ),
|
||||
current_panel( NULL ),
|
||||
ATIS_mgr( NULL ),
|
||||
controls( NULL ),
|
||||
viewmgr( NULL ),
|
||||
|
@ -189,7 +187,6 @@ FGGlobals::~FGGlobals()
|
|||
delete mag;
|
||||
delete matlib;
|
||||
delete route_mgr;
|
||||
current_panel = NULL;
|
||||
|
||||
delete ATIS_mgr;
|
||||
|
||||
|
@ -519,11 +516,4 @@ void FGGlobals::set_warp_delta( long int d )
|
|||
fgSetInt("/sim/time/warp-delta", d);
|
||||
}
|
||||
|
||||
void FGGlobals::set_current_panel( FGPanel *cp )
|
||||
{
|
||||
current_panel = cp;
|
||||
// poke the renderer to rebuild the scene node as necessary
|
||||
get_renderer()->panelChanged();
|
||||
}
|
||||
|
||||
// end of globals.cxx
|
||||
|
|
|
@ -65,7 +65,6 @@ class FGLocale;
|
|||
class FGModelMgr;
|
||||
class FGRouteMgr;
|
||||
class FGScenery;
|
||||
class FGPanel;
|
||||
class FGTileMgr;
|
||||
class FGViewMgr;
|
||||
class FGViewer;
|
||||
|
@ -119,9 +118,6 @@ private:
|
|||
// Global autopilot "route"
|
||||
FGRouteMgr *route_mgr;
|
||||
|
||||
// 2D panel
|
||||
SGSharedPtr<FGPanel> current_panel;
|
||||
|
||||
// ATC manager
|
||||
FGATISMgr *ATIS_mgr;
|
||||
|
||||
|
@ -243,9 +239,6 @@ public:
|
|||
inline FGATISMgr *get_ATIS_mgr() const { return ATIS_mgr; }
|
||||
inline void set_ATIS_mgr( FGATISMgr *a ) {ATIS_mgr = a; }
|
||||
|
||||
inline FGPanel *get_current_panel() const { return current_panel; }
|
||||
void set_current_panel( FGPanel *cp );
|
||||
|
||||
inline FGControls *get_controls() const { return controls; }
|
||||
inline void set_controls( FGControls *c ) { controls = c; }
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/Switch>
|
||||
#include <osg/BlendFunc>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
@ -18,13 +20,40 @@
|
|||
#include <simgear/scene/util/SGSceneUserData.hxx>
|
||||
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||
|
||||
#include <plib/pu.h>
|
||||
|
||||
#include <Main/fg_os.hxx>
|
||||
#include <Cockpit/panel.hxx>
|
||||
#include <Cockpit/panel_io.hxx>
|
||||
|
||||
#include "Viewer/viewer.hxx"
|
||||
|
||||
using std::vector;
|
||||
|
||||
static FGPanelNode* global_panel = NULL;
|
||||
|
||||
/**
|
||||
* Built-in command: pass a mouse click to the panel.
|
||||
*
|
||||
* button: the mouse button number, zero-based.
|
||||
* is-down: true if the button is down, false if it is up.
|
||||
* x-pos: the x position of the mouse click.
|
||||
* y-pos: the y position of the mouse click.
|
||||
*/
|
||||
static bool
|
||||
do_panel_mouse_click (const SGPropertyNode * arg)
|
||||
{
|
||||
if (global_panel)
|
||||
return global_panel->getPanel()
|
||||
->doMouseAction(arg->getIntValue("button"),
|
||||
arg->getBoolValue("is-down") ? PU_DOWN : PU_UP,
|
||||
arg->getIntValue("x-pos"),
|
||||
arg->getIntValue("y-pos"));
|
||||
else
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class FGPanelPickCallback : public SGPickCallback {
|
||||
public:
|
||||
FGPanelPickCallback(FGPanelNode* p) :
|
||||
|
@ -61,94 +90,146 @@ private:
|
|||
osg::Vec3 picked;
|
||||
};
|
||||
|
||||
class FGPanelSwitchCallback : public osg::NodeCallback {
|
||||
public:
|
||||
FGPanelSwitchCallback(FGPanelNode* pn) :
|
||||
panel(pn),
|
||||
visProp(fgGetNode("/sim/panel/visibility"))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<osg::Switch*>(node));
|
||||
osg::Switch* sw = static_cast<osg::Switch*>(node);
|
||||
|
||||
if (!visProp->getBoolValue()) {
|
||||
sw->setValue(0, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
panel->lazyLoad(); // isVisible check needs the panel loaded for auto-hide flag
|
||||
bool enabled = panel->isVisible2d();
|
||||
sw->setValue(0, enabled);
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
traverse(node, nv);
|
||||
}
|
||||
|
||||
private:
|
||||
FGPanelNode* panel;
|
||||
SGPropertyNode* visProp;
|
||||
};
|
||||
|
||||
|
||||
FGPanelNode::FGPanelNode(SGPropertyNode* props) :
|
||||
_resizeToViewport(false)
|
||||
{
|
||||
// Make an FGPanel object. But *don't* call init() or bind() on
|
||||
// it -- those methods touch static state.
|
||||
const char *path = props->getStringValue("path");
|
||||
_panel = fgReadPanel(path);
|
||||
if (!_panel)
|
||||
throw sg_io_exception(string("Failed to load panel ") + path);
|
||||
commonInit();
|
||||
_panelPath = props->getStringValue("path");
|
||||
|
||||
// And the corner points
|
||||
SGPropertyNode* pt = props->getChild("bottom-left");
|
||||
_bottomLeft[0] = pt->getFloatValue("x-m");
|
||||
_bottomLeft[1] = pt->getFloatValue("y-m");
|
||||
_bottomLeft[2] = pt->getFloatValue("z-m");
|
||||
|
||||
pt = props->getChild("top-left");
|
||||
_topLeft[0] = pt->getFloatValue("x-m");
|
||||
_topLeft[1] = pt->getFloatValue("y-m");
|
||||
_topLeft[2] = pt->getFloatValue("z-m");
|
||||
|
||||
pt = props->getChild("bottom-right");
|
||||
_bottomRight[0] = pt->getFloatValue("x-m");
|
||||
_bottomRight[1] = pt->getFloatValue("y-m");
|
||||
_bottomRight[2] = pt->getFloatValue("z-m");
|
||||
// And the corner points
|
||||
SGPropertyNode* pt = props->getChild("bottom-left");
|
||||
_bottomLeft[0] = pt->getFloatValue("x-m");
|
||||
_bottomLeft[1] = pt->getFloatValue("y-m");
|
||||
_bottomLeft[2] = pt->getFloatValue("z-m");
|
||||
|
||||
_panel->setDepthTest( props->getBoolValue("depth-test") );
|
||||
pt = props->getChild("top-left");
|
||||
_topLeft[0] = pt->getFloatValue("x-m");
|
||||
_topLeft[1] = pt->getFloatValue("y-m");
|
||||
_topLeft[2] = pt->getFloatValue("z-m");
|
||||
|
||||
initWithPanel();
|
||||
pt = props->getChild("bottom-right");
|
||||
_bottomRight[0] = pt->getFloatValue("x-m");
|
||||
_bottomRight[1] = pt->getFloatValue("y-m");
|
||||
_bottomRight[2] = pt->getFloatValue("z-m");
|
||||
|
||||
_depthTest = props->getBoolValue("depth-test");
|
||||
}
|
||||
|
||||
FGPanelNode::FGPanelNode(FGPanel* p) :
|
||||
_panel(p),
|
||||
_resizeToViewport(true)
|
||||
FGPanelNode::FGPanelNode() :
|
||||
_resizeToViewport(true),
|
||||
_depthTest(false)
|
||||
{
|
||||
commonInit();
|
||||
}
|
||||
|
||||
void FGPanelNode::setPanelPath(const std::string& panel)
|
||||
{
|
||||
if (panel == _panelPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
_panelPath = panel;
|
||||
if (_panel) {
|
||||
_panel.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void FGPanelNode::lazyLoad()
|
||||
{
|
||||
if (!_panelPath.empty() && !_panel) {
|
||||
_panel = fgReadPanel(_panelPath);
|
||||
if (!_panel) {
|
||||
SG_LOG(SG_COCKPIT, SG_WARN, "failed to read panel from:" << _panelPath);
|
||||
_panelPath = string(); // don't keep trying to read
|
||||
return;
|
||||
}
|
||||
|
||||
_panel->setDepthTest(_depthTest);
|
||||
initWithPanel();
|
||||
}
|
||||
}
|
||||
|
||||
void FGPanelNode::commonInit()
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
setDataVariance(Object::DYNAMIC);
|
||||
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
void FGPanelNode::initWithPanel()
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Never mind. We *have* to call init to make sure the static
|
||||
// state is initialized (it's not, if there aren't any 2D
|
||||
// panels). This is a memory leak and should be fixed!`
|
||||
// FIXME
|
||||
_panel->init();
|
||||
// Read out the pixel-space info
|
||||
float panelWidth = _panel->getWidth();
|
||||
float panelHeight = _panel->getHeight();
|
||||
|
||||
// Read out the pixel-space info
|
||||
float panelWidth = _panel->getWidth();
|
||||
float panelHeight = _panel->getHeight();
|
||||
_panel->getLogicalExtent(_xmin, _ymin, _xmax, _ymax);
|
||||
|
||||
_panel->getLogicalExtent(_xmin, _ymin, _xmax, _ymax);
|
||||
|
||||
// Now generate our transformation matrix. For shorthand, use
|
||||
// "a", "b", and "c" as our corners and "m" as the matrix. The
|
||||
// vector u goes from a to b, v from a to c, and w is a
|
||||
// perpendicular cross product.
|
||||
osg::Vec3 a = _bottomLeft;
|
||||
osg::Vec3 b = _bottomRight;
|
||||
osg::Vec3 c = _topLeft;
|
||||
osg::Vec3 u = b - a;
|
||||
osg::Vec3 v = c - a;
|
||||
osg::Vec3 w = u^v;
|
||||
// Now generate our transformation matrix. For shorthand, use
|
||||
// "a", "b", and "c" as our corners and "m" as the matrix. The
|
||||
// vector u goes from a to b, v from a to c, and w is a
|
||||
// perpendicular cross product.
|
||||
osg::Vec3 a = _bottomLeft;
|
||||
osg::Vec3 b = _bottomRight;
|
||||
osg::Vec3 c = _topLeft;
|
||||
osg::Vec3 u = b - a;
|
||||
osg::Vec3 v = c - a;
|
||||
osg::Vec3 w = u^v;
|
||||
|
||||
osg::Matrix& m = _xform;
|
||||
// Now generate a trivial basis transformation matrix. If we want
|
||||
// to map the three unit vectors to three arbitrary vectors U, V,
|
||||
// and W, then those just become the columns of the 3x3 matrix.
|
||||
m(0,0) = u[0]; m(1,0) = v[0]; m(2,0) = w[0]; m(3,0) = a[0];// |Ux Vx Wx|
|
||||
m(0,1) = u[1]; m(1,1) = v[1]; m(2,1) = w[1]; m(3,1) = a[1];//m = |Uy Vy Wy|
|
||||
m(0,2) = u[2]; m(1,2) = v[2]; m(2,2) = w[2]; m(3,2) = a[2];// |Uz Vz Wz|
|
||||
m(0,3) = 0; m(1,3) = 0; m(2,3) = 0; m(3,3) = 1;
|
||||
osg::Matrix& m = _xform;
|
||||
// Now generate a trivial basis transformation matrix. If we want
|
||||
// to map the three unit vectors to three arbitrary vectors U, V,
|
||||
// and W, then those just become the columns of the 3x3 matrix.
|
||||
m(0,0) = u[0]; m(1,0) = v[0]; m(2,0) = w[0]; m(3,0) = a[0];// |Ux Vx Wx|
|
||||
m(0,1) = u[1]; m(1,1) = v[1]; m(2,1) = w[1]; m(3,1) = a[1];//m = |Uy Vy Wy|
|
||||
m(0,2) = u[2]; m(1,2) = v[2]; m(2,2) = w[2]; m(3,2) = a[2];// |Uz Vz Wz|
|
||||
m(0,3) = 0; m(1,3) = 0; m(2,3) = 0; m(3,3) = 1;
|
||||
|
||||
// The above matrix maps the unit (!) square to the panel
|
||||
// rectangle. Postmultiply scaling factors that match the
|
||||
// pixel-space size of the panel.
|
||||
for(i=0; i<4; ++i) {
|
||||
m(0,i) *= 1.0/panelWidth;
|
||||
m(1,i) *= 1.0/panelHeight;
|
||||
}
|
||||
// The above matrix maps the unit (!) square to the panel
|
||||
// rectangle. Postmultiply scaling factors that match the
|
||||
// pixel-space size of the panel.
|
||||
for(i=0; i<4; ++i) {
|
||||
m(0,i) *= 1.0/panelWidth;
|
||||
m(1,i) *= 1.0/panelHeight;
|
||||
}
|
||||
|
||||
dirtyBound();
|
||||
setUseDisplayList(false);
|
||||
setDataVariance(Object::DYNAMIC);
|
||||
|
||||
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
FGPanelNode::~FGPanelNode()
|
||||
|
@ -157,6 +238,10 @@ FGPanelNode::~FGPanelNode()
|
|||
|
||||
osg::Matrix FGPanelNode::transformMatrix() const
|
||||
{
|
||||
if (!_panel) {
|
||||
osg::Matrix();
|
||||
}
|
||||
|
||||
if (!_resizeToViewport) {
|
||||
return _xform;
|
||||
}
|
||||
|
@ -171,6 +256,10 @@ osg::Matrix FGPanelNode::transformMatrix() const
|
|||
void
|
||||
FGPanelNode::drawImplementation(osg::State& state) const
|
||||
{
|
||||
if (!_panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::RefMatrix> mv = new osg::RefMatrix;
|
||||
mv->set(transformMatrix() * state.getModelViewMatrix());
|
||||
state.applyModelViewMatrix(mv.get());
|
||||
|
@ -209,6 +298,23 @@ void FGPanelNode::accept(osg::PrimitiveFunctor& functor) const
|
|||
functor.drawArrays( GL_QUADS, 0, 4);
|
||||
}
|
||||
|
||||
bool FGPanelNode::isVisible2d() const
|
||||
{
|
||||
if (!_panel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_panel->getAutohide()) {
|
||||
if (!globals->get_current_view()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return globals->get_current_view()->getHeadingOffset_deg() == 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static osg::Node* createGeode(FGPanelNode* panel)
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
@ -222,14 +328,52 @@ static osg::Node* createGeode(FGPanelNode* panel)
|
|||
return geode;
|
||||
}
|
||||
|
||||
osg::Node* FGPanelNode::createNode(FGPanel* p)
|
||||
class PanelPathObserver : public SGPropertyChangeListener
|
||||
{
|
||||
FGPanelNode* drawable = new FGPanelNode(p);
|
||||
return createGeode(drawable);
|
||||
public:
|
||||
PanelPathObserver(FGPanelNode* pn) : _panelNode(pn) {}
|
||||
|
||||
virtual void valueChanged (SGPropertyNode * node)
|
||||
{
|
||||
_panelNode->setPanelPath(node->getStringValue());
|
||||
}
|
||||
private:
|
||||
FGPanelNode* _panelNode;
|
||||
};
|
||||
|
||||
osg::Node* FGPanelNode::create2DPanelNode()
|
||||
{
|
||||
SGCommandMgr::instance()->addCommand("panel-mouse-click", do_panel_mouse_click);
|
||||
|
||||
SGPropertyNode* pathNode = fgGetNode("/sim/panel/path");
|
||||
|
||||
FGPanelNode* drawable = new FGPanelNode();
|
||||
// need a global to keep the panel_mouse_click command working, sadly
|
||||
global_panel = drawable;
|
||||
|
||||
PanelPathObserver* ppo = new PanelPathObserver(drawable);
|
||||
pathNode->addChangeListener(ppo);
|
||||
drawable->setPanelPath(pathNode->getStringValue());
|
||||
|
||||
osg::Switch* ps = new osg::Switch;
|
||||
osg::StateSet* stateSet = ps->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(1000, "RenderBin");
|
||||
ps->addChild(createGeode(drawable));
|
||||
|
||||
// speed optimization?
|
||||
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||
stateSet->setAttribute(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA));
|
||||
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
|
||||
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||
|
||||
ps->setUpdateCallback(new FGPanelSwitchCallback(drawable));
|
||||
return ps;
|
||||
}
|
||||
|
||||
osg::Node* FGPanelNode::load(SGPropertyNode *n)
|
||||
{
|
||||
FGPanelNode* drawable = new FGPanelNode(n);
|
||||
drawable->lazyLoad(); // force load now for 2.5D panels
|
||||
return createGeode(drawable);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class SGPropertyNode;
|
|||
class FGPanelNode : public osg::Drawable
|
||||
{
|
||||
public:
|
||||
FGPanelNode(FGPanel* panel);
|
||||
FGPanelNode();
|
||||
|
||||
FGPanelNode(SGPropertyNode* props);
|
||||
virtual ~FGPanelNode();
|
||||
|
@ -37,17 +37,27 @@ public:
|
|||
virtual void accept(osg::PrimitiveFunctor& functor) const;
|
||||
|
||||
static osg::Node* load(SGPropertyNode *n);
|
||||
static osg::Node* createNode(FGPanel* panel);
|
||||
static osg::Node* create2DPanelNode();
|
||||
|
||||
osg::Matrix transformMatrix() const;
|
||||
|
||||
void setPanelPath(const std::string& panel);
|
||||
void lazyLoad();
|
||||
|
||||
/**
|
||||
* is visible in 2D mode or not?
|
||||
*/
|
||||
bool isVisible2d() const;
|
||||
private:
|
||||
void commonInit();
|
||||
void initWithPanel();
|
||||
|
||||
SGSharedPtr<FGPanel> _panel;
|
||||
std::string _panelPath;
|
||||
|
||||
bool _resizeToViewport;
|
||||
|
||||
bool _depthTest;
|
||||
|
||||
// Panel corner coordinates
|
||||
osg::Vec3 _bottomLeft, _topLeft, _bottomRight;
|
||||
|
||||
|
|
|
@ -383,25 +383,6 @@ static osg::ref_ptr<osg::Group> mDeferredRealRoot = new osg::Group;
|
|||
|
||||
static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
|
||||
|
||||
static osg::ref_ptr<osg::Switch> panelSwitch;
|
||||
|
||||
|
||||
// update callback for the switch node controlling the 2D panel
|
||||
class FGPanelSwitchCallback : public osg::NodeCallback {
|
||||
public:
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<osg::Switch*>(node));
|
||||
osg::Switch* sw = static_cast<osg::Switch*>(node);
|
||||
|
||||
bool enabled = fgPanelVisible();
|
||||
sw->setValue(0, enabled);
|
||||
if (!enabled)
|
||||
return;
|
||||
traverse(node, nv);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef FG_JPEG_SERVER
|
||||
static void updateRenderer()
|
||||
{
|
||||
|
@ -1625,22 +1606,8 @@ FGRenderer::setupView( void )
|
|||
geode->addDrawable(new SGHUDDrawable);
|
||||
guiCamera->addChild(geode);
|
||||
|
||||
panelSwitch = new osg::Switch;
|
||||
osg::StateSet* stateSet = panelSwitch->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(1000, "RenderBin");
|
||||
|
||||
// speed optimization?
|
||||
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||
stateSet->setAttribute(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA));
|
||||
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
|
||||
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||
|
||||
|
||||
panelSwitch->setUpdateCallback(new FGPanelSwitchCallback);
|
||||
panelChanged();
|
||||
|
||||
guiCamera->addChild(panelSwitch.get());
|
||||
guiCamera->addChild(FGPanelNode::create2DPanelNode());
|
||||
}
|
||||
|
||||
osg::Switch* sw = new osg::Switch;
|
||||
|
@ -1661,20 +1628,6 @@ FGRenderer::setupView( void )
|
|||
|
||||
mDeferredRealRoot->addChild( mRealRoot.get() );
|
||||
}
|
||||
|
||||
void FGRenderer::panelChanged()
|
||||
{
|
||||
if (!panelSwitch) {
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Node* n = FGPanelNode::createNode(globals->get_current_panel());
|
||||
if (panelSwitch->getNumChildren()) {
|
||||
panelSwitch->setChild(0, n);
|
||||
} else {
|
||||
panelSwitch->addChild(n);
|
||||
}
|
||||
}
|
||||
|
||||
// Update all Visuals (redraws anything graphics related)
|
||||
void
|
||||
|
|
|
@ -117,11 +117,7 @@ public:
|
|||
SGSky* getSky() const { return _sky; }
|
||||
|
||||
void setPlanes( double zNear, double zFar );
|
||||
|
||||
/**
|
||||
* inform the renderer when the global (2D) panel is changed
|
||||
*/
|
||||
void panelChanged();
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
|
||||
|
|
Loading…
Reference in a new issue