Introduced new scheme for handling mouse events with osgViewer. The new scheme enables robust event handling even when using distortion correction render to texture Cameras.
This commit is contained in:
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
~PickHandler() {}
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
|
||||
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
if (!view) return false;
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
{
|
||||
if (_mx==ea.getX() && _my==ea.getY())
|
||||
{
|
||||
pick(view, ea.getX(), ea.getY());
|
||||
pick(view, ea);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -81,13 +81,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void pick(osgViewer::View* view, float x, float y)
|
||||
void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osg::Node* node = 0;
|
||||
osg::Group* parent = 0;
|
||||
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (view->computeIntersections(x, y, intersections))
|
||||
if (view->computeIntersections(event, intersections))
|
||||
{
|
||||
osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
|
||||
osg::NodePath& nodePath = intersection.nodePath;
|
||||
@@ -98,7 +98,6 @@ public:
|
||||
// now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked"
|
||||
if (parent && node)
|
||||
{
|
||||
|
||||
osgFX::Scribe* parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent);
|
||||
if (!parentAsScribe)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@ class Keystone : public osg::Referenced
|
||||
public:
|
||||
Keystone():
|
||||
keystoneEditingEnabled(false),
|
||||
gridColour(1.0f,1.0f,1.0f,1.0f),
|
||||
bottom_left(-1.0,-1.0),
|
||||
bottom_right(1.0,-1.0),
|
||||
top_left(-1.0,1.0),
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
{
|
||||
if (&rhs==this) return *this;
|
||||
keystoneEditingEnabled = rhs.keystoneEditingEnabled;
|
||||
gridColour = rhs.gridColour;
|
||||
bottom_left = rhs.bottom_left;
|
||||
bottom_right = rhs.bottom_right;
|
||||
top_left = rhs.top_left;
|
||||
@@ -61,6 +63,8 @@ public:
|
||||
|
||||
bool keystoneEditingEnabled;
|
||||
|
||||
osg::Vec4 gridColour;
|
||||
|
||||
osg::Vec2d bottom_left;
|
||||
osg::Vec2d bottom_right;
|
||||
osg::Vec2d top_left;
|
||||
@@ -97,7 +101,7 @@ public:
|
||||
|
||||
~KeystoneHandler() {}
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
|
||||
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv);
|
||||
|
||||
void setKeystoneEditingEnabled(bool enabled) { if (_currentControlPoints.valid()) _currentControlPoints->keystoneEditingEnabled = enabled; }
|
||||
bool getKeystoneEditingEnabled() const { return _currentControlPoints.valid() ? _currentControlPoints->keystoneEditingEnabled : false; }
|
||||
@@ -228,8 +232,31 @@ osg::Vec2d KeystoneHandler::incrementScale(const osgGA::GUIEventAdapter& ea) con
|
||||
return _defaultIncrement;
|
||||
}
|
||||
|
||||
bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
|
||||
bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
|
||||
{
|
||||
osg::Camera* camera = dynamic_cast<osg::Camera*>(obj);
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
|
||||
if (!viewport) return false;
|
||||
|
||||
bool haveCameraMatch = false;
|
||||
float x = ea.getXnormalized();
|
||||
float y = ea.getYnormalized();
|
||||
for(unsigned int i=0; i<ea.getNumPointerData(); ++i)
|
||||
{
|
||||
const osgGA::PointerData* pd = ea.getPointerData(i);
|
||||
if (pd->object==obj)
|
||||
{
|
||||
haveCameraMatch = true;
|
||||
x = pd->getXnormalized();
|
||||
y = pd->getYnormalized();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!haveCameraMatch) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
@@ -241,7 +268,7 @@ bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA
|
||||
{
|
||||
_selectedRegion = computeRegion(ea);
|
||||
(*_startControlPoints) = (*_currentControlPoints);
|
||||
_startPosition.set(ea.getXnormalized(),ea.getYnormalized());
|
||||
_startPosition.set(x,y);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -257,7 +284,7 @@ bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA
|
||||
if (_selectedRegion!=NONE_SELECTED)
|
||||
{
|
||||
(*_currentControlPoints) = (*_startControlPoints);
|
||||
osg::Vec2d currentPosition(ea.getXnormalized(), ea.getYnormalized());
|
||||
osg::Vec2d currentPosition(x, y);
|
||||
osg::Vec2d delta(currentPosition-_startPosition);
|
||||
osg::Vec2d scale = incrementScale(ea);
|
||||
move(_selectedRegion, osg::Vec2d(delta.x()*scale.x(), delta.y()*scale.y()) );
|
||||
@@ -306,19 +333,19 @@ bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_7 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
|
||||
{
|
||||
_currentControlPoints->top_left.set(ea.getXnormalized(), ea.getYnormalized());
|
||||
_currentControlPoints->top_left.set(x, y);
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_9 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
|
||||
{
|
||||
_currentControlPoints->top_right.set(ea.getXnormalized(), ea.getYnormalized());
|
||||
_currentControlPoints->top_right.set(x, y);
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_3 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
|
||||
{
|
||||
_currentControlPoints->bottom_right.set(ea.getXnormalized(), ea.getYnormalized());
|
||||
_currentControlPoints->bottom_right.set(x, y);
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_1 || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
|
||||
{
|
||||
_currentControlPoints->bottom_left.set(ea.getXnormalized(), ea.getYnormalized());
|
||||
_currentControlPoints->bottom_left.set(x, y);
|
||||
}
|
||||
}
|
||||
else if (ea.getUnmodifiedKey()=='g' && (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL))
|
||||
@@ -471,7 +498,7 @@ osg::Node* createGrid(Keystone* keystone, const osg::Vec4& colour)
|
||||
geometry->setCullCallback(new KeystoneCullCallback(keystone));
|
||||
|
||||
osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
|
||||
colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
||||
colours->push_back(keystone->gridColour);
|
||||
geometry->setColorArray(colours.get());
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
|
||||
@@ -579,18 +606,14 @@ osg::Texture* createKestoneDistortionTexture(int width, int height)
|
||||
|
||||
osg::Camera* assignKeystoneRenderToTextureCamera(osgViewer::View* view, osg::GraphicsContext* gc, int width, int height, osg::Texture* texture)
|
||||
{
|
||||
osg::Camera::RenderTargetImplementation renderTargetImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
|
||||
GLenum buffer = GL_FRONT;
|
||||
|
||||
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
|
||||
camera->setName("Render to texture camera");
|
||||
camera->setGraphicsContext(gc);
|
||||
camera->setViewport(new osg::Viewport(0,0,width, height));
|
||||
camera->setDrawBuffer(buffer);
|
||||
camera->setReadBuffer(buffer);
|
||||
camera->setDrawBuffer(GL_FRONT);
|
||||
camera->setReadBuffer(GL_FRONT);
|
||||
camera->setAllowEventFocus(false);
|
||||
// tell the camera to use OpenGL frame buffer object where supported.
|
||||
camera->setRenderTargetImplementation(renderTargetImplementation);
|
||||
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
camera->attach(osg::Camera::COLOR_BUFFER, texture);
|
||||
@@ -628,7 +651,6 @@ osg::Camera* assignKeystoneDistortionCamera(osgViewer::View* view, osg::DisplayS
|
||||
camera->setDrawBuffer(buffer);
|
||||
camera->setReadBuffer(buffer);
|
||||
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
camera->setAllowEventFocus(false);
|
||||
camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
|
||||
//camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
@@ -822,6 +844,9 @@ void setUpViewForStereo(osgViewer::View* view, osg::DisplaySettings* ds)
|
||||
|
||||
ds->setUseSceneViewForStereoHint(false);
|
||||
|
||||
|
||||
osg::ref_ptr<Keystone> keystone = new Keystone;
|
||||
|
||||
|
||||
// set up view's main camera
|
||||
{
|
||||
@@ -910,48 +935,142 @@ void setUpViewForStereo(osgViewer::View* view, osg::DisplaySettings* ds)
|
||||
case(osg::DisplaySettings::ANAGLYPHIC):
|
||||
{
|
||||
// left Camera red
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> camera = assignStereoCamera(view, ds, gc, 0, 0, traits->width, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT, -1.0);
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
camera->getOrCreateStateSet()->setAttribute(new osg::ColorMask(true, false, false, true));
|
||||
camera->setRenderOrder(osg::Camera::NESTED_RENDER, 0);
|
||||
}
|
||||
osg::ref_ptr<osg::Camera> left_camera = assignStereoCamera(view, ds, gc, 0, 0, traits->width, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT, -1.0);
|
||||
left_camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
left_camera->getOrCreateStateSet()->setAttribute(new osg::ColorMask(true, false, false, true));
|
||||
left_camera->setRenderOrder(osg::Camera::NESTED_RENDER, 0);
|
||||
|
||||
// right Camera cyan
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> camera = assignStereoCamera(view, ds, gc, 0, 0, traits->width, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT, 1.0);
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
camera->getOrCreateStateSet()->setAttribute(new osg::ColorMask(false, true, true, true));
|
||||
camera->setRenderOrder(osg::Camera::NESTED_RENDER, 1);
|
||||
}
|
||||
osg::ref_ptr<osg::Camera> right_camera = assignStereoCamera(view, ds, gc, 0, 0, traits->width, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT, 1.0);
|
||||
right_camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
right_camera->getOrCreateStateSet()->setAttribute(new osg::ColorMask(false, true, true, true));
|
||||
right_camera->setRenderOrder(osg::Camera::NESTED_RENDER, 1);
|
||||
|
||||
// for keystone:
|
||||
// left camera to render to texture using red colour mask
|
||||
// right camera to render to same texture using cyan colour mask
|
||||
// keystone camera to render to whole screen without colour masks
|
||||
// one keystone and editing for the one window
|
||||
if (keystone.valid())
|
||||
{
|
||||
// for keystone:
|
||||
// left camera to render to texture using red colour mask
|
||||
// right camera to render to same texture using cyan colour mask
|
||||
// keystone camera to render to whole screen without colour masks
|
||||
// one keystone and editing for the one window
|
||||
|
||||
// create distortion texture
|
||||
osg::ref_ptr<osg::Texture> texture = createKestoneDistortionTexture(traits->width, traits->height);
|
||||
|
||||
// convert to RTT Camera
|
||||
left_camera->setDrawBuffer(GL_FRONT);
|
||||
left_camera->setReadBuffer(GL_FRONT);
|
||||
left_camera->setAllowEventFocus(false);
|
||||
left_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
left_camera->attach(osg::Camera::COLOR_BUFFER, texture.get());
|
||||
|
||||
|
||||
// convert to RTT Camera
|
||||
right_camera->setDrawBuffer(GL_FRONT);
|
||||
right_camera->setReadBuffer(GL_FRONT);
|
||||
right_camera->setAllowEventFocus(false);
|
||||
right_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
right_camera->attach(osg::Camera::COLOR_BUFFER, texture.get());
|
||||
|
||||
|
||||
// create Keystone distortion camera
|
||||
osg::ref_ptr<osg::Camera> camera = assignKeystoneDistortionCamera(view, ds, gc.get(),
|
||||
0, 0, traits->width, traits->height,
|
||||
traits->doubleBuffer ? GL_BACK : GL_FRONT,
|
||||
texture, keystone.get());
|
||||
|
||||
camera->setRenderOrder(osg::Camera::NESTED_RENDER, 2);
|
||||
|
||||
// attach Keystone editing event handler.
|
||||
camera->addEventCallback(new KeystoneHandler(keystone.get()));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
|
||||
{
|
||||
// left viewport Camera
|
||||
assignStereoCamera(view, ds, gc,
|
||||
osg::ref_ptr<osg::Camera> left_camera = assignStereoCamera(view, ds, gc,
|
||||
0, 0, traits->width/2, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT,
|
||||
(ds->getSplitStereoHorizontalEyeMapping()==osg::DisplaySettings::LEFT_EYE_LEFT_VIEWPORT) ? -1.0 : 1.0);
|
||||
|
||||
// right viewport Camera
|
||||
assignStereoCamera(view, ds, gc,
|
||||
osg::ref_ptr<osg::Camera> right_camera = assignStereoCamera(view, ds, gc,
|
||||
traits->width/2,0, traits->width/2, traits->height, traits->doubleBuffer ? GL_BACK : GL_FRONT,
|
||||
(ds->getSplitStereoHorizontalEyeMapping()==osg::DisplaySettings::LEFT_EYE_RIGHT_VIEWPORT) ? -1.0 : 1.0);
|
||||
|
||||
// for keystone:
|
||||
// left camera to render to left texture using whole viewport of left texture
|
||||
// right camera to render to right texture using whole viewport of right texture
|
||||
// left keystone camera to render to left viewport/window
|
||||
// right keystone camera to render to right viewport/window
|
||||
// two keystone, one for each of the left and right viewports/windows
|
||||
if (keystone.valid())
|
||||
{
|
||||
// for keystone:
|
||||
// left camera to render to left texture using whole viewport of left texture
|
||||
// right camera to render to right texture using whole viewport of right texture
|
||||
// left keystone camera to render to left viewport/window
|
||||
// right keystone camera to render to right viewport/window
|
||||
// two keystone, one for each of the left and right viewports/windows
|
||||
|
||||
// create distortion texture
|
||||
osg::ref_ptr<osg::Texture> left_texture = createKestoneDistortionTexture(traits->width/2, traits->height);
|
||||
|
||||
// convert to RTT Camera
|
||||
left_camera->setViewport(0, 0, traits->width/2, traits->height);
|
||||
left_camera->setDrawBuffer(GL_FRONT);
|
||||
left_camera->setReadBuffer(GL_FRONT);
|
||||
left_camera->setAllowEventFocus(true);
|
||||
left_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
left_camera->attach(osg::Camera::COLOR_BUFFER, left_texture.get());
|
||||
|
||||
|
||||
// create distortion texture
|
||||
osg::ref_ptr<osg::Texture> right_texture = createKestoneDistortionTexture(traits->width/2, traits->height);
|
||||
|
||||
// convert to RTT Camera
|
||||
right_camera->setViewport(0, 0, traits->width/2, traits->height);
|
||||
right_camera->setDrawBuffer(GL_FRONT);
|
||||
right_camera->setReadBuffer(GL_FRONT);
|
||||
right_camera->setAllowEventFocus(true);
|
||||
right_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
right_camera->attach(osg::Camera::COLOR_BUFFER, right_texture.get());
|
||||
|
||||
|
||||
// create Keystone left distortion camera
|
||||
keystone->gridColour.set(1.0f,0.0f,0.0,1.0);
|
||||
osg::ref_ptr<osg::Camera> left_keystone_camera = assignKeystoneDistortionCamera(view, ds, gc.get(),
|
||||
0, 0, traits->width/2, traits->height,
|
||||
traits->doubleBuffer ? GL_BACK : GL_FRONT,
|
||||
left_texture, keystone.get());
|
||||
|
||||
left_keystone_camera->setRenderOrder(osg::Camera::NESTED_RENDER, 2);
|
||||
|
||||
// attach Keystone editing event handler.
|
||||
left_keystone_camera->addEventCallback(new KeystoneHandler(keystone.get()));
|
||||
|
||||
|
||||
osg::ref_ptr<Keystone> right_keystone = new Keystone;
|
||||
right_keystone->gridColour.set(0.0f,1.0f,0.0,1.0);
|
||||
|
||||
// create Keystone right distortion camera
|
||||
osg::ref_ptr<osg::Camera> right_keystone_camera = assignKeystoneDistortionCamera(view, ds, gc.get(),
|
||||
traits->width/2, 0, traits->width/2, traits->height,
|
||||
traits->doubleBuffer ? GL_BACK : GL_FRONT,
|
||||
right_texture, right_keystone.get());
|
||||
|
||||
right_keystone_camera->setRenderOrder(osg::Camera::NESTED_RENDER, 3);
|
||||
|
||||
// attach Keystone editing event handler.
|
||||
right_keystone_camera->addEventCallback(new KeystoneHandler(right_keystone.get()));
|
||||
|
||||
view->getCamera()->setAllowEventFocus(false);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case(osg::DisplaySettings::VERTICAL_SPLIT):
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
|
||||
|
||||
std::string pick(float x, float y);
|
||||
std::string pick(const osgGA::GUIEventAdapter& event);
|
||||
|
||||
void highlight(const std::string& name)
|
||||
{
|
||||
@@ -83,15 +83,15 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
|
||||
case(osgGA::GUIEventAdapter::FRAME):
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"MOVE "<<ea.getX()<<ea.getY()<<std::endl;
|
||||
std::string picked_name = pick(ea.getX(),ea.getY());
|
||||
// osg::notify(osg::NOTICE)<<"MOVE "<<ea.getX()<<", "<<ea.getY()<<std::endl;
|
||||
std::string picked_name = pick(ea);
|
||||
highlight(picked_name);
|
||||
return false;
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"PUSH "<<ea.getX()<<ea.getY()<<std::endl;
|
||||
std::string picked_name = pick(ea.getX(),ea.getY());
|
||||
// osg::notify(osg::NOTICE)<<"PUSH "<<ea.getX()<<", "<<ea.getY()<<std::endl;
|
||||
std::string picked_name = pick(ea);
|
||||
if (!picked_name.empty())
|
||||
{
|
||||
runApp(picked_name);
|
||||
@@ -108,10 +108,10 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
|
||||
}
|
||||
|
||||
|
||||
std::string PickHandler::pick(float x, float y)
|
||||
std::string PickHandler::pick(const osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (_viewer->computeIntersections(x, y, intersections))
|
||||
if (_viewer->computeIntersections(event, intersections))
|
||||
{
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
|
||||
hitr != intersections.end();
|
||||
|
||||
@@ -148,8 +148,8 @@ bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
bool foundIntersection = view==0 ? false :
|
||||
(nv==0 ? view->computeIntersections(ea.getX(), ea.getY(), intersections) :
|
||||
view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections));
|
||||
(nv==0 ? view->computeIntersections(ea, intersections) :
|
||||
view->computeIntersections(ea, nv->getNodePath(), intersections));
|
||||
|
||||
if (foundIntersection)
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
|
||||
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
bool foundIntersection = view==0 ? false : view->computeIntersections(ea.getX(), ea.getY(), intersections);
|
||||
bool foundIntersection = view==0 ? false : view->computeIntersections(ea, intersections);
|
||||
|
||||
if (foundIntersection)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAct
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (view && view->computeIntersections(ea.getX(), ea.getY(), intersections))
|
||||
if (view && view->computeIntersections(ea, intersections))
|
||||
{
|
||||
const osgUtil::LineSegmentIntersector::Intersection& hit = *(intersections.begin());
|
||||
if (hit.matrix.valid()) addPoint(hit.localIntersectionPoint * (*hit.matrix));
|
||||
|
||||
@@ -122,17 +122,8 @@ void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
|
||||
std::string gdlist="";
|
||||
float x = ea.getX();
|
||||
float y = ea.getY();
|
||||
#if 0
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y);
|
||||
osgUtil::IntersectionVisitor iv(picker.get());
|
||||
view->getCamera()->accept(iv);
|
||||
if (picker->containsIntersections())
|
||||
if (view->computeIntersections(ea, intersections))
|
||||
{
|
||||
intersections = picker->getIntersections();
|
||||
#else
|
||||
if (view->computeIntersections(x,y,intersections))
|
||||
{
|
||||
#endif
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
|
||||
hitr != intersections.end();
|
||||
++hitr)
|
||||
|
||||
@@ -268,9 +268,9 @@ public:
|
||||
{
|
||||
osg::Group* root = dynamic_cast<osg::Group*>(viewer->getSceneData());
|
||||
if (!root) return;
|
||||
|
||||
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (viewer->computeIntersections(ea.getX(),ea.getY(),intersections))
|
||||
if (viewer->computeIntersections(ea,intersections))
|
||||
{
|
||||
const osgUtil::LineSegmentIntersector::Intersection& hit = *intersections.begin();
|
||||
|
||||
|
||||
@@ -106,19 +106,9 @@ void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
|
||||
std::string gdlist="";
|
||||
float x = ea.getX();
|
||||
float y = ea.getY();
|
||||
#if 0
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y);
|
||||
osgUtil::IntersectionVisitor iv(picker.get());
|
||||
view->getCamera()->accept(iv);
|
||||
if (picker->containsIntersections())
|
||||
|
||||
if (view->computeIntersections(ea,intersections))
|
||||
{
|
||||
intersections = picker->getIntersections();
|
||||
#else
|
||||
if (view->computeIntersections(x,y,intersections))
|
||||
{
|
||||
#endif
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
|
||||
hitr != intersections.end();
|
||||
++hitr)
|
||||
|
||||
@@ -38,6 +38,7 @@ struct ColorWidget: public osgWidget::Widget {
|
||||
}
|
||||
|
||||
bool mouseOver(double x, double y, const osgWidget::WindowManager*) {
|
||||
|
||||
osgWidget::Color c = getImageColorAtPointerXY(x, y);
|
||||
|
||||
if(c.a() < 0.001f) {
|
||||
@@ -45,7 +46,6 @@ struct ColorWidget: public osgWidget::Widget {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,13 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced
|
||||
|
||||
/** Set the graphics context associated with this event queue.*/
|
||||
void setGraphicsContext(osg::GraphicsContext* context) { getCurrentEventState()->setGraphicsContext(context); }
|
||||
|
||||
osg::GraphicsContext* getGraphicsContext() { return getCurrentEventState()->getGraphicsContext(); }
|
||||
|
||||
const osg::GraphicsContext* getGraphicsContext() const { return getCurrentEventState()->getGraphicsContext(); }
|
||||
|
||||
/** Read the window record dimensions from the graphics context. */
|
||||
void syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
|
||||
/** Set the mouse input range.*/
|
||||
|
||||
@@ -21,7 +21,59 @@
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
struct PointerData : public osg::Referenced
|
||||
{
|
||||
PointerData():
|
||||
object(0),
|
||||
x(0.0f),
|
||||
xMin(-1.0f),
|
||||
xMax(1.0f),
|
||||
y(0.0f),
|
||||
yMin(-1.0f),
|
||||
yMax(1.0f) {}
|
||||
|
||||
PointerData(osg::Object* obj, float in_x, float in_xMin, float in_xMax, float in_y, float in_yMin, float in_yMax):
|
||||
object(obj),
|
||||
x(in_x),
|
||||
xMin(in_xMin),
|
||||
xMax(in_xMax),
|
||||
y(in_y),
|
||||
yMin(in_yMin),
|
||||
yMax(in_yMax) {}
|
||||
|
||||
PointerData(const PointerData& pd):
|
||||
object(pd.object),
|
||||
x(pd.x),
|
||||
xMin(pd.xMin),
|
||||
xMax(pd.xMax),
|
||||
y(pd.y),
|
||||
yMin(pd.yMin),
|
||||
yMax(pd.yMax) {}
|
||||
|
||||
PointerData& operator = (const PointerData& pd)
|
||||
{
|
||||
if (&pd==this) return *this;
|
||||
|
||||
object = pd.object;
|
||||
x = pd.x;
|
||||
xMin = pd.xMin;
|
||||
xMax = pd.xMax;
|
||||
y = pd.y;
|
||||
yMin = pd.yMin;
|
||||
yMax = pd.yMax;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
osg::observer_ptr<osg::Object> object;
|
||||
float x, xMin, xMax;
|
||||
float y, yMin, yMax;
|
||||
|
||||
float getXnormalized() const { return (x-xMin)/(xMax-xMin)*2.0f-1.0f; }
|
||||
float getYnormalized() const { return (y-yMin)/(yMax-yMin)*2.0f-1.0f; }
|
||||
};
|
||||
|
||||
|
||||
/** Event class for storing Keyboard, mouse and window events.
|
||||
*/
|
||||
class OSGGA_EXPORT GUIEventAdapter : public osg::Object
|
||||
@@ -425,6 +477,7 @@ public:
|
||||
|
||||
|
||||
void setGraphicsContext(osg::GraphicsContext* context) { _context = context; }
|
||||
osg::GraphicsContext* getGraphicsContext() { return _context.get(); }
|
||||
const osg::GraphicsContext* getGraphicsContext() const { return _context.get(); }
|
||||
|
||||
|
||||
@@ -514,6 +567,21 @@ public:
|
||||
/** get current mouse y position.*/
|
||||
float getY() const { return _my; }
|
||||
|
||||
#if 1
|
||||
inline float getXnormalized() const
|
||||
{
|
||||
return _pointerDataList.size()>=1 ?
|
||||
_pointerDataList[_pointerDataList.size()-1]->getXnormalized():
|
||||
2.0f*(getX()-getXmin())/(getXmax()-getXmin())-1.0f;
|
||||
}
|
||||
|
||||
inline float getYnormalized() const
|
||||
{
|
||||
if (_pointerDataList.size()>=1) return _pointerDataList[_pointerDataList.size()-1]->getYnormalized();
|
||||
if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
|
||||
else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* return the current mouse x value normalized to the range of -1 to 1.
|
||||
* -1 would be the left hand side of the window.
|
||||
@@ -533,7 +601,7 @@ public:
|
||||
if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
|
||||
else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
|
||||
}
|
||||
|
||||
#endif
|
||||
/// set mouse-Y orientation (mouse-Y increases upwards or downwards).
|
||||
void setMouseYOrientation(MouseYOrientation myo) { _mouseYOrientation = myo; }
|
||||
|
||||
@@ -616,6 +684,22 @@ public:
|
||||
TouchData* getTouchData() const { return _touchData.get(); }
|
||||
bool isMultiTouchEvent() const { return (_touchData.valid()); }
|
||||
|
||||
|
||||
typedef std::vector< osg::ref_ptr<PointerData> > PointerDataList;
|
||||
void setPointerDataList(const PointerDataList& pdl) { _pointerDataList = pdl; }
|
||||
PointerDataList& getPointerDataList() { return _pointerDataList; }
|
||||
const PointerDataList& getPointerDataList() const { return _pointerDataList; }
|
||||
|
||||
unsigned int getNumPointerData() const { return _pointerDataList.size(); }
|
||||
PointerData* getPointerData(unsigned int i) { return _pointerDataList[i].get(); }
|
||||
const PointerData* getPointerData(unsigned int i) const { return _pointerDataList[i].get(); }
|
||||
|
||||
PointerData* getPointerData(osg::Object* obj) { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
|
||||
const PointerData* getPointerData(osg::Object* obj) const { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
|
||||
void addPointerData(PointerData* pd) { _pointerDataList.push_back(pd); }
|
||||
|
||||
void copyPointerDataFrom(const osgGA::GUIEventAdapter& sourceEvent);
|
||||
|
||||
protected:
|
||||
|
||||
/** Force users to create on heap, so that multiple referencing is safe.*/
|
||||
@@ -664,6 +748,9 @@ public:
|
||||
TabletPen _tabletPen;
|
||||
|
||||
osg::ref_ptr<TouchData> _touchData;
|
||||
|
||||
|
||||
PointerDataList _pointerDataList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector
|
||||
|
||||
const osg::Vec3& getLocalIntersectNormal() const { return localIntersectionNormal; }
|
||||
osg::Vec3 getWorldIntersectNormal() const { return matrix.valid() ? osg::Matrix::transform3x3(osg::Matrix::inverse(*matrix),localIntersectionNormal) : localIntersectionNormal; }
|
||||
|
||||
/** convinience function for mapping the intersection point to any textures assigned to the objects intersected.
|
||||
* Returns the Texture pointer and texture coords of object hit when a texture is available on the object, returns NULL otherwise.*/
|
||||
osg::Texture* getTextureLookUp(osg::Vec3& tc) const;
|
||||
|
||||
};
|
||||
|
||||
typedef std::multiset<Intersection> Intersections;
|
||||
|
||||
@@ -123,6 +123,10 @@ class OSGVIEWER_EXPORT CompositeViewer : public ViewerBase
|
||||
|
||||
virtual void viewerInit();
|
||||
|
||||
void generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event);
|
||||
void generatePointerData(osgGA::GUIEventAdapter& event);
|
||||
void reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event);
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osgViewer::View> > RefViews;
|
||||
RefViews _views;
|
||||
|
||||
@@ -135,6 +139,8 @@ class OSGVIEWER_EXPORT CompositeViewer : public ViewerBase
|
||||
|
||||
osg::observer_ptr<osg::Camera> _cameraWithFocus;
|
||||
osg::observer_ptr<osgViewer::View> _viewWithFocus;
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> _previousEvent;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -227,20 +227,29 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter
|
||||
/** Return true if this view contains a specified camera.*/
|
||||
bool containsCamera(const osg::Camera* camera) const;
|
||||
|
||||
/** Get the camera which contains the pointer position x,y specified in the master camera's window/eye coordinates.
|
||||
* Also passes back the local window coordinatess for the graphics context associated with the camera. */
|
||||
|
||||
/** deprecated. */
|
||||
const osg::Camera* getCameraContainingPosition(float x, float y, float& local_x, float& local_y) const;
|
||||
|
||||
/** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified node.
|
||||
* Note, when a master camera has slaves and no viewport itself, its coordinate frame will be in clip space i.e. -1,-1 to 1,1,
|
||||
* while if it has a viewport the coordintates will be relative to its viewport dimensions.
|
||||
* Mouse events handled by the view will automatically be attached to the master camera window/clip coordinates so that they can be passed
|
||||
* directly to the computeIntersections method. */
|
||||
/** deprecated. */
|
||||
bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
/** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */
|
||||
/** deprecated. */
|
||||
bool computeIntersections(float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
|
||||
/** Compute intersections of a ray, starting the current mouse position, through the specified camera. */
|
||||
bool computeIntersections(const osgGA::GUIEventAdapter& ea, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
/** Compute intersections of a ray, starting the current mouse position, through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */
|
||||
bool computeIntersections(const osgGA::GUIEventAdapter& ea, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
|
||||
/** Compute intersections of a ray through the specified camera. */
|
||||
bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
/** Compute intersections of a ray through the specified camera and a specified nodePath's subgraph. */
|
||||
bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
|
||||
|
||||
virtual void requestRedraw();
|
||||
virtual void requestContinuousUpdate(bool needed=true);
|
||||
|
||||
@@ -93,10 +93,6 @@ class OSGVIEWER_EXPORT Viewer : public ViewerBase, public osgViewer::View
|
||||
|
||||
virtual void updateTraversal();
|
||||
|
||||
void setCameraWithFocus(osg::Camera* camera) { _cameraWithFocus = camera; }
|
||||
osg::Camera* getCameraWithFocus() { return _cameraWithFocus.get(); }
|
||||
const osg::Camera* getCameraWithFocus() const { return _cameraWithFocus.get(); }
|
||||
|
||||
virtual void getCameras(Cameras& cameras, bool onlyActive=true);
|
||||
|
||||
virtual void getContexts(Contexts& contexts, bool onlyValid=true);
|
||||
@@ -119,8 +115,9 @@ class OSGVIEWER_EXPORT Viewer : public ViewerBase, public osgViewer::View
|
||||
|
||||
virtual void viewerInit() { init(); }
|
||||
|
||||
osg::observer_ptr<osg::Camera> _cameraWithFocus;
|
||||
|
||||
void generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event);
|
||||
void generatePointerData(osgGA::GUIEventAdapter& event);
|
||||
void reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -528,7 +528,6 @@ protected:
|
||||
osg::Object(), osgGA::GUIEventHandler(), osg::Drawable::CullCallback(), _fullscreen(false) {}
|
||||
|
||||
bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
|
||||
bool computeIntersections(osgViewer::View* view, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff) const;
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
|
||||
@@ -132,6 +132,11 @@ bool EventQueue::copyEvents(Events& events) const
|
||||
}
|
||||
}
|
||||
|
||||
void EventQueue::syncWindowRectangleWithGraphcisContext()
|
||||
{
|
||||
const osg::GraphicsContext::Traits* traits = (getGraphicsContext()!=0) ? getGraphicsContext()->getTraits() : 0;
|
||||
if (traits) _accumulateEventState->setWindowRectangle(traits->x, traits->y, traits->width, traits->height, !_useFixedMouseInputRange);
|
||||
}
|
||||
|
||||
void EventQueue::windowResize(int x, int y, int width, int height, double time)
|
||||
{
|
||||
@@ -490,6 +495,8 @@ void EventQueue::frame(double time)
|
||||
GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
|
||||
event->setEventType(GUIEventAdapter::FRAME);
|
||||
event->setTime(time);
|
||||
|
||||
OSG_NOTICE<<"frame("<<time<<"), event->getX()="<<event->getX()<<", event->getY()="<<event->getY()<<", event->getXmin()="<<event->getXmin()<<", event->getYmin()="<<event->getYmin()<<", event->getXmax()="<<event->getXmax()<<", event->getYmax()="<<event->getYmax()<<std::endl;
|
||||
|
||||
addEvent(event);
|
||||
}
|
||||
|
||||
@@ -122,3 +122,14 @@ void GUIEventAdapter::addTouchPoint(unsigned int id, TouchPhase phase, float x,
|
||||
|
||||
_touchData->addTouchPoint(id, phase, x, y, tapCount);
|
||||
}
|
||||
|
||||
void GUIEventAdapter::copyPointerDataFrom(const osgGA::GUIEventAdapter& sourceEvent)
|
||||
{
|
||||
setGraphicsContext(const_cast<osg::GraphicsContext*>(sourceEvent.getGraphicsContext()));
|
||||
setX(sourceEvent.getX());
|
||||
setY(sourceEvent.getY());
|
||||
setInputRange(sourceEvent.getXmin(), sourceEvent.getYmin(), sourceEvent.getXmax(), sourceEvent.getYmax());
|
||||
setButtonMask(sourceEvent.getButtonMask());
|
||||
setMouseYOrientation(sourceEvent.getMouseYOrientation());
|
||||
setPointerDataList(sourceEvent.getPointerDataList());
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ bool Dragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&
|
||||
|
||||
_pointer.reset();
|
||||
|
||||
if (view->computeIntersections(ea.getX(),ea.getY(),intersections, _intersectionMask))
|
||||
if (view->computeIntersections(ea ,intersections, _intersectionMask))
|
||||
{
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
|
||||
hitr != intersections.end();
|
||||
|
||||
@@ -1419,7 +1419,7 @@ bool ReaderWriterP3DXML::getKeyPositionInner(osgDB::XmlNode*cur, osgPresentation
|
||||
{
|
||||
keyValue = itr->second;
|
||||
}
|
||||
if (key.find("0x",0,2)!=std::string::npos)
|
||||
else if (key.find("0x",0,2)!=std::string::npos)
|
||||
{
|
||||
std::istringstream iss(key);
|
||||
iss>>std::hex>>keyValue;
|
||||
@@ -1438,7 +1438,7 @@ bool ReaderWriterP3DXML::getKeyPositionInner(osgDB::XmlNode*cur, osgPresentation
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"Warning: invalid key used in <key>"<<key<<"</key>, ignoring tag."<<std::endl;
|
||||
OSG_NOTICE<<"Warning: invalid key used in <key>"<<key<<"</key>, ignoring tag. key=["<<key<<"]"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
|
||||
}
|
||||
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
if (viewer->computeIntersections(ea.getX(),ea.getY(), nv->getNodePath(), intersections))
|
||||
if (viewer->computeIntersections(ea, nv->getNodePath(), intersections))
|
||||
{
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();
|
||||
hitr!=intersections.end();
|
||||
|
||||
@@ -432,6 +432,9 @@ bool GraphicsWindowQt::init( QWidget* parent, const QGLWidget* shareWidget, Qt::
|
||||
getState()->setContextID( osg::GraphicsContext::createNewContextID() );
|
||||
}
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -647,6 +650,9 @@ bool GraphicsWindowQt::realizeImplementation()
|
||||
|
||||
_realized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
// make this window's context not current
|
||||
// note: this must be done as we will probably make the context current from another thread
|
||||
// and it is not allowed to have one context current in two threads
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <osg/TriangleFunctor>
|
||||
#include <osg/KdTree>
|
||||
#include <osg/Timer>
|
||||
#include <osg/TexMat>
|
||||
|
||||
using namespace osgUtil;
|
||||
|
||||
@@ -613,3 +614,111 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::Texture* LineSegmentIntersector::Intersection::getTextureLookUp(osg::Vec3& tc) const
|
||||
{
|
||||
osg::Geometry* geometry = drawable.valid() ? drawable->asGeometry() : 0;
|
||||
osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
|
||||
|
||||
if (vertices)
|
||||
{
|
||||
if (indexList.size()==3 && ratioList.size()==3)
|
||||
{
|
||||
unsigned int i1 = indexList[0];
|
||||
unsigned int i2 = indexList[1];
|
||||
unsigned int i3 = indexList[2];
|
||||
|
||||
float r1 = ratioList[0];
|
||||
float r2 = ratioList[1];
|
||||
float r3 = ratioList[2];
|
||||
|
||||
osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
|
||||
osg::FloatArray* texcoords_FloatArray = dynamic_cast<osg::FloatArray*>(texcoords);
|
||||
osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
|
||||
osg::Vec3Array* texcoords_Vec3Array = dynamic_cast<osg::Vec3Array*>(texcoords);
|
||||
if (texcoords_FloatArray)
|
||||
{
|
||||
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
|
||||
float tc1 = (*texcoords_FloatArray)[i1];
|
||||
float tc2 = (*texcoords_FloatArray)[i2];
|
||||
float tc3 = (*texcoords_FloatArray)[i3];
|
||||
tc.x() = tc1*r1 + tc2*r2 + tc3*r3;
|
||||
}
|
||||
else if (texcoords_Vec2Array)
|
||||
{
|
||||
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
|
||||
const osg::Vec2& tc1 = (*texcoords_Vec2Array)[i1];
|
||||
const osg::Vec2& tc2 = (*texcoords_Vec2Array)[i2];
|
||||
const osg::Vec2& tc3 = (*texcoords_Vec2Array)[i3];
|
||||
tc.x() = tc1.x()*r1 + tc2.x()*r2 + tc3.x()*r3;
|
||||
tc.y() = tc1.y()*r1 + tc2.y()*r2 + tc3.y()*r3;
|
||||
}
|
||||
else if (texcoords_Vec3Array)
|
||||
{
|
||||
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
|
||||
const osg::Vec3& tc1 = (*texcoords_Vec3Array)[i1];
|
||||
const osg::Vec3& tc2 = (*texcoords_Vec3Array)[i2];
|
||||
const osg::Vec3& tc3 = (*texcoords_Vec3Array)[i3];
|
||||
tc.x() = tc1.x()*r1 + tc2.x()*r2 + tc3.x()*r3;
|
||||
tc.y() = tc1.y()*r1 + tc2.y()*r2 + tc3.y()*r3;
|
||||
tc.z() = tc1.z()*r1 + tc2.z()*r2 + tc3.z()*r3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const osg::TexMat* activeTexMat = 0;
|
||||
const osg::Texture* activeTexture = 0;
|
||||
|
||||
if (drawable->getStateSet())
|
||||
{
|
||||
const osg::TexMat* texMat = dynamic_cast<osg::TexMat*>(drawable->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXMAT));
|
||||
if (texMat) activeTexMat = texMat;
|
||||
|
||||
const osg::Texture* texture = dynamic_cast<osg::Texture*>(drawable->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
|
||||
if (texture) activeTexture = texture;
|
||||
}
|
||||
|
||||
for(osg::NodePath::const_reverse_iterator itr = nodePath.rbegin();
|
||||
itr != nodePath.rend() && (!activeTexMat || !activeTexture);
|
||||
++itr)
|
||||
{
|
||||
const osg::Node* node = *itr;
|
||||
if (node->getStateSet())
|
||||
{
|
||||
if (!activeTexMat)
|
||||
{
|
||||
const osg::TexMat* texMat = dynamic_cast<const osg::TexMat*>(node->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXMAT));
|
||||
if (texMat) activeTexMat = texMat;
|
||||
}
|
||||
|
||||
if (!activeTexture)
|
||||
{
|
||||
const osg::Texture* texture = dynamic_cast<const osg::Texture*>(node->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
|
||||
if (texture) activeTexture = texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activeTexMat)
|
||||
{
|
||||
osg::Vec4 tc_transformed = osg::Vec4(tc.x(), tc.y(), tc.z() ,0.0f) * activeTexMat->getMatrix();
|
||||
tc.x() = tc_transformed.x();
|
||||
tc.y() = tc_transformed.y();
|
||||
tc.z() = tc_transformed.z();
|
||||
|
||||
if (activeTexture && activeTexMat->getScaleByTextureRectangleSize())
|
||||
{
|
||||
tc.x() *= static_cast<float>(activeTexture->getTextureWidth());
|
||||
tc.y() *= static_cast<float>(activeTexture->getTextureHeight());
|
||||
tc.z() *= static_cast<float>(activeTexture->getTextureDepth());
|
||||
}
|
||||
}
|
||||
|
||||
return const_cast<osg::Texture*>(activeTexture);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
*/
|
||||
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osg/TextureCubeMap>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
#include <osgViewer/Renderer>
|
||||
@@ -640,27 +643,6 @@ void CompositeViewer::advance(double simulationTime)
|
||||
_frameStamp->setSimulationTime(simulationTime);
|
||||
}
|
||||
|
||||
for(RefViews::iterator vitr = _views.begin();
|
||||
vitr != _views.end();
|
||||
++vitr)
|
||||
{
|
||||
View* view = vitr->get();
|
||||
|
||||
osgGA::GUIEventAdapter* eventState = view->getEventQueue()->getCurrentEventState();
|
||||
if (view->getCamera()->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = view->getCamera()->getViewport();
|
||||
eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
|
||||
}
|
||||
else
|
||||
{
|
||||
eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );
|
||||
}
|
||||
|
||||
|
||||
if (getViewerStats() && getViewerStats()->collectStats("frame_rate"))
|
||||
{
|
||||
@@ -697,6 +679,195 @@ void CompositeViewer::setCameraWithFocus(osg::Camera* camera)
|
||||
_viewWithFocus = 0;
|
||||
}
|
||||
|
||||
|
||||
void CompositeViewer::generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
// What type of Camera is it?
|
||||
// 1) Master Camera : do nothin extra
|
||||
// 2) Slave Camera, Relative RF, Same scene graph as master : transform coords into Master Camera and add to PointerData list
|
||||
// 3) Slave Camera, Relative RF, Different scene graph from master : do nothing extra?
|
||||
// 4) Slave Camera, Absolute RF, Same scene graph as master : do nothing extra?
|
||||
// 5) Slave Camera, Absolute RF, Different scene graph : do nothing extra?
|
||||
// 6) Slave Camera, Absolute RF, Different scene graph but a distortion correction subgraph depending upon RTT Camera (slave or master)
|
||||
// : project ray into RTT Camera's clip space, and RTT Camera's is Relative RF and sharing same scene graph as master then transform coords.
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
|
||||
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(camera->getView());
|
||||
if (!view) return;
|
||||
|
||||
osg::Camera* view_masterCamera = view->getCamera();
|
||||
if (camera!=view_masterCamera)
|
||||
{
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
bool invert_y = event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
osg::Matrix masterCameraVPW = view_masterCamera->getViewMatrix() * view_masterCamera->getProjectionMatrix();
|
||||
if (view_masterCamera->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = view_masterCamera->getViewport();
|
||||
masterCameraVPW *= viewport->computeWindowMatrix();
|
||||
}
|
||||
|
||||
// slave Camera tahnks to sharing the same View
|
||||
osg::View::Slave* slave = view ? view->findSlaveForCamera(camera) : 0;
|
||||
if (slave)
|
||||
{
|
||||
if (camera->getReferenceFrame()==osg::Camera::RELATIVE_RF && slave->_useMastersSceneData)
|
||||
{
|
||||
osg::Viewport* viewport = camera->getViewport();
|
||||
osg::Matrix localCameraVPW = camera->getViewMatrix() * camera->getProjectionMatrix();
|
||||
if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
|
||||
|
||||
osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
|
||||
osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
|
||||
//OSG_NOTICE<<" pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
|
||||
event.addPointerData(new osgGA::PointerData(view_masterCamera, new_coord.x(), -1.0, 1.0,
|
||||
new_coord.y(), -1.0, 1.0));
|
||||
}
|
||||
else if (!slave->_useMastersSceneData)
|
||||
{
|
||||
// Are their any RTT Camera's that this Camera depends upon for textures?
|
||||
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> ray = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x,y);
|
||||
osgUtil::IntersectionVisitor iv(ray.get());
|
||||
camera->accept(iv);
|
||||
if (ray->containsIntersections())
|
||||
{
|
||||
osg::Vec3 tc;
|
||||
osg::Texture* texture = ray->getFirstIntersection().getTextureLookUp(tc);
|
||||
if (texture)
|
||||
{
|
||||
// look up Texture in RTT Camera's.
|
||||
for(unsigned int i=0; i<view->getNumSlaves();++i)
|
||||
{
|
||||
osg::Camera* slave_camera = view->getSlave(i)._camera;
|
||||
if (slave_camera)
|
||||
{
|
||||
osg::Camera::BufferAttachmentMap::const_iterator ba_itr = slave_camera->getBufferAttachmentMap().find(osg::Camera::COLOR_BUFFER);
|
||||
if (ba_itr != slave_camera->getBufferAttachmentMap().end())
|
||||
{
|
||||
if (ba_itr->second._texture == texture)
|
||||
{
|
||||
osg::TextureRectangle* tr = dynamic_cast<osg::TextureRectangle*>(ba_itr->second._texture.get());
|
||||
osg::TextureCubeMap* tcm = dynamic_cast<osg::TextureCubeMap*>(ba_itr->second._texture.get());
|
||||
if (tr)
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(slave_camera, tc.x(), 0.0f, static_cast<float>(tr->getTextureWidth()),
|
||||
tc.y(), 0.0f, static_cast<float>(tr->getTextureHeight())));
|
||||
}
|
||||
else if (tcm)
|
||||
{
|
||||
OSG_NOTICE<<" Slave has matched texture cubemap"<<ba_itr->second._texture.get()<<", "<<ba_itr->second._face<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(slave_camera, tc.x(), 0.0f, 1.0f,
|
||||
tc.y(), 0.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CompositeViewer::generatePointerData(osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
bool invert_y = event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
event.addPointerData(new osgGA::PointerData(gw, x, 0, gw->getTraits()->width,
|
||||
y, 0, gw->getTraits()->height));
|
||||
|
||||
osg::GraphicsContext::Cameras& cameras = gw->getCameras();
|
||||
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
|
||||
citr != cameras.end();
|
||||
++citr)
|
||||
{
|
||||
osg::Camera* camera = *citr;
|
||||
if (camera->getAllowEventFocus() &&
|
||||
camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
|
||||
{
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
if (viewport &&
|
||||
x >= viewport->x() && y >= viewport->y() &&
|
||||
x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(camera, (x-viewport->x())/viewport->width()*2.0f-1.0f, -1.0, 1.0,
|
||||
(y-viewport->y())/viewport->height()*2.0f-1.0f, -1.0, 1.0));
|
||||
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(camera->getView());
|
||||
osg::Camera* view_masterCamera = view ? view->getCamera() : 0;
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
if (view && camera!=view_masterCamera)
|
||||
{
|
||||
generateSlavePointerData(camera, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompositeViewer::reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(dest_event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
float x = dest_event.getX();
|
||||
float y = dest_event.getY();
|
||||
|
||||
bool invert_y = dest_event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
dest_event.addPointerData(new osgGA::PointerData(gw, x, 0, gw->getTraits()->width,
|
||||
y, 0, gw->getTraits()->height));
|
||||
|
||||
osg::Camera* camera = (source_event.getNumPointerData()>=2) ? dynamic_cast<osg::Camera*>(source_event.getPointerData(1)->object.get()) : 0;
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
|
||||
if (!viewport) return;
|
||||
|
||||
dest_event.addPointerData(new osgGA::PointerData(camera, (x-viewport->x())/viewport->width()*2.0f-1.0f, -1.0, 1.0,
|
||||
(y-viewport->y())/viewport->height()*2.0f-1.0f, -1.0, 1.0));
|
||||
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(camera->getView());
|
||||
osg::Camera* view_masterCamera = view ? view->getCamera() : 0;
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
if (view && camera!=view_masterCamera)
|
||||
{
|
||||
generateSlavePointerData(camera, dest_event);
|
||||
}
|
||||
}
|
||||
|
||||
struct SortEvents
|
||||
{
|
||||
bool operator() (const osg::ref_ptr<osgGA::GUIEventAdapter>& lhs,const osg::ref_ptr<osgGA::GUIEventAdapter>& rhs) const
|
||||
{
|
||||
return lhs->getTime() < rhs->getTime();
|
||||
}
|
||||
};
|
||||
|
||||
void CompositeViewer::eventTraversal()
|
||||
{
|
||||
if (_done) return;
|
||||
@@ -707,10 +878,7 @@ void CompositeViewer::eventTraversal()
|
||||
|
||||
double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
|
||||
|
||||
// OSG_NOTICE<<"CompositeViewer::frameEventTraversal()."<<std::endl;
|
||||
|
||||
// need to copy events from the GraphicsWindow's into local EventQueue;
|
||||
|
||||
// need to copy events from the GraphicsWindow's into local EventQueue for each view;
|
||||
typedef std::map<osgViewer::View*, osgGA::EventQueue::Events> ViewEventsMap;
|
||||
ViewEventsMap viewEventsMap;
|
||||
|
||||
@@ -720,22 +888,9 @@ void CompositeViewer::eventTraversal()
|
||||
// set done if there are no windows
|
||||
checkWindowStatus(contexts);
|
||||
if (_done) return;
|
||||
|
||||
Scenes scenes;
|
||||
getScenes(scenes);
|
||||
|
||||
osgViewer::View* masterView = getViewWithFocus() ? getViewWithFocus() : _views[0].get();
|
||||
|
||||
osg::Camera* masterCamera = masterView->getCamera();
|
||||
osgGA::GUIEventAdapter* eventState = masterView->getEventQueue()->getCurrentEventState();
|
||||
osg::Matrix masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
|
||||
if (masterCamera->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = masterCamera->getViewport();
|
||||
masterCameraVPW *= viewport->computeWindowMatrix();
|
||||
}
|
||||
|
||||
// get events from all windows attached to Viewer.
|
||||
|
||||
osgGA::EventQueue::Events all_events;
|
||||
|
||||
for(Contexts::iterator citr = contexts.begin();
|
||||
citr != contexts.end();
|
||||
++citr)
|
||||
@@ -748,178 +903,130 @@ void CompositeViewer::eventTraversal()
|
||||
osgGA::EventQueue::Events gw_events;
|
||||
gw->getEventQueue()->takeEvents(gw_events, cutOffTime);
|
||||
|
||||
osgGA::EventQueue::Events::iterator itr;
|
||||
for(itr = gw_events.begin();
|
||||
for(osgGA::EventQueue::Events::iterator itr = gw_events.begin();
|
||||
itr != gw_events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
//OSG_NOTICE<<"event->getGraphicsContext()="<<event->getGraphicsContext()<<std::endl;
|
||||
|
||||
bool pointerEvent = false;
|
||||
|
||||
float x = event->getX();
|
||||
float y = event->getY();
|
||||
|
||||
bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::RESIZE):
|
||||
setCameraWithFocus(0);
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
case(osgGA::GUIEventAdapter::DOUBLECLICK):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
{
|
||||
pointerEvent = true;
|
||||
|
||||
if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
|
||||
{
|
||||
osg::GraphicsContext::Cameras& cameras = gw->getCameras();
|
||||
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
|
||||
citr != cameras.end();
|
||||
++citr)
|
||||
{
|
||||
osg::Camera* camera = *citr;
|
||||
if ((camera->getNodeMask()!=0) &&
|
||||
camera->getView() &&
|
||||
camera->getAllowEventFocus() &&
|
||||
camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
|
||||
{
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
if (viewport &&
|
||||
x >= viewport->x() && y >= viewport->y() &&
|
||||
x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
|
||||
{
|
||||
setCameraWithFocus(camera);
|
||||
|
||||
// If this camera is not a slave camera
|
||||
if (camera->getView()->getCamera() == camera)
|
||||
{
|
||||
eventState->setGraphicsContext(gw);
|
||||
eventState->setInputRange( viewport->x(), viewport->y(),
|
||||
viewport->x()+viewport->width(),
|
||||
viewport->y()+viewport->height());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
if (getViewWithFocus()!=masterView)
|
||||
{
|
||||
// need to reset the masterView
|
||||
masterView = getViewWithFocus();
|
||||
masterCamera = masterView->getCamera();
|
||||
eventState = masterView->getEventQueue()->getCurrentEventState();
|
||||
masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
|
||||
|
||||
if (masterCamera->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = masterCamera->getViewport();
|
||||
masterCameraVPW *= viewport->computeWindowMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
// If this camera is not a slave camera
|
||||
if (camera->getView()->getCamera() == camera)
|
||||
{
|
||||
eventState->setGraphicsContext(gw);
|
||||
eventState->setInputRange( viewport->x(), viewport->y(),
|
||||
viewport->x()+viewport->width(),
|
||||
viewport->y()+viewport->height());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pointerEvent)
|
||||
{
|
||||
if (getCameraWithFocus())
|
||||
{
|
||||
osg::Viewport* viewport = getCameraWithFocus()->getViewport();
|
||||
osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
|
||||
if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
|
||||
|
||||
osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
|
||||
|
||||
osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
|
||||
|
||||
x = new_coord.x();
|
||||
y = new_coord.y();
|
||||
|
||||
event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
|
||||
event->setX(x);
|
||||
event->setY(y);
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
}
|
||||
// pass along the new pointer events details to the eventState of the viewer
|
||||
eventState->setX(x);
|
||||
eventState->setY(y);
|
||||
eventState->setButtonMask(event->getButtonMask());
|
||||
eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
|
||||
event->setX(eventState->getX());
|
||||
event->setY(eventState->getY());
|
||||
event->setButtonMask(eventState->getButtonMask());
|
||||
event->setMouseYOrientation(eventState->getMouseYOrientation());
|
||||
}
|
||||
(*itr)->setGraphicsContext(gw);
|
||||
}
|
||||
|
||||
for(itr = gw_events.begin();
|
||||
itr != gw_events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
|
||||
{
|
||||
bool wasThreading = areThreadsRunning();
|
||||
if (wasThreading) stopThreading();
|
||||
|
||||
gw->close();
|
||||
|
||||
if (wasThreading) startThreading();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
viewEventsMap[masterView].insert( viewEventsMap[masterView].end(), gw_events.begin(), gw_events.end() );
|
||||
|
||||
all_events.insert(all_events.end(), gw_events.begin(), gw_events.end());
|
||||
}
|
||||
}
|
||||
|
||||
// sort all the events in time order so we can make sure we pass them all on in the correct order.
|
||||
all_events.sort(SortEvents());
|
||||
|
||||
// pass on pointer data onto non mouse events to keep the position data usable by all recipients of all events.
|
||||
for(osgGA::EventQueue::Events::iterator itr = all_events.begin();
|
||||
itr != all_events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
// OSG_NOTICE<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
case(osgGA::GUIEventAdapter::DOUBLECLICK):
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
{
|
||||
if ((event->getEventType()!=osgGA::GUIEventAdapter::DRAG && event->getEventType()!=osgGA::GUIEventAdapter::RELEASE) ||
|
||||
!_previousEvent ||
|
||||
_previousEvent->getGraphicsContext()!=event->getGraphicsContext() ||
|
||||
_previousEvent->getNumPointerData()<2)
|
||||
{
|
||||
generatePointerData(*event);
|
||||
}
|
||||
else
|
||||
{
|
||||
reprojectPointerData(*_previousEvent, *event);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// assign topmost PointeData settings as the events X,Y and InputRange
|
||||
osgGA::PointerData* pd = event->getPointerData(event->getNumPointerData()-1);
|
||||
event->setX(pd->x);
|
||||
event->setY(pd->y);
|
||||
event->setInputRange(pd->xMin, pd->yMin, pd->xMax, pd->yMax);
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
#else
|
||||
if (event->getMouseYOrientation()!=osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
|
||||
{
|
||||
event->setY((event->getYmax()-event->getY())+event->getYmin());
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
}
|
||||
#endif
|
||||
|
||||
_previousEvent = event;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (_previousEvent.valid()) event->copyPointerDataFrom(*_previousEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
osgGA::PointerData* pd = event->getNumPointerData()>0 ? event->getPointerData(event->getNumPointerData()-1) : 0;
|
||||
osg::Camera* camera = pd ? dynamic_cast<osg::Camera*>(pd->object.get()) : 0;
|
||||
osgViewer::View* view = camera ? dynamic_cast<osgViewer::View*>(camera->getView()) : 0;
|
||||
|
||||
if (!view)
|
||||
{
|
||||
if (_viewWithFocus.valid())
|
||||
{
|
||||
// OSG_NOTICE<<"Falling back to using _viewWithFocus"<<std::endl;
|
||||
view = _viewWithFocus.get();
|
||||
}
|
||||
else if (!_views.empty())
|
||||
{
|
||||
// OSG_NOTICE<<"Falling back to using first view as one with focus"<<std::endl;
|
||||
view = _views[0].get();
|
||||
}
|
||||
}
|
||||
|
||||
// reassign view with focus
|
||||
if (_viewWithFocus != view) _viewWithFocus = view;
|
||||
|
||||
if (view)
|
||||
{
|
||||
viewEventsMap[view].push_back( event );
|
||||
|
||||
osgGA::GUIEventAdapter* eventState = view->getEventQueue()->getCurrentEventState();
|
||||
eventState->copyPointerDataFrom(*event);
|
||||
}
|
||||
|
||||
_previousEvent = event;
|
||||
}
|
||||
|
||||
// handle any close windows
|
||||
for(osgGA::EventQueue::Events::iterator itr = all_events.begin();
|
||||
itr != all_events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
|
||||
{
|
||||
bool wasThreading = areThreadsRunning();
|
||||
if (wasThreading) stopThreading();
|
||||
|
||||
if (event->getGraphicsContext())
|
||||
{
|
||||
event->getGraphicsContext()->close();
|
||||
}
|
||||
|
||||
if (wasThreading) startThreading();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(RefViews::iterator vitr = _views.begin();
|
||||
vitr != _views.end();
|
||||
@@ -941,12 +1048,12 @@ void CompositeViewer::eventTraversal()
|
||||
es->getEventQueue()->takeEvents(viewEventsMap[view], cutOffTime);
|
||||
}
|
||||
|
||||
// generate frame event
|
||||
view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );
|
||||
|
||||
view->getEventQueue()->takeEvents(viewEventsMap[view], cutOffTime);
|
||||
}
|
||||
|
||||
|
||||
// OSG_NOTICE<<"Events "<<events.size()<<std::endl;
|
||||
|
||||
if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
|
||||
{
|
||||
for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
|
||||
@@ -987,10 +1094,11 @@ void CompositeViewer::eventTraversal()
|
||||
++veitr)
|
||||
{
|
||||
View* view = veitr->first;
|
||||
_eventVisitor->setActionAdapter(view);
|
||||
|
||||
if (view->getSceneData())
|
||||
if (view && view->getSceneData())
|
||||
{
|
||||
_eventVisitor->setActionAdapter(view);
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
|
||||
itr != veitr->second.end();
|
||||
++itr)
|
||||
@@ -1078,8 +1186,6 @@ void CompositeViewer::eventTraversal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (getViewerStats() && getViewerStats()->collectStats("event"))
|
||||
{
|
||||
double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
|
||||
@@ -1091,7 +1197,6 @@ void CompositeViewer::eventTraversal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CompositeViewer::updateTraversal()
|
||||
{
|
||||
if (_done) return;
|
||||
|
||||
@@ -251,6 +251,9 @@ void GraphicsWindowCarbon::init()
|
||||
}
|
||||
_valid = (_pixelFormat != NULL);
|
||||
_initialized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
}
|
||||
|
||||
bool GraphicsWindowCarbon::setWindowDecorationImplementation(bool flag)
|
||||
@@ -452,6 +455,10 @@ bool GraphicsWindowCarbon::realizeImplementation()
|
||||
_currentVSync = _traits->vsync;
|
||||
|
||||
_realized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
return _realized;
|
||||
}
|
||||
|
||||
|
||||
@@ -1074,6 +1074,9 @@ void GraphicsWindowCocoa::init()
|
||||
|
||||
_updateContext = false;
|
||||
_valid = _initialized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
}
|
||||
|
||||
|
||||
@@ -1241,6 +1244,9 @@ bool GraphicsWindowCocoa::realizeImplementation()
|
||||
// Cocoa's origin is bottom/left:
|
||||
getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
_valid = _initialized = _realized = true;
|
||||
return _valid;
|
||||
}
|
||||
|
||||
@@ -727,6 +727,9 @@ void GraphicsWindowIOS::init()
|
||||
//if -1.0 we use the screens scale factor
|
||||
_viewContentScaleFactor = -1.0f;
|
||||
_valid = _initialized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
}
|
||||
|
||||
|
||||
@@ -889,6 +892,9 @@ bool GraphicsWindowIOS::realizeImplementation()
|
||||
|
||||
// IOSs origin is top/left:
|
||||
getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
_valid = _initialized = _realized = true;
|
||||
return _valid;
|
||||
|
||||
@@ -1184,6 +1184,9 @@ void GraphicsWindowWin32::init()
|
||||
|
||||
_initialized = _ownsWindow ? createWindow() : setWindow(windowHandle);
|
||||
_valid = _initialized;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
// 2008/10/03
|
||||
// Few days ago NVidia released WHQL certified drivers ver 178.13.
|
||||
@@ -1986,6 +1989,9 @@ bool GraphicsWindowWin32::realizeImplementation()
|
||||
|
||||
_realized = true;
|
||||
|
||||
// make sure the event queue has the correct window rectangle size and input range
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -841,8 +841,7 @@ void GraphicsWindowX11::init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
}
|
||||
|
||||
bool GraphicsWindowX11::createWindow()
|
||||
@@ -995,7 +994,7 @@ bool GraphicsWindowX11::createWindow()
|
||||
XFlush( _eventDisplay );
|
||||
XSync( _eventDisplay, 0 );
|
||||
rescanModifierMapping();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1055,9 @@ bool GraphicsWindowX11::realizeImplementation()
|
||||
|
||||
XMapWindow( _display, _window );
|
||||
|
||||
// Window temp = _window;
|
||||
getEventQueue()->syncWindowRectangleWithGraphcisContext();
|
||||
|
||||
// Window temp = _window;
|
||||
// XSetWMColormapWindows( _display, _window, &temp, 1);
|
||||
|
||||
_realized = true;
|
||||
|
||||
@@ -1062,7 +1062,7 @@ void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned
|
||||
camera->setDrawBuffer(buffer);
|
||||
camera->setReadBuffer(buffer);
|
||||
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
camera->setAllowEventFocus(false);
|
||||
camera->setAllowEventFocus(true);
|
||||
camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
|
||||
//camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
@@ -1956,7 +1956,7 @@ void View::requestContinuousUpdate(bool flag)
|
||||
void View::requestWarpPointer(float x,float y)
|
||||
{
|
||||
OSG_INFO<<"View::requestWarpPointer("<<x<<","<<y<<")"<<std::endl;
|
||||
|
||||
|
||||
float local_x, local_y;
|
||||
const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
|
||||
if (camera)
|
||||
@@ -1991,45 +1991,55 @@ bool View::containsCamera(const osg::Camera* camera) const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const osg::Camera* View::getCameraContainingPosition(float x, float y, float& local_x, float& local_y) const
|
||||
{
|
||||
const osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
|
||||
const osgViewer::GraphicsWindow* gw = dynamic_cast<const osgViewer::GraphicsWindow*>(eventState->getGraphicsContext());
|
||||
|
||||
bool view_invert_y = eventState->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
|
||||
// OSG_NOTICE<<"getCameraContainingPosition("<<x<<", "<<y<<") view_invert_y = "<<view_invert_y<<", Xmin() = "<<eventState->getXmin()<<", Xmax() = "<<eventState->getXmax()<<", Ymin() = "<<eventState->getYmin()<<", Ymax() = "<<eventState->getYmax()<<std::endl;
|
||||
|
||||
double epsilon = 0.5;
|
||||
|
||||
if (_camera->getGraphicsContext() &&
|
||||
(!gw || _camera->getGraphicsContext()==gw) &&
|
||||
_camera->getViewport())
|
||||
|
||||
|
||||
// if master camera has graphics context and eventState context matches then assume coordinates refer
|
||||
// to master camera
|
||||
bool masterActive = (_camera->getGraphicsContext()!=0 && _camera->getViewport());
|
||||
bool eventStateMatchesMaster = (gw!=0) ? _camera->getGraphicsContext()==gw : false;
|
||||
|
||||
if (masterActive && eventStateMatchesMaster)
|
||||
{
|
||||
// OSG_NOTICE<<"Event state matches master"<<std::endl;
|
||||
const osg::Viewport* viewport = _camera->getViewport();
|
||||
|
||||
double new_x = x;
|
||||
double new_y = y;
|
||||
|
||||
if (!gw)
|
||||
{
|
||||
new_x = static_cast<double>(_camera->getGraphicsContext()->getTraits()->width) * (x - eventState->getXmin())/(eventState->getXmax()-eventState->getXmin());
|
||||
new_y = view_invert_y ?
|
||||
static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (1.0 - (y- eventState->getYmin())/(eventState->getYmax()-eventState->getYmin())) :
|
||||
static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (y - eventState->getYmin())/(eventState->getYmax()-eventState->getYmin());
|
||||
}
|
||||
|
||||
if (viewport &&
|
||||
new_x >= (viewport->x()-epsilon) && new_y >= (viewport->y()-epsilon) &&
|
||||
|
||||
// rescale mouse x,y first to 0 to 1 range
|
||||
double new_x = (x-eventState->getXmin())/(eventState->getXmax()-eventState->getXmin());
|
||||
double new_y = (y-eventState->getYmin())/(eventState->getYmax()-eventState->getYmin());
|
||||
|
||||
// flip y if required
|
||||
if (view_invert_y) new_y = 1.0f-new_y;
|
||||
|
||||
// rescale mouse x, y to window dimensions so we can check against master Camera's viewport
|
||||
new_x *= static_cast<double>(_camera->getGraphicsContext()->getTraits()->width);
|
||||
new_y *= static_cast<double>(_camera->getGraphicsContext()->getTraits()->height);
|
||||
|
||||
if (new_x >= (viewport->x()-epsilon) && new_y >= (viewport->y()-epsilon) &&
|
||||
new_x < (viewport->x()+viewport->width()-1.0+epsilon) && new_y <= (viewport->y()+viewport->height()-1.0+epsilon) )
|
||||
{
|
||||
local_x = new_x;
|
||||
local_y = new_y;
|
||||
|
||||
OSG_INFO<<"Returning master camera"<<std::endl;
|
||||
//OSG_NOTICE<<"Returning master camera"<<std::endl;
|
||||
|
||||
return _camera.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
// OSG_NOTICE<<"master camera viewport not matched."<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix();
|
||||
|
||||
// convert to non dimensional
|
||||
@@ -2088,77 +2098,67 @@ const osg::Camera* View::getCameraContainingPosition(float x, float y, float& lo
|
||||
|
||||
bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections, osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
if (!_camera.valid()) return false;
|
||||
|
||||
float local_x, local_y = 0.0;
|
||||
float local_x, local_y;
|
||||
const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
|
||||
if (!camera) camera = _camera.get();
|
||||
|
||||
OSG_NOTICE<<"computeIntersections("<<x<<", "<<y<<") local_x="<<local_x<<", local_y="<<local_y<<std::endl;
|
||||
|
||||
if (camera) return computeIntersections(camera, (camera->getViewport()==0)?osgUtil::Intersector::PROJECTION : osgUtil::Intersector::WINDOW, local_x, local_y, intersections, traversalMask);
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool View::computeIntersections(float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections, osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
float local_x, local_y;
|
||||
const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
|
||||
|
||||
OSG_NOTICE<<"computeIntersections("<<x<<", "<<y<<") local_x="<<local_x<<", local_y="<<local_y<<std::endl;
|
||||
|
||||
osgUtil::LineSegmentIntersector::CoordinateFrame cf = camera->getViewport() ? osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION;
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(cf, local_x, local_y);
|
||||
if (camera) return computeIntersections(camera, (camera->getViewport()==0)?osgUtil::Intersector::PROJECTION : osgUtil::Intersector::WINDOW, local_x, local_y, nodePath, intersections, traversalMask);
|
||||
else return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
OSG_NOTICE<<"View::computeIntersections(x="<<x<<", y="<<y<<", local_x="<<local_x<<", local_y="<<local_y<<") "<<cf<<std::endl;
|
||||
OSG_NOTICE<<" viewport ("<<camera->getViewport()->x()<<","<<camera->getViewport()->y()<<","<<camera->getViewport()->width()<<","<<camera->getViewport()->height()<<")"<<std::endl;
|
||||
|
||||
const osg::GraphicsContext::Traits* traits = camera->getGraphicsContext() ? camera->getGraphicsContext()->getTraits() : 0;
|
||||
if (traits)
|
||||
bool View::computeIntersections(const osgGA::GUIEventAdapter& ea, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
#if 1
|
||||
if (ea.getNumPointerData()>=1)
|
||||
{
|
||||
OSG_NOTICE<<" window ("<<traits->x<<","<<traits->y<<","<<traits->width<<","<<traits->height<<")"<<std::endl;
|
||||
const osgGA::PointerData* pd = ea.getPointerData(ea.getNumPointerData()-1);
|
||||
const osg::Camera* camera = dynamic_cast<const osg::Camera*>(pd->object.get());
|
||||
if (camera)
|
||||
{
|
||||
return computeIntersections(camera, osgUtil::Intersector::PROJECTION, pd->getXnormalized(), pd->getYnormalized(), intersections, traversalMask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return computeIntersections(ea.getX(), ea.getY(), intersections, traversalMask);
|
||||
}
|
||||
|
||||
bool View::computeIntersections(const osgGA::GUIEventAdapter& ea, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
#if 1
|
||||
if (ea.getNumPointerData()>=1)
|
||||
{
|
||||
const osgGA::PointerData* pd = ea.getPointerData(ea.getNumPointerData()-1);
|
||||
const osg::Camera* camera = dynamic_cast<const osg::Camera*>(pd->object.get());
|
||||
if (camera)
|
||||
{
|
||||
return computeIntersections(camera, osgUtil::Intersector::PROJECTION, pd->getXnormalized(), pd->getYnormalized(), nodePath, intersections, traversalMask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return computeIntersections(ea.getX(), ea.getY(), nodePath, intersections, traversalMask);
|
||||
}
|
||||
|
||||
bool View::computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections, osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
if (!camera) return false;
|
||||
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(cf, x, y);
|
||||
osgUtil::IntersectionVisitor iv(picker.get());
|
||||
iv.setTraversalMask(traversalMask);
|
||||
|
||||
|
||||
#if 1
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
#else
|
||||
|
||||
// timing test code paths for comparing KdTree based intersections vs conventional intersections
|
||||
|
||||
iv.setUseKdTreeWhenAvailable(true);
|
||||
iv.setDoDummyTraversal(true);
|
||||
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
|
||||
|
||||
osg::Timer_t before = osg::Timer::instance()->tick();
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
|
||||
osg::Timer_t after_dummy = osg::Timer::instance()->tick();
|
||||
|
||||
int intersectsBeforeKdTree = picker->getIntersections().size();
|
||||
|
||||
iv.setDoDummyTraversal(false);
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
osg::Timer_t after_kdTree_2 = osg::Timer::instance()->tick();
|
||||
|
||||
int intersectsBeforeConventional = picker->getIntersections().size();
|
||||
|
||||
iv.setUseKdTreeWhenAvailable(false);
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
osg::Timer_t after = osg::Timer::instance()->tick();
|
||||
|
||||
int intersectsAfterConventional = picker->getIntersections().size();
|
||||
|
||||
double timeDummy = osg::Timer::instance()->delta_m(before, after_dummy);
|
||||
double timeKdTree = osg::Timer::instance()->delta_m(after_dummy, after_kdTree_2);
|
||||
double timeConventional = osg::Timer::instance()->delta_m(after_kdTree_2, after);
|
||||
|
||||
OSG_NOTICE<<"Using Dummy "<<timeDummy<<std::endl;
|
||||
OSG_NOTICE<<" KdTrees "<<timeKdTree
|
||||
<<"\tNum intersects = "<<intersectsBeforeConventional-intersectsBeforeKdTree<<std::endl;
|
||||
OSG_NOTICE<<" KdTrees - Traversal "<<timeKdTree-timeDummy<<std::endl;
|
||||
OSG_NOTICE<<" Conventional "<<timeConventional
|
||||
<<"\tNum intersects = "<<intersectsAfterConventional-intersectsBeforeConventional<<std::endl;
|
||||
OSG_NOTICE<<" Conventional - Traversal "<<timeConventional-timeDummy<<std::endl;
|
||||
OSG_NOTICE<<" Delta "<<timeConventional/timeKdTree<<std::endl;
|
||||
OSG_NOTICE<<" Delta sans Traversal "<<(timeConventional-timeDummy)/(timeKdTree-timeDummy)<<std::endl;
|
||||
OSG_NOTICE<<std::endl;
|
||||
#endif
|
||||
|
||||
if (picker->containsIntersections())
|
||||
{
|
||||
@@ -2172,13 +2172,9 @@ bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector
|
||||
}
|
||||
}
|
||||
|
||||
bool View::computeIntersections(float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask)
|
||||
bool View::computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
if (!_camera.valid() || nodePath.empty()) return false;
|
||||
|
||||
float local_x, local_y = 0.0;
|
||||
const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
|
||||
if (!camera) camera = _camera.get();
|
||||
if (!camera || nodePath.empty()) return false;
|
||||
|
||||
osg::Matrixd matrix;
|
||||
if (nodePath.size()>1)
|
||||
@@ -2192,7 +2188,7 @@ bool View::computeIntersections(float x,float y, const osg::NodePath& nodePath,
|
||||
|
||||
double zNear = -1.0;
|
||||
double zFar = 1.0;
|
||||
if (camera->getViewport())
|
||||
if (cf==osgUtil::Intersector::WINDOW && camera->getViewport())
|
||||
{
|
||||
matrix.postMult(camera->getViewport()->computeWindowMatrix());
|
||||
zNear = 0.0;
|
||||
@@ -2202,8 +2198,8 @@ bool View::computeIntersections(float x,float y, const osg::NodePath& nodePath,
|
||||
osg::Matrixd inverse;
|
||||
inverse.invert(matrix);
|
||||
|
||||
osg::Vec3d startVertex = osg::Vec3d(local_x,local_y,zNear) * inverse;
|
||||
osg::Vec3d endVertex = osg::Vec3d(local_x,local_y,zFar) * inverse;
|
||||
osg::Vec3d startVertex = osg::Vec3d(x,y,zNear) * inverse;
|
||||
osg::Vec3d endVertex = osg::Vec3d(x,y,zFar) * inverse;
|
||||
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, startVertex, endVertex);
|
||||
|
||||
@@ -2223,7 +2219,6 @@ bool View::computeIntersections(float x,float y, const osg::NodePath& nodePath,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void View::addDevice(osgGA::Device* eventSource)
|
||||
{
|
||||
Devices::iterator itr = std::find( _eventSources.begin(), _eventSources.end(), eventSource );
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <osg/DeleteHandler>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osg/TextureCubeMap>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
@@ -266,7 +268,6 @@ void Viewer::take(osg::View& rhs)
|
||||
_startRenderingBarrier = rhs_viewer->_startRenderingBarrier;
|
||||
_endRenderingDispatchBarrier = rhs_viewer->_endRenderingDispatchBarrier;
|
||||
_endDynamicDrawBlock = rhs_viewer->_endDynamicDrawBlock;
|
||||
_cameraWithFocus = rhs_viewer->_cameraWithFocus;
|
||||
_eventVisitor = rhs_viewer->_eventVisitor;
|
||||
_updateOperations = rhs_viewer->_updateOperations;
|
||||
_updateVisitor = rhs_viewer->_updateVisitor;
|
||||
@@ -279,7 +280,6 @@ void Viewer::take(osg::View& rhs)
|
||||
rhs_viewer->_startRenderingBarrier = 0;
|
||||
rhs_viewer->_endRenderingDispatchBarrier = 0;
|
||||
rhs_viewer->_endDynamicDrawBlock = 0;
|
||||
rhs_viewer->_cameraWithFocus = 0;
|
||||
rhs_viewer->_eventVisitor = 0;
|
||||
rhs_viewer->_updateOperations = 0;
|
||||
rhs_viewer->_updateVisitor = 0;
|
||||
@@ -429,8 +429,6 @@ void Viewer::realize()
|
||||
{
|
||||
//OSG_INFO<<"Viewer::realize()"<<std::endl;
|
||||
|
||||
setCameraWithFocus(0);
|
||||
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
@@ -561,7 +559,7 @@ void Viewer::realize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
|
||||
if (getCamera()->getViewport())
|
||||
{
|
||||
@@ -572,6 +570,7 @@ void Viewer::realize()
|
||||
{
|
||||
eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -616,6 +615,177 @@ void Viewer::advance(double simulationTime)
|
||||
|
||||
}
|
||||
|
||||
void Viewer::generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
// What type of Camera is it?
|
||||
// 1) Master Camera : do nothin extra
|
||||
// 2) Slave Camera, Relative RF, Same scene graph as master : transform coords into Master Camera and add to PointerData list
|
||||
// 3) Slave Camera, Relative RF, Different scene graph from master : do nothing extra?
|
||||
// 4) Slave Camera, Absolute RF, Same scene graph as master : do nothing extra?
|
||||
// 5) Slave Camera, Absolute RF, Different scene graph : do nothing extra?
|
||||
// 6) Slave Camera, Absolute RF, Different scene graph but a distortion correction subgraph depending upon RTT Camera (slave or master)
|
||||
// : project ray into RTT Camera's clip space, and RTT Camera's is Relative RF and sharing same scene graph as master then transform coords.
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
if (camera!=getCamera())
|
||||
{
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
bool invert_y = event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix();
|
||||
if (getCamera()->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = getCamera()->getViewport();
|
||||
masterCameraVPW *= viewport->computeWindowMatrix();
|
||||
}
|
||||
|
||||
// slave Camera tahnks to sharing the same View
|
||||
osg::View::Slave* slave = findSlaveForCamera(camera);
|
||||
if (slave)
|
||||
{
|
||||
if (camera->getReferenceFrame()==osg::Camera::RELATIVE_RF && slave->_useMastersSceneData)
|
||||
{
|
||||
osg::Viewport* viewport = camera->getViewport();
|
||||
osg::Matrix localCameraVPW = camera->getViewMatrix() * camera->getProjectionMatrix();
|
||||
if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
|
||||
|
||||
osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
|
||||
osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
|
||||
//OSG_NOTICE<<" pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
|
||||
event.addPointerData(new osgGA::PointerData(getCamera(), new_coord.x(), -1.0, 1.0,
|
||||
new_coord.y(), -1.0, 1.0));
|
||||
}
|
||||
else if (!slave->_useMastersSceneData)
|
||||
{
|
||||
// Are their any RTT Camera's that this Camera depends upon for textures?
|
||||
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> ray = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x,y);
|
||||
osgUtil::IntersectionVisitor iv(ray.get());
|
||||
camera->accept(iv);
|
||||
if (ray->containsIntersections())
|
||||
{
|
||||
osg::Vec3 tc;
|
||||
osg::Texture* texture = ray->getFirstIntersection().getTextureLookUp(tc);
|
||||
if (texture)
|
||||
{
|
||||
// look up Texture in RTT Camera's.
|
||||
for(unsigned int i=0; i<getNumSlaves();++i)
|
||||
{
|
||||
osg::Camera* slave_camera = getSlave(i)._camera;
|
||||
if (slave_camera)
|
||||
{
|
||||
osg::Camera::BufferAttachmentMap::const_iterator ba_itr = slave_camera->getBufferAttachmentMap().find(osg::Camera::COLOR_BUFFER);
|
||||
if (ba_itr != slave_camera->getBufferAttachmentMap().end())
|
||||
{
|
||||
if (ba_itr->second._texture == texture)
|
||||
{
|
||||
osg::TextureRectangle* tr = dynamic_cast<osg::TextureRectangle*>(ba_itr->second._texture.get());
|
||||
osg::TextureCubeMap* tcm = dynamic_cast<osg::TextureCubeMap*>(ba_itr->second._texture.get());
|
||||
if (tr)
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(slave_camera, tc.x(), 0.0f, static_cast<float>(tr->getTextureWidth()),
|
||||
tc.y(), 0.0f, static_cast<float>(tr->getTextureHeight())));
|
||||
}
|
||||
else if (tcm)
|
||||
{
|
||||
OSG_NOTICE<<" Slave has matched texture cubemap"<<ba_itr->second._texture.get()<<", "<<ba_itr->second._face<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(slave_camera, tc.x(), 0.0f, 1.0f,
|
||||
tc.y(), 0.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Viewer::generatePointerData(osgGA::GUIEventAdapter& event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
bool invert_y = event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
event.addPointerData(new osgGA::PointerData(gw, x, 0, gw->getTraits()->width,
|
||||
y, 0, gw->getTraits()->height));
|
||||
|
||||
// new code for populating the PointerData
|
||||
osgViewer::View* this_view = dynamic_cast<osgViewer::View*>(this);
|
||||
osg::GraphicsContext::Cameras& cameras = gw->getCameras();
|
||||
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
|
||||
citr != cameras.end();
|
||||
++citr)
|
||||
{
|
||||
osg::Camera* camera = *citr;
|
||||
if (camera->getView()==this_view &&
|
||||
camera->getAllowEventFocus() &&
|
||||
camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
|
||||
{
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
if (viewport &&
|
||||
x >= viewport->x() && y >= viewport->y() &&
|
||||
x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
|
||||
{
|
||||
event.addPointerData(new osgGA::PointerData(camera, (x-viewport->x())/viewport->width()*2.0f-1.0f, -1.0, 1.0,
|
||||
(y-viewport->y())/viewport->height()*2.0f-1.0f, -1.0, 1.0));
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
if (camera!=getCamera())
|
||||
{
|
||||
generateSlavePointerData(camera, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Viewer::reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event)
|
||||
{
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(dest_event.getGraphicsContext());
|
||||
if (!gw) return;
|
||||
|
||||
float x = dest_event.getX();
|
||||
float y = dest_event.getY();
|
||||
|
||||
bool invert_y = dest_event.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
|
||||
dest_event.addPointerData(new osgGA::PointerData(gw, x, 0, gw->getTraits()->width,
|
||||
y, 0, gw->getTraits()->height));
|
||||
|
||||
osg::Camera* camera = (source_event.getNumPointerData()>=2) ? dynamic_cast<osg::Camera*>(source_event.getPointerData(1)->object.get()) : 0;
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
|
||||
if (!viewport) return;
|
||||
|
||||
dest_event.addPointerData(new osgGA::PointerData(camera, (x-viewport->x())/viewport->width()*2.0f-1.0f, -1.0, 1.0,
|
||||
(y-viewport->y())/viewport->height()*2.0f-1.0f, -1.0, 1.0));
|
||||
|
||||
// if camera isn't the master it must be a slave and could need reprojecting.
|
||||
if (camera!=getCamera())
|
||||
{
|
||||
generateSlavePointerData(camera, dest_event);
|
||||
}
|
||||
}
|
||||
|
||||
void Viewer::eventTraversal()
|
||||
{
|
||||
if (_done) return;
|
||||
@@ -637,13 +807,6 @@ void Viewer::eventTraversal()
|
||||
if (_done) return;
|
||||
|
||||
osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
|
||||
osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix();
|
||||
if (getCamera()->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = getCamera()->getViewport();
|
||||
masterCameraVPW *= viewport->computeWindowMatrix();
|
||||
}
|
||||
|
||||
|
||||
// get events from user Devices attached to Viewer.
|
||||
for(Devices::iterator eitr = _eventSources.begin();
|
||||
@@ -679,111 +842,54 @@ void Viewer::eventTraversal()
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
bool pointerEvent = false;
|
||||
|
||||
float x = event->getX();
|
||||
float y = event->getY();
|
||||
|
||||
bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
|
||||
if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
|
||||
event->setGraphicsContext(gw);
|
||||
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
case(osgGA::GUIEventAdapter::DOUBLECLICK):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
{
|
||||
pointerEvent = true;
|
||||
|
||||
if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
|
||||
if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG ||
|
||||
eventState->getGraphicsContext()!=event->getGraphicsContext() ||
|
||||
eventState->getNumPointerData()<2)
|
||||
{
|
||||
osg::GraphicsContext::Cameras& cameras = gw->getCameras();
|
||||
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
|
||||
citr != cameras.end();
|
||||
++citr)
|
||||
{
|
||||
osg::Camera* camera = *citr;
|
||||
if (camera->getView()==this &&
|
||||
camera->getAllowEventFocus() &&
|
||||
camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
|
||||
{
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
|
||||
if (viewport &&
|
||||
x >= viewport->x() && y >= viewport->y() &&
|
||||
x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
|
||||
{
|
||||
// OSG_NOTICE<<"setCamera with focus "<<camera->getName()<<" x="<<x<<" y="<<y<<std::endl;
|
||||
setCameraWithFocus(camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
generatePointerData(*event);
|
||||
}
|
||||
else
|
||||
{
|
||||
reprojectPointerData(*eventState, *event);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// assign topmost PointeData settings as the events X,Y and InputRange
|
||||
osgGA::PointerData* pd = event->getPointerData(event->getNumPointerData()-1);
|
||||
event->setX(pd->x);
|
||||
event->setY(pd->y);
|
||||
event->setInputRange(pd->xMin, pd->yMin, pd->xMax, pd->yMax);
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
#else
|
||||
if (event->getMouseYOrientation()!=osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
|
||||
{
|
||||
event->setY((event->getYmax()-event->getY())+event->getYmin());
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
}
|
||||
#endif
|
||||
|
||||
eventState->copyPointerDataFrom(*event);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
event->copyPointerDataFrom(*eventState);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pointerEvent)
|
||||
{
|
||||
if (getCameraWithFocus())
|
||||
{
|
||||
if (getCameraWithFocus()!=getCamera())
|
||||
{
|
||||
osg::Viewport* viewport = getCameraWithFocus()->getViewport();
|
||||
osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
|
||||
if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
|
||||
|
||||
osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
|
||||
|
||||
osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
|
||||
|
||||
x = new_coord.x();
|
||||
y = new_coord.y();
|
||||
}
|
||||
|
||||
// OSG_NOTICE<<"pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
|
||||
|
||||
event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
|
||||
event->setX(x);
|
||||
event->setY(y);
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
x = eventState->getXmin() + (x/double(gw->getTraits()->width))*(eventState->getXmax() - eventState->getXmin());
|
||||
y = eventState->getYmin() + (y/double(gw->getTraits()->height))*(eventState->getYmax() - eventState->getYmin());
|
||||
// OSG_NOTICE<<"new x = "<<x<<" new y = "<<y<<std::endl;
|
||||
|
||||
event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
|
||||
event->setX(x);
|
||||
event->setY(y);
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
}
|
||||
|
||||
// pass along the new pointer events details to the eventState of the viewer
|
||||
eventState->setX(x);
|
||||
eventState->setY(y);
|
||||
eventState->setButtonMask(event->getButtonMask());
|
||||
eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
|
||||
event->setX(eventState->getX());
|
||||
event->setY(eventState->getY());
|
||||
event->setButtonMask(eventState->getButtonMask());
|
||||
event->setMouseYOrientation(eventState->getMouseYOrientation());
|
||||
}
|
||||
//OSG_NOTICE<<" mouse x = "<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
// OSG_NOTICE<<" mouse Xmin = "<<event->getXmin()<<" Ymin="<<event->getYmin()<<" xMax="<<event->getXmax()<<" Ymax="<<event->getYmax()<<std::endl;
|
||||
|
||||
events.push_back(event);
|
||||
}
|
||||
|
||||
|
||||
for(itr = gw_events.begin();
|
||||
itr != gw_events.end();
|
||||
++itr)
|
||||
@@ -808,22 +914,9 @@ void Viewer::eventTraversal()
|
||||
}
|
||||
}
|
||||
|
||||
events.insert(events.end(), gw_events.begin(), gw_events.end());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// pass on the coorindates of the main camera to make sure the frame event is scaled appropriately.
|
||||
if (getCamera()->getViewport())
|
||||
{
|
||||
osg::Viewport* viewport = getCamera()->getViewport();
|
||||
eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
|
||||
}
|
||||
else
|
||||
{
|
||||
eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// create a frame event for the new frame.
|
||||
_eventQueue->frame( getFrameStamp()->getReferenceTime() );
|
||||
|
||||
@@ -831,53 +924,6 @@ void Viewer::eventTraversal()
|
||||
|
||||
_eventQueue->takeEvents(events, cutOffTime);
|
||||
|
||||
|
||||
#if 0
|
||||
// OSG_NOTICE<<"Events "<<events.size()<<std::endl;
|
||||
for(osgGA::EventQueue::Events::iterator itr = events.begin();
|
||||
itr != events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
switch(event->getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
OSG_NOTICE<<" PUSH "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
OSG_NOTICE<<" RELEASE "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
OSG_NOTICE<<" DRAG "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
OSG_NOTICE<<" MOVE "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::SCROLL):
|
||||
OSG_NOTICE<<" SCROLL "<<event->getScrollingMotion()<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
OSG_NOTICE<<" KEYDOWN '"<<(char)event->getKey()<<"'"<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::KEYUP):
|
||||
OSG_NOTICE<<" KEYUP '"<<(char)event->getKey()<<"'"<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::RESIZE):
|
||||
OSG_NOTICE<<" RESIZE "<<event->getWindowX()<<"/"<<event->getWindowY()<<" x "<<event->getWindowWidth()<<"/"<<event->getWindowHeight() << std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
|
||||
OSG_NOTICE<<" QUIT_APPLICATION " << std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::FRAME):
|
||||
// OSG_NOTICE<<" FRAME "<<std::endl;
|
||||
break;
|
||||
default:
|
||||
// OSG_NOTICE<<" Event not handled"<<std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// OSG_NOTICE<<"Events "<<events.size()<<std::endl;
|
||||
|
||||
if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
|
||||
|
||||
@@ -716,90 +716,13 @@ InteractiveImageHandler::InteractiveImageHandler(osg::Image* image, osg::Texture
|
||||
}
|
||||
}
|
||||
|
||||
bool InteractiveImageHandler::computeIntersections(osgViewer::View* view, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask) const
|
||||
{
|
||||
float local_x, local_y = 0.0;
|
||||
const osg::Camera* camera;
|
||||
if (_fullscreen)
|
||||
{
|
||||
if (!_camera) return false;
|
||||
camera = _camera.get();
|
||||
local_x = x;
|
||||
local_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!view->getCamera() || nodePath.empty()) return false;
|
||||
camera = view->getCameraContainingPosition(x, y, local_x, local_y);
|
||||
if (!camera) camera = view->getCamera();
|
||||
}
|
||||
|
||||
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker;
|
||||
if (_fullscreen)
|
||||
{
|
||||
picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, local_x, local_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Matrixd matrix;
|
||||
if (nodePath.size()>1)
|
||||
{
|
||||
osg::NodePath prunedNodePath(nodePath.begin(),nodePath.end()-1);
|
||||
matrix = osg::computeLocalToWorld(prunedNodePath);
|
||||
}
|
||||
|
||||
matrix.postMult(camera->getViewMatrix());
|
||||
matrix.postMult(camera->getProjectionMatrix());
|
||||
|
||||
double zNear = -1.0;
|
||||
double zFar = 1.0;
|
||||
if (camera->getViewport())
|
||||
{
|
||||
matrix.postMult(camera->getViewport()->computeWindowMatrix());
|
||||
zNear = 0.0;
|
||||
zFar = 1.0;
|
||||
}
|
||||
|
||||
osg::Matrixd inverse;
|
||||
inverse.invert(matrix);
|
||||
|
||||
osg::Vec3d startVertex = osg::Vec3d(local_x,local_y,zNear) * inverse;
|
||||
osg::Vec3d endVertex = osg::Vec3d(local_x,local_y,zFar) * inverse;
|
||||
|
||||
picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, startVertex, endVertex);
|
||||
}
|
||||
|
||||
osgUtil::IntersectionVisitor iv(picker.get());
|
||||
iv.setTraversalMask(traversalMask);
|
||||
|
||||
if (_fullscreen)
|
||||
{
|
||||
const_cast<osg::Camera*>(camera)->accept(iv);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodePath.back()->accept(iv);
|
||||
}
|
||||
|
||||
if (picker->containsIntersections())
|
||||
{
|
||||
intersections = picker->getIntersections();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
intersections.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool InteractiveImageHandler::mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const
|
||||
{
|
||||
if (!view) return false;
|
||||
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
bool foundIntersection = view==0 ? false :
|
||||
(nv==0 ? view->computeIntersections(ea.getX(), ea.getY(), intersections) :
|
||||
//view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections));
|
||||
computeIntersections(view, ea.getX(), ea.getY(), nv->getNodePath(), intersections));
|
||||
bool foundIntersection = (nv==0) ? view->computeIntersections(ea, intersections) :
|
||||
view->computeIntersections(ea, nv->getNodePath(), intersections);
|
||||
|
||||
if (foundIntersection)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,14 @@ bool MouseHandler::handle(
|
||||
// If we're scrolling, we need to inform the WindowManager of that.
|
||||
_wm->setScrollingMotion(gea.getScrollingMotion());
|
||||
|
||||
return (this->*ma)(gea.getX(), gea.getY(), gea.getButton());
|
||||
// osgWidget assumes origin is bottom left of window so make sure mouse coordinate are increaseing y upwards and are scaled to window size.
|
||||
float x = (gea.getX()-gea.getXmin())/(gea.getXmax()-gea.getXmin())*static_cast<float>(gea.getWindowWidth());
|
||||
float y = (gea.getY()-gea.getYmin())/(gea.getYmax()-gea.getYmin())*static_cast<float>(gea.getWindowHeight());
|
||||
if (gea.getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS) y = static_cast<float>(gea.getWindowHeight())-y;
|
||||
|
||||
//OSG_NOTICE<<"MouseHandler(x="<<x<<", y="<<y<<")"<<std::endl;
|
||||
|
||||
return (this->*ma)(x, y, gea.getButton());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -511,7 +511,13 @@ Color Widget::getImageColorAtXY(point_type x, point_type y) const {
|
||||
point_type height = fabs((*texs)[LR].y() - (*texs)[UR].y());
|
||||
|
||||
point_type X = ((x / getWidth()) * width) + (*texs)[LL].x();
|
||||
point_type Y = (((getHeight() - y) / getHeight()) * height) + (*texs)[UR].y();
|
||||
point_type Y = ((y / getHeight()) * height) + (*texs)[LR].y();
|
||||
|
||||
if (X<0.0 || X>1.0 || Y<0.0 || Y>1.0)
|
||||
{
|
||||
OSG_INFO<<"Widget::getImageColorAtXY("<<x<<", "<<y<<") Texture coordinate out of range, X="<<X<<", Y="<<Y<<std::endl;
|
||||
return Color();
|
||||
}
|
||||
|
||||
return image->getColor(TexCoord(X, Y));
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ void WindowManager::_updatePickWindow(const WidgetList* wl, point_type x, point_
|
||||
_getPointerXYDiff(xdiff, ydiff);
|
||||
|
||||
ss
|
||||
<< "At XY Coords: " << x << ", " << _height - y
|
||||
<< "At XY Coords: " << x << ", " << y
|
||||
<< " ( diff " << xdiff << ", " << ydiff << " )"
|
||||
<< std::endl
|
||||
;
|
||||
@@ -296,10 +296,20 @@ void WindowManager::childRemoved(unsigned int start, unsigned int numChildren) {
|
||||
// This method performs intersection testing at the given XY coords, and returns true if
|
||||
// any intersections were found. It will break after processing the first pickable Window
|
||||
// it finds.
|
||||
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl)
|
||||
{
|
||||
Intersections intr;
|
||||
|
||||
if(_view->computeIntersections(x, y, intr, _nodeMask)) {
|
||||
|
||||
osg::Camera* camera = _view->getCamera();
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(camera->getGraphicsContext());
|
||||
if (gw)
|
||||
{
|
||||
_view->computeIntersections(camera, osgUtil::Intersector::WINDOW, x, y, intr, _nodeMask);
|
||||
}
|
||||
|
||||
if (!intr.empty())
|
||||
{
|
||||
// Get the first Window at the XY coordinates; if you want a Window to be
|
||||
// non-pickable, set the NodeMask to something else.
|
||||
Window* activeWin = 0;
|
||||
@@ -347,48 +357,6 @@ bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
Intersections intr;
|
||||
|
||||
if(!_view->computeIntersections(x, y, intr, _nodeMask)) return false;
|
||||
|
||||
typedef std::vector<osg::observer_ptr<Window> > WindowVector;
|
||||
|
||||
WindowVector windows;
|
||||
|
||||
Window* activeWin = 0;
|
||||
|
||||
for(Intersections::iterator i = intr.begin(); i != intr.end(); i++) {
|
||||
Window* win = dynamic_cast<Window*>(i->nodePath.back()->getParent(0));
|
||||
|
||||
if(
|
||||
!win ||
|
||||
(win->getVisibilityMode() == Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(activeWin != win) {
|
||||
activeWin = win;
|
||||
|
||||
windows.push_back(win);
|
||||
}
|
||||
}
|
||||
|
||||
if(!windows.size()) return false;
|
||||
|
||||
std::sort(windows.begin(), windows.end(), WindowBinNumberCompare());
|
||||
|
||||
for(WindowVector::iterator i = windows.begin(); i != windows.end(); i++) {
|
||||
warn() << "- " << i->get()->getName() << " " << i->get()->getOrCreateStateSet()->getBinNumber() << std::endl;
|
||||
}
|
||||
|
||||
warn() << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
bool WindowManager::setFocused(Window* window) {
|
||||
Event ev(this);
|
||||
|
||||
Reference in New Issue
Block a user