1
0
Fork 0

Fix bug 864 - moving the 2D panel around.

Bounding box wasn't being dirtied when changing the transform,
breaking picking visitor for the panel. Add listeners to the relevant
props so we can tell OSG when the panel transform changes.
This commit is contained in:
James Turner 2013-07-03 08:57:48 +01:00
parent 05572cbb3e
commit 55d6d09524

View file

@ -30,6 +30,19 @@
using std::vector; using std::vector;
class PanelTransformListener : public SGPropertyChangeListener
{
public:
PanelTransformListener(FGPanelNode* pn) : _panelNode(pn) {}
virtual void valueChanged (SGPropertyNode * node)
{
_panelNode->dirtyBound();
}
private:
FGPanelNode* _panelNode;
};
static FGPanelNode* global_panel = NULL; static FGPanelNode* global_panel = NULL;
/** /**
@ -158,6 +171,16 @@ FGPanelNode::FGPanelNode() :
_resizeToViewport(true), _resizeToViewport(true),
_depthTest(false) _depthTest(false)
{ {
// for a 2D panel, various options adjust the transformation
// matrix. We need to pass this data on to OSG or its bounding box
// will be stale, and picking will break.
// http://code.google.com/p/flightgear-bugs/issues/detail?id=864
PanelTransformListener* ptl = new PanelTransformListener(this);
fgGetNode("/sim/panel/x-offset", true)->addChangeListener(ptl);
fgGetNode("/sim/panel/y-offset", true)->addChangeListener(ptl);
fgGetNode("/sim/startup/xsize", true)->addChangeListener(ptl);
fgGetNode("/sim/startup/ysize", true)->addChangeListener(ptl);
commonInit(); commonInit();
} }
@ -218,6 +241,9 @@ void FGPanelNode::initWithPanel()
osg::Vec3 w = u^v; osg::Vec3 w = u^v;
osg::Matrix& m = _xform; osg::Matrix& m = _xform;
if ((u.length2() == 0.0) || (b.length2() == 0.0)) {
m.makeIdentity();
} else {
// Now generate a trivial basis transformation matrix. If we want // Now generate a trivial basis transformation matrix. If we want
// to map the three unit vectors to three arbitrary vectors U, V, // to map the three unit vectors to three arbitrary vectors U, V,
// and W, then those just become the columns of the 3x3 matrix. // and W, then those just become the columns of the 3x3 matrix.
@ -225,6 +251,7 @@ void FGPanelNode::initWithPanel()
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,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,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; 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 // The above matrix maps the unit (!) square to the panel
// rectangle. Postmultiply scaling factors that match the // rectangle. Postmultiply scaling factors that match the
@ -347,10 +374,10 @@ static osg::Node* createGeode(FGPanelNode* panel)
return geode; return geode;
} }
class PanelPathObserver : public SGPropertyChangeListener class PanelPathListener : public SGPropertyChangeListener
{ {
public: public:
PanelPathObserver(FGPanelNode* pn) : _panelNode(pn) {} PanelPathListener(FGPanelNode* pn) : _panelNode(pn) {}
virtual void valueChanged (SGPropertyNode * node) virtual void valueChanged (SGPropertyNode * node)
{ {
@ -360,6 +387,7 @@ private:
FGPanelNode* _panelNode; FGPanelNode* _panelNode;
}; };
osg::Node* FGPanelNode::create2DPanelNode() osg::Node* FGPanelNode::create2DPanelNode()
{ {
SGCommandMgr::instance()->addCommand("panel-mouse-click", do_panel_mouse_click); SGCommandMgr::instance()->addCommand("panel-mouse-click", do_panel_mouse_click);
@ -370,7 +398,7 @@ osg::Node* FGPanelNode::create2DPanelNode()
// need a global to keep the panel_mouse_click command working, sadly // need a global to keep the panel_mouse_click command working, sadly
global_panel = drawable; global_panel = drawable;
PanelPathObserver* ppo = new PanelPathObserver(drawable); PanelPathListener* ppo = new PanelPathListener(drawable);
pathNode->addChangeListener(ppo); pathNode->addChangeListener(ppo);
drawable->setPanelPath(pathNode->getStringValue()); drawable->setPanelPath(pathNode->getStringValue());