OSG+TUIO osgRecipes之osgtuio

来源:互联网 发布:linux服务器架构 编辑:程序博客网 时间:2024/06/05 22:49

致敬王锐大大!

osgRecipes中的osgtuio

找到这个的时候简直激动的不行,感谢Array大大的贡献,要是某一天自己也能成为能够给别人给予帮助的人,而不是成天伸手要源码的人就好了。

和TUIO API 上写的一样,有构造一个继承了TuioListener的类,并实现TuioListener里的这几个虚函数。这里应该也没有添加什么功能,现在还是不太理解这几个函数是要做什么的。


还有就是要自己设计一个TUIOClientHandler来处理Tuio事件。
TUIOClientHandler公有继承了GUIEventHandler类,然后重构handle方法。

之前一直在想应该把连接TuioClient和TuioServer的代码放在哪里,这里是放在这个TUIOClientHandler的构造函数中,针对每一个构造的TUIOClientHandler对象都需要connect一下。


重点关注一下这个handle函数,之后的工作应该在修改和拓展这个函数上展开,从而添加一些自己的交互事件。

在这里是对FRAME帧事件来handle的,也就是说每一帧都会监听TUIO事件,并针对TUIO事件作出相应的操作。


使用getTuioCursors()方法来获取当前的触摸点,并将其存在list中。


并使用迭代器对list中的对象,也就是TuioCursor对象进行访问,从而通过getX(),和getY()方法获得触摸点的位置。
这里需要注意一下区别
通过TUIO获取的触摸点的位置getX()和getY()的值是在0-1之间,这与在OSG中获取的鼠标位置不一样。如果需要这个触摸位置做相应的操作,需要进行转换。
point1.x = c.getX() * GetSystemMetrics(SM_CXSCREEN) - rect.left;//获取触摸点的x位置
point1.y = ea.getYmax()-(c.getY() *  GetSystemMetrics(SM_CYSCREEN) - rect.top);//获取触摸点的y位置


最后贴上王锐大大的源码,这里和我自己做的转换不一样,然后里面还用到了OSG中定义了的相关的Touch事件,这里我还没有弄明白。如何运行这个代码可以参考之前的博文如何调用TUIO中的代码那一篇点击打开链接
为什么我总觉得这个世界上只有我在学TUIO呢。。。好难过。

#include <osg/Texture2D>#include <osg/Geometry>#include <osg/MatrixTransform>#include <osgDB/ReadFile>#include <osgGA/StateSetManipulator>#include <osgGA/MultiTouchTrackballManipulator>#include <osgViewer/ViewerEventHandlers>#include <osgViewer/Viewer>#include "TUIO/TuioClient.h"#include "TUIO/TuioListener.h"class ClientListener : public TUIO::TuioListener{public:    ClientListener() : active(false) {}    bool active;        virtual void addTuioObject( TUIO::TuioObject* tobj ) { active = true; }    virtual void updateTuioObject( TUIO::TuioObject* tobj ) { active = true; }    virtual void removeTuioObject( TUIO::TuioObject* tobj ) { active = true; }    virtual void addTuioCursor( TUIO::TuioCursor* tcur ) { active = true; }    virtual void updateTuioCursor( TUIO::TuioCursor* tcur ) { active = true; }    virtual void removeTuioCursor( TUIO::TuioCursor* tcur ) { active = true; }    virtual void addTuioBlob( TUIO::TuioBlob* tblb ) { active = true; }    virtual void updateTuioBlob( TUIO::TuioBlob* tblb ) { active = true; }    virtual void removeTuioBlob( TUIO::TuioBlob* tblb ) { active = true; }    virtual void refresh( TUIO::TuioTime ftime ) {}};class TUIOClientHandler : public osgGA::GUIEventHandler{public:    TUIOClientHandler( int port=3333 )    {        _listener = new ClientListener;        _client = new TUIO::TuioClient( port );        _client->addTuioListener( _listener );        _client->connect();    }        virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )    {        osgViewer::View* view = dynamic_cast<osgViewer::View*>( &aa );//定义了一个指向View类型对象的指针,并指向aa        if ( !view ) return false;                osgGA::EventQueue* queue = view->getEventQueue();        switch ( ea.getEventType() )        {        case osgGA::GUIEventAdapter::FRAME:            if ( _listener->active )            {                _listener->active = false;  // FIXME: is that safe enough for multithreading?                std::map<unsigned int, osg::Vec2d> lastIDs = _clientIDs;                std::list<TUIO::TuioCursor*> cursors = _client->getTuioCursors();                                osg::ref_ptr<osgGA::GUIEventAdapter> touched;                for ( std::list<TUIO::TuioCursor*>::iterator itr=cursors.begin();                      itr!=cursors.end(); ++itr )                {                    TUIO::TuioCursor* c = *itr;                    if ( !c ) continue;                                        unsigned int id = c->getCursorID();                    double x = 0.1 * c->getX() * ea.getWindowWidth() + ea.getWindowX();                    double y = 0.1 * c->getY() * ea.getWindowHeight() + ea.getWindowY();                    if ( _clientIDs.find(id)!=_clientIDs.end() )                    {                        if ( !touched ) touched = queue->touchMoved(id, osgGA::GUIEventAdapter::TOUCH_MOVED, x, y);                        else touched->addTouchPoint(id, osgGA::GUIEventAdapter::TOUCH_MOVED, x, y);                        lastIDs.erase( id );                    }                    else                    {                        if ( !touched ) touched = queue->touchBegan(id, osgGA::GUIEventAdapter::TOUCH_BEGAN, x, y);                        else touched->addTouchPoint(id, osgGA::GUIEventAdapter::TOUCH_BEGAN, x, y);                    }                    _clientIDs[id] = osg::Vec2d(x, y);                }                                for ( std::map<unsigned int, osg::Vec2d>::iterator itr=lastIDs.begin();                      itr!=lastIDs.end(); ++itr )                {                    // Unset IDs are going to be removed this time                    double x = itr->second.x(), y = itr->second.y();                    if ( !touched ) touched = queue->touchEnded(itr->first, osgGA::GUIEventAdapter::TOUCH_ENDED, x, y, 1);                    else touched->addTouchPoint(itr->first, osgGA::GUIEventAdapter::TOUCH_ENDED, x, y, 1);                    _clientIDs.erase( itr->first );                }            }            break;        default: break;        }        return false;    }    protected:    virtual ~TUIOClientHandler()    {        if ( _client )        {            _client->removeTuioListener( _listener );            _client->disconnect();            delete _client;        }        if ( _listener ) delete _listener;    }        std::map<unsigned int, osg::Vec2d> _clientIDs;    TUIO::TuioClient* _client;    ClientListener* _listener;};int main( int argc, char** argv ){    osg::ref_ptr<osg::MatrixTransform> scene = new osg::MatrixTransform;    scene->addChild( osgDB::readNodeFile("cow.osg") );        osgViewer::Viewer viewer;    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );    viewer.addEventHandler( new osgViewer::StatsHandler );    viewer.addEventHandler( new osgViewer::WindowSizeHandler );    viewer.addEventHandler( new TUIOClientHandler(3333) );    viewer.setCameraManipulator( new osgGA::MultiTouchTrackballManipulator );    viewer.setSceneData( scene.get() );    return viewer.run();}




0 0
原创粉丝点击