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 <string.h>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Depth>
|
||||
|
@ -48,6 +49,7 @@
|
|||
|
||||
#include <plib/fnt.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
|
@ -196,7 +198,7 @@ FGPanel::FGPanel ()
|
|||
: _mouseDown(false),
|
||||
_mouseInstrument(0),
|
||||
_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)),
|
||||
_x_offset(fgGetNode("/sim/panel/x-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++ )
|
||||
_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();
|
||||
|
||||
state.popStateSet();
|
||||
|
@ -626,7 +641,55 @@ void FGPanel::setDepthTest (bool 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.
|
||||
|
@ -774,6 +837,21 @@ FGPanelInstrument::getHeight () const
|
|||
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
|
||||
FGPanelInstrument::addAction (FGPanelAction * action)
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
class FGPanelInstrument;
|
||||
class fntFont;
|
||||
class DCLGPS;
|
||||
class IntRect;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Texture management.
|
||||
|
@ -166,8 +167,14 @@ public:
|
|||
virtual int getYOffset () const { return _y_offset->getIntValue(); }
|
||||
|
||||
// View height.
|
||||
virtual void setViewHeight (int height) { _view_height = height; }
|
||||
virtual int getViewHeight () const { return _view_height; }
|
||||
// virtual void setViewHeight (int height) { _view_height = 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.
|
||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||
|
@ -191,7 +198,7 @@ private:
|
|||
typedef std::vector<FGPanelInstrument *> instrument_list_type;
|
||||
int _width;
|
||||
int _height;
|
||||
int _view_height;
|
||||
// int _view_height;
|
||||
|
||||
SGPropertyNode_ptr _visibility;
|
||||
SGPropertyNode_ptr _x_offset;
|
||||
|
@ -392,6 +399,7 @@ public:
|
|||
// Coordinates relative to centre.
|
||||
virtual bool doMouseAction (int button, int updown, int x, int y);
|
||||
|
||||
void extendRect(IntRect& r) const;
|
||||
protected:
|
||||
int _x, _y, _w, _h;
|
||||
typedef std::vector<FGPanelAction *> action_list_type;
|
||||
|
|
|
@ -662,8 +662,8 @@ readPanel (const SGPropertyNode * root)
|
|||
//
|
||||
// Grab the visible external viewing area, default to
|
||||
//
|
||||
panel->setViewHeight(root->getIntValue("view-height",
|
||||
768 - panel->getHeight() + 2));
|
||||
// panel->setViewHeight(root->getIntValue("view-height",
|
||||
// 768 - panel->getHeight() + 2));
|
||||
|
||||
//
|
||||
// Grab the panel's initial offsets, default to 0, 0.
|
||||
|
|
|
@ -110,9 +110,10 @@ void FGPanelNode::initWithPanel()
|
|||
_panel->init();
|
||||
|
||||
// Read out the pixel-space info
|
||||
_xmax = _panel->getWidth();
|
||||
_ymax = _panel->getHeight();
|
||||
float panelWidth = _panel->getWidth();
|
||||
float panelHeight = _panel->getHeight();
|
||||
|
||||
_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
|
||||
|
@ -138,8 +139,8 @@ void FGPanelNode::initWithPanel()
|
|||
// rectangle. Postmultiply scaling factors that match the
|
||||
// pixel-space size of the panel.
|
||||
for(i=0; i<4; ++i) {
|
||||
m(0,i) *= 1.0/_xmax;
|
||||
m(1,i) *= 1.0/_ymax;
|
||||
m(0,i) *= 1.0/panelWidth;
|
||||
m(1,i) *= 1.0/panelHeight;
|
||||
}
|
||||
|
||||
dirtyBound();
|
||||
|
@ -181,11 +182,12 @@ FGPanelNode::drawImplementation(osg::State& state) const
|
|||
osg::BoundingBox
|
||||
FGPanelNode::computeBound() const
|
||||
{
|
||||
osg::Vec3 coords[4];
|
||||
|
||||
osg::Vec3 coords[3];
|
||||
osg::Matrix m(transformMatrix());
|
||||
coords[0] = m.preMult(osg::Vec3(0,0,0));
|
||||
coords[1] = m.preMult(osg::Vec3(_xmax,0,0));
|
||||
coords[2] = m.preMult(osg::Vec3(0,_ymax,0));
|
||||
coords[0] = m.preMult(osg::Vec3(_xmin,_ymin,0));
|
||||
coords[1] = m.preMult(osg::Vec3(_xmax,_ymin,0));
|
||||
coords[2] = m.preMult(osg::Vec3(_xmin,_ymax,0));
|
||||
|
||||
osg::BoundingBox bb;
|
||||
bb.expandBy(coords[0]);
|
||||
|
@ -199,10 +201,10 @@ void FGPanelNode::accept(osg::PrimitiveFunctor& functor) const
|
|||
osg::Vec3 coords[4];
|
||||
osg::Matrix m(transformMatrix());
|
||||
|
||||
coords[0] = m.preMult(osg::Vec3(0,0,0));
|
||||
coords[1] = m.preMult(osg::Vec3(_xmax,0,0));
|
||||
coords[0] = m.preMult(osg::Vec3(_xmin,_ymin,0));
|
||||
coords[1] = m.preMult(osg::Vec3(_xmax,_ymin,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.drawArrays( GL_QUADS, 0, 4);
|
||||
|
|
|
@ -50,9 +50,7 @@ private:
|
|||
// Panel corner coordinates
|
||||
osg::Vec3 _bottomLeft, _topLeft, _bottomRight;
|
||||
|
||||
// The input range expected in the panel definition. These x/y
|
||||
// coordinates will map to the right/top sides.
|
||||
float _xmax, _ymax;
|
||||
int _xmin, _ymin, _xmax, _ymax;
|
||||
|
||||
// The matrix that results, which transforms 2D x/y panel
|
||||
// coordinates into 3D coordinates of the panel quadrilateral.
|
||||
|
|
Loading…
Reference in a new issue