Hi, I'm trying to display a context menu on mouse's right button click. At the
same time, I have a TrackballManipulator attached to my main camera. When I
click the right button, the mouse keep triggering DRAG events, even when no
button is pressed, thus scaling the scene to perform zooming. I need a hint on
what I should change to fix this.
I have also tried to subclass TrackballManipulator to include a boolean flag to
enable it or disabled at will, but didn't work.
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=52938#52938
#include "mousehandler.h"
#include <osgUtil/LineSegmentIntersector>
#include <osgViewer/Viewer>
#include <osg/Notify>
#include <map>
#include <bitset>
#include <QtGui/QColor>
#include <QtDebug>
#include "conversionhelper.h"
bool MouseHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
osgGA::GUIEventAdapter::EventType eventType = ea.getEventType();
int button = ea.getButton();
if( eventType == osgGA::GUIEventAdapter::DRAG )
{
qDebug() << "Se ha arrastrado el raton";
switch( button ) {
case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON: qDebug() << "Con el boton derecho"; break;
case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON: qDebug() << "Con el boton izquierdo"; break;
case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON: qDebug() << "Con el boton central"; break;
}
}
// Solo tomar en cuenta clicks derechos del raton
if(
eventType != osgGA::GUIEventAdapter::PUSH ||
button != osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON
){
return false;
}
qDebug() << "El usuario ha generado un evento de raton";
osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
if ( viewer )
{
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector =
new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
osgUtil::IntersectionVisitor iv( intersector.get() );
viewer->getCamera()->accept( iv );
osg::Drawable *drawable = NULL;
osg::ref_ptr< osg::Geometry > geometry = NULL;
osgUtil::LineSegmentIntersector::Intersection i;
if( intersector->containsIntersections() )
{
qDebug() << "El usuario ha seleccionado objetos en la escena";
//this->clearSelectedGeometries();
this->lastIntersections = intersector->getIntersections();
i = *(this->lastIntersections.begin());
drawable = i.drawable;
geometry = drawable->asGeometry();
//osgUtil::LineSegmentIntersector::Intersections::iterator k;
//for(k=intersector->getIntersections().begin(); k!=intersector->getIntersections().end(); k++)
//{
//qDebug() << "Intentando seleccionar geometria";
//this->selectGeometry(k->drawable->asGeometry());
this->selectGeometry(geometry);
//emit( objectSelected(k->drawable->asGeometry()) );
emit( objectSelected(geometry) );
//}
emit( contextMenuDisplayed(ea.getX(), ea.getY(), drawable) );
return true;
} else {
qDebug() << "El usuario no ha seleccionado objetos validos en la escena.";
}
}
return false;
}
void MouseHandler::selectGeometry( osg::ref_ptr< osg::Geometry > geom )
{
//osg::Vec4 originalColor;
if( !geom ){
qDebug() << "No sean seleccionado geometrias validas";
return;
} else {
qDebug() << "Se han seleccionado geometrias validas";
}
osg::Vec4Array *colors = dynamic_cast< osg::Vec4Array* >( geom->getColorArray() );
if( colors && !colors->empty() )
{
osg::Vec4 currentColor = colors->front();
// XOR de colores con verde semi transparente
osg::Vec4 hColor; hColor.r() = 0.0f, hColor.g() = 1.0f, hColor.b() = 0.0f, hColor.a() = 1.0f;
osg::Vec4 newColor = this->xorColor(currentColor, hColor);
newColor.a() = currentColor.a();
qDebug() << "Color actual es " << hex2str( currentColor.asRGBA() ).c_str();
qDebug() << "Nuevo color es " << hex2str( newColor.asRGBA() ).c_str();
colors->front() = newColor;
colors->dirty();
} else {
qDebug() << "No se encontraron colores en la geometria";
}
}
void MouseHandler::clearSelectedGeometries()
{
osgUtil::LineSegmentIntersector::Intersections::iterator it;
osgUtil::LineSegmentIntersector::Intersection intersection;
osg::ref_ptr< osg::Geometry > g;
for( it = this->lastIntersections.begin(); it != this->lastIntersections.end(); it++ )
{
intersection = *it;
g = intersection.drawable->asGeometry();
this->selectGeometry(g);
}
this->lastIntersections.empty();
}
void MouseHandler::setDrawableColor(osg::Geometry *geom, const osg::Vec4 &color)
{
osg::Vec4Array* colors = dynamic_cast<osg::Vec4Array*>( geom->getColorArray() );
if ( colors && colors->size()>0 )
{
colors->front() = color;
colors->dirty();
}
}
osg::Vec4 MouseHandler::xorColor(const osg::Vec4 &a, const osg::Vec4 &b)
{
qDebug() << "XORing colors " << hex2str(a.asRGBA()).c_str() << " and " << hex2str(b.asRGBA()).c_str();
unsigned int result = a.asABGR() ^ b.asABGR();
osg::Vec4 rv;
rv.r() = ((result >> 24) / 255.0f);
rv.g() = ((result >> 16) & 0xff) / 255.0f;
rv.b() = ((result >> 8) & 0xff) / 255.0f;
rv.a() = result & 0xff;
//rv.set(alpha, blue, green, red);
qDebug() << "Result is " << hex2str(result).c_str() << endl;
qDebug() << "Converted Result is " << hex2str( rv.asABGR() ).c_str() << endl;
return rv;
}
std::string MouseHandler::hex2str(const unsigned int hex)
{
std::bitset<32> bs = hex;
return bs.to_string();
}
#ifndef MOUSEHANDLER_H
#define MOUSEHANDLER_H
#include <osg/Geometry>
#include <osgGA/GUIEventHandler>
#include <osgUtil/LineSegmentIntersector>
#include <QObject>
class MouseHandler : public QObject, public osgGA::GUIEventHandler
{
Q_OBJECT
signals:
void contextMenuDisplayed( int x, int y, osg::ref_ptr< osg::Drawable > drawable = NULL );
void objectSelected( osg::ref_ptr< osg::Geometry > object );
public:
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa );
protected:
bool _handleRightClick(int x, int y);
void selectGeometry( osg::ref_ptr< osg::Geometry > geom );
void clearSelectedGeometries();
private:
osgUtil::LineSegmentIntersector::Intersections lastIntersections;
void setDrawableColor( osg::Geometry* geom, const osg::Vec4& color );
osg::Vec4 xorColor( const osg::Vec4&, const osg::Vec4& = osg::Vec4(0.0f, 1.0f, 0.0f, 0.5f) );
std::string hex2str( const unsigned int hex );
};
#endif // MOUSEHANDLER_H
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org