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

Reply via email to