Fix 2.5D panel hit detection, compute logical panel extend from actions.
This commit is contained in:
parent
2e735e6234
commit
086df400de
5 changed files with 117 additions and 31 deletions
|
@ -36,6 +36,7 @@
|
||||||
#include <stdio.h> // sprintf
|
#include <stdio.h> // sprintf
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include <osg/CullFace>
|
#include <osg/CullFace>
|
||||||
#include <osg/Depth>
|
#include <osg/Depth>
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
|
|
||||||
#include <plib/fnt.h>
|
#include <plib/fnt.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/scene/model/model.hxx>
|
#include <simgear/scene/model/model.hxx>
|
||||||
|
@ -196,7 +198,7 @@ FGPanel::FGPanel ()
|
||||||
: _mouseDown(false),
|
: _mouseDown(false),
|
||||||
_mouseInstrument(0),
|
_mouseInstrument(0),
|
||||||
_width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
|
_width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
|
||||||
_view_height(int(WIN_H * 0.4232)),
|
// _view_height(int(WIN_H * 0.4232)),
|
||||||
_visibility(fgGetNode("/sim/panel/visibility", true)),
|
_visibility(fgGetNode("/sim/panel/visibility", true)),
|
||||||
_x_offset(fgGetNode("/sim/panel/x-offset", true)),
|
_x_offset(fgGetNode("/sim/panel/x-offset", true)),
|
||||||
_y_offset(fgGetNode("/sim/panel/y-offset", true)),
|
_y_offset(fgGetNode("/sim/panel/y-offset", true)),
|
||||||
|
@ -475,6 +477,19 @@ FGPanel::draw(osg::State& state)
|
||||||
for ( unsigned int i = 0; i < _instruments.size(); i++ )
|
for ( unsigned int i = 0; i < _instruments.size(); i++ )
|
||||||
_instruments[i]->drawHotspots(state);
|
_instruments[i]->drawHotspots(state);
|
||||||
|
|
||||||
|
glColor3f(0, 1, 1);
|
||||||
|
|
||||||
|
int x0, y0, x1, y1;
|
||||||
|
getLogicalExtent(x0, y0, x1, y1);
|
||||||
|
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glVertex2f(x0, y0);
|
||||||
|
glVertex2f(x1, y0);
|
||||||
|
glVertex2f(x1, y1);
|
||||||
|
glVertex2f(x0, y1);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
|
|
||||||
state.popStateSet();
|
state.popStateSet();
|
||||||
|
@ -626,7 +641,55 @@ void FGPanel::setDepthTest (bool enable) {
|
||||||
_enable_depth_test = enable;
|
_enable_depth_test = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IntRect
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
IntRect() :
|
||||||
|
x0(std::numeric_limits<int>::max()),
|
||||||
|
y0(std::numeric_limits<int>::max()),
|
||||||
|
x1(std::numeric_limits<int>::min()),
|
||||||
|
y1(std::numeric_limits<int>::min())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
IntRect(int x, int y, int w, int h) :
|
||||||
|
x0(x), y0(y), x1(x + w), y1( y + h)
|
||||||
|
{
|
||||||
|
if (x1 < x0) {
|
||||||
|
std::swap(x0, x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < y0) {
|
||||||
|
std::swap(y0, y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(x0 <= x1);
|
||||||
|
assert(y0 <= y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void extend(const IntRect& r)
|
||||||
|
{
|
||||||
|
x0 = std::min(x0, r.x0);
|
||||||
|
y0 = std::min(y0, r.y0);
|
||||||
|
x1 = std::max(x1, r.x1);
|
||||||
|
y1 = std::max(y1, r.y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int x0, y0, x1, y1;
|
||||||
|
};
|
||||||
|
|
||||||
|
void FGPanel::getLogicalExtent(int &x0, int& y0, int& x1, int &y1)
|
||||||
|
{
|
||||||
|
IntRect result;
|
||||||
|
BOOST_FOREACH(FGPanelInstrument *inst, _instruments) {
|
||||||
|
inst->extendRect(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
x0 = result.x0;
|
||||||
|
y0 = result.y0;
|
||||||
|
x1 = result.x1;
|
||||||
|
y1 = result.y1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////.
|
////////////////////////////////////////////////////////////////////////.
|
||||||
// Implementation of FGPanelAction.
|
// Implementation of FGPanelAction.
|
||||||
|
@ -774,6 +837,21 @@ FGPanelInstrument::getHeight () const
|
||||||
return _h;
|
return _h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGPanelInstrument::extendRect(IntRect& r) const
|
||||||
|
{
|
||||||
|
IntRect instRect(_x, _y, _w, _h);
|
||||||
|
r.extend(instRect);
|
||||||
|
|
||||||
|
BOOST_FOREACH(FGPanelAction* act, _actions) {
|
||||||
|
r.extend(IntRect(getXPos() + act->getX(),
|
||||||
|
getYPos() + act->getY(),
|
||||||
|
act->getWidth(),
|
||||||
|
act->getHeight()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGPanelInstrument::addAction (FGPanelAction * action)
|
FGPanelInstrument::addAction (FGPanelAction * action)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
class FGPanelInstrument;
|
class FGPanelInstrument;
|
||||||
class fntFont;
|
class fntFont;
|
||||||
class DCLGPS;
|
class DCLGPS;
|
||||||
|
class IntRect;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Texture management.
|
// Texture management.
|
||||||
|
@ -166,8 +167,14 @@ public:
|
||||||
virtual int getYOffset () const { return _y_offset->getIntValue(); }
|
virtual int getYOffset () const { return _y_offset->getIntValue(); }
|
||||||
|
|
||||||
// View height.
|
// View height.
|
||||||
virtual void setViewHeight (int height) { _view_height = height; }
|
// virtual void setViewHeight (int height) { _view_height = height; }
|
||||||
virtual int getViewHeight () const { return _view_height; }
|
// virtual int getViewHeight () const { return _view_height; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find the actual logical extend of the panel, including all instruments
|
||||||
|
* and actions.
|
||||||
|
*/
|
||||||
|
void getLogicalExtent(int &x0, int& y0, int& x1, int &y1);
|
||||||
|
|
||||||
// Handle a mouse click.
|
// Handle a mouse click.
|
||||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||||
|
@ -191,7 +198,7 @@ private:
|
||||||
typedef std::vector<FGPanelInstrument *> instrument_list_type;
|
typedef std::vector<FGPanelInstrument *> instrument_list_type;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
int _view_height;
|
// int _view_height;
|
||||||
|
|
||||||
SGPropertyNode_ptr _visibility;
|
SGPropertyNode_ptr _visibility;
|
||||||
SGPropertyNode_ptr _x_offset;
|
SGPropertyNode_ptr _x_offset;
|
||||||
|
@ -392,6 +399,7 @@ public:
|
||||||
// Coordinates relative to centre.
|
// Coordinates relative to centre.
|
||||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||||
|
|
||||||
|
void extendRect(IntRect& r) const;
|
||||||
protected:
|
protected:
|
||||||
int _x, _y, _w, _h;
|
int _x, _y, _w, _h;
|
||||||
typedef std::vector<FGPanelAction *> action_list_type;
|
typedef std::vector<FGPanelAction *> action_list_type;
|
||||||
|
|
|
@ -662,8 +662,8 @@ readPanel (const SGPropertyNode * root)
|
||||||
//
|
//
|
||||||
// Grab the visible external viewing area, default to
|
// Grab the visible external viewing area, default to
|
||||||
//
|
//
|
||||||
panel->setViewHeight(root->getIntValue("view-height",
|
// panel->setViewHeight(root->getIntValue("view-height",
|
||||||
768 - panel->getHeight() + 2));
|
// 768 - panel->getHeight() + 2));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Grab the panel's initial offsets, default to 0, 0.
|
// Grab the panel's initial offsets, default to 0, 0.
|
||||||
|
|
|
@ -110,9 +110,10 @@ void FGPanelNode::initWithPanel()
|
||||||
_panel->init();
|
_panel->init();
|
||||||
|
|
||||||
// Read out the pixel-space info
|
// Read out the pixel-space info
|
||||||
_xmax = _panel->getWidth();
|
float panelWidth = _panel->getWidth();
|
||||||
_ymax = _panel->getHeight();
|
float panelHeight = _panel->getHeight();
|
||||||
|
|
||||||
|
_panel->getLogicalExtent(_xmin, _ymin, _xmax, _ymax);
|
||||||
|
|
||||||
// Now generate our transformation matrix. For shorthand, use
|
// Now generate our transformation matrix. For shorthand, use
|
||||||
// "a", "b", and "c" as our corners and "m" as the matrix. The
|
// "a", "b", and "c" as our corners and "m" as the matrix. The
|
||||||
|
@ -138,8 +139,8 @@ void FGPanelNode::initWithPanel()
|
||||||
// rectangle. Postmultiply scaling factors that match the
|
// rectangle. Postmultiply scaling factors that match the
|
||||||
// pixel-space size of the panel.
|
// pixel-space size of the panel.
|
||||||
for(i=0; i<4; ++i) {
|
for(i=0; i<4; ++i) {
|
||||||
m(0,i) *= 1.0/_xmax;
|
m(0,i) *= 1.0/panelWidth;
|
||||||
m(1,i) *= 1.0/_ymax;
|
m(1,i) *= 1.0/panelHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyBound();
|
dirtyBound();
|
||||||
|
@ -181,11 +182,12 @@ FGPanelNode::drawImplementation(osg::State& state) const
|
||||||
osg::BoundingBox
|
osg::BoundingBox
|
||||||
FGPanelNode::computeBound() const
|
FGPanelNode::computeBound() const
|
||||||
{
|
{
|
||||||
osg::Vec3 coords[4];
|
|
||||||
|
osg::Vec3 coords[3];
|
||||||
osg::Matrix m(transformMatrix());
|
osg::Matrix m(transformMatrix());
|
||||||
coords[0] = m.preMult(osg::Vec3(0,0,0));
|
coords[0] = m.preMult(osg::Vec3(_xmin,_ymin,0));
|
||||||
coords[1] = m.preMult(osg::Vec3(_xmax,0,0));
|
coords[1] = m.preMult(osg::Vec3(_xmax,_ymin,0));
|
||||||
coords[2] = m.preMult(osg::Vec3(0,_ymax,0));
|
coords[2] = m.preMult(osg::Vec3(_xmin,_ymax,0));
|
||||||
|
|
||||||
osg::BoundingBox bb;
|
osg::BoundingBox bb;
|
||||||
bb.expandBy(coords[0]);
|
bb.expandBy(coords[0]);
|
||||||
|
@ -199,10 +201,10 @@ void FGPanelNode::accept(osg::PrimitiveFunctor& functor) const
|
||||||
osg::Vec3 coords[4];
|
osg::Vec3 coords[4];
|
||||||
osg::Matrix m(transformMatrix());
|
osg::Matrix m(transformMatrix());
|
||||||
|
|
||||||
coords[0] = m.preMult(osg::Vec3(0,0,0));
|
coords[0] = m.preMult(osg::Vec3(_xmin,_ymin,0));
|
||||||
coords[1] = m.preMult(osg::Vec3(_xmax,0,0));
|
coords[1] = m.preMult(osg::Vec3(_xmax,_ymin,0));
|
||||||
coords[2] = m.preMult(osg::Vec3(_xmax, _ymax, 0));
|
coords[2] = m.preMult(osg::Vec3(_xmax, _ymax, 0));
|
||||||
coords[3] = m.preMult(osg::Vec3(0,_ymax,0));
|
coords[3] = m.preMult(osg::Vec3(_xmin,_ymax,0));
|
||||||
|
|
||||||
functor.setVertexArray(4, coords);
|
functor.setVertexArray(4, coords);
|
||||||
functor.drawArrays( GL_QUADS, 0, 4);
|
functor.drawArrays( GL_QUADS, 0, 4);
|
||||||
|
|
|
@ -50,9 +50,7 @@ private:
|
||||||
// Panel corner coordinates
|
// Panel corner coordinates
|
||||||
osg::Vec3 _bottomLeft, _topLeft, _bottomRight;
|
osg::Vec3 _bottomLeft, _topLeft, _bottomRight;
|
||||||
|
|
||||||
// The input range expected in the panel definition. These x/y
|
int _xmin, _ymin, _xmax, _ymax;
|
||||||
// coordinates will map to the right/top sides.
|
|
||||||
float _xmax, _ymax;
|
|
||||||
|
|
||||||
// The matrix that results, which transforms 2D x/y panel
|
// The matrix that results, which transforms 2D x/y panel
|
||||||
// coordinates into 3D coordinates of the panel quadrilateral.
|
// coordinates into 3D coordinates of the panel quadrilateral.
|
||||||
|
|
Loading…
Reference in a new issue