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位置
这里需要注意一下区别
通过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
- OSG+TUIO osgRecipes之osgtuio
- TUIO之TuioDemo
- osgRecipes编译中osg库的路径怎么设置
- Array osgRecipes
- osg之osg环境配置
- TUIO笔记
- OSG之osg::StateAttribute派生类速查
- 初步阅读tuio.as
- osg示例解析之osganimationskinning
- OSG例子讲解之osgautotransform
- OSG MINGW 编译之路
- osg示例解析之osgcamera
- osg之osgViewer基础应用
- osg之矩阵(一)
- osg之矩阵(二)
- OSG
- osg
- OSG
- angularjs路由改变的事件监听
- Ubuntu中Source Insight的使用
- BadgeView(数字提醒)
- 高精度除法(高除高)
- 第2.1.8章 WEB系统最佳实践Spring文件配置之spring-email.xml
- OSG+TUIO osgRecipes之osgtuio
- C/C++ Windows API——多线程加锁与临界区域
- 利用Python实现简单的日记本
- 如何屏蔽违禁词语
- react-native打印__nw_connection_get_connected_socket_block_invoke Connection has no connected handler
- Leetcode 300. Longest Increasing Subsequence
- Oracle创建测试REDO视图
- 如何有效防止SQL注入
- javaweb初学者常见问题解决