From Stephan Huber, "attached are some fixes to the osc-plugin and the touch-implementations for iOS and os x and other small bugfixes. These fixes will normalize the orientation of the touch points, and transmitting the touch points over osc via the TUIO-protocol works now more robustly between two osg-applications.
I added a new tag to p3d called forward_touch_event_to_device and renamed the existing forward_event_to_device to forward_mouse_event_to_device. This new tag will transmit touches to the virtual trackpad as touch events. I added the MultitouchTrackball to the p3d-app so zooming and moving a model remotely should now work, if you use forward_touch_event_to_device. I kept (and fixed) forward_mouse_event_to_device for background compatibility, so old presentations works as in previous versions, without the ability to zoom + scale. of course. forward_touch_event_to_device needs some more testing, (e.g. with image-streams and keystone, afaik there’s no support for touch-events...) but for a first version it works nice. "
This commit is contained in:
parent
09c09628ac
commit
a96ad565c7
@ -36,6 +36,7 @@
|
||||
#include <osgGA/TerrainManipulator>
|
||||
#include <osgGA/AnimationPathManipulator>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
#include <osgGA/MultiTouchTrackballManipulator>
|
||||
|
||||
#include <osgPresentation/deprecated/SlideEventHandler>
|
||||
#include <osgPresentation/Cursor>
|
||||
@ -50,6 +51,7 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SDL
|
||||
@ -174,6 +176,58 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class DumpEventHandler : public osgGA::GUIEventHandler {
|
||||
public:
|
||||
DumpEventHandler() : osgGA::GUIEventHandler() {}
|
||||
|
||||
virtual bool handle (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *, osg::NodeVisitor *)
|
||||
{
|
||||
switch (ea.getEventType())
|
||||
{
|
||||
case osgGA::GUIEventAdapter::FRAME:
|
||||
return false;
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::PUSH:
|
||||
std::cout << "PUSH: ";
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::RELEASE:
|
||||
std::cout << "RELEASE: ";
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::MOVE:
|
||||
std::cout << "MOVE: ";
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::DRAG:
|
||||
std::cout << "DRAG: ";
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::SCROLL:
|
||||
std::cout << "SCROLL: ";
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << ea.getEventType() << " ";
|
||||
break;
|
||||
}
|
||||
std::cout << ea.getX() << "/" << ea.getY() << " " << ea.isMultiTouchEvent() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool handle(osgGA::Event* event, osg::Object* object, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (event->asGUIEventAdapter())
|
||||
return osgGA::GUIEventHandler::handle(event, object, nv);
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum P3DApplicationType
|
||||
{
|
||||
@ -423,7 +477,7 @@ int main( int argc, char **argv )
|
||||
{
|
||||
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
|
||||
|
||||
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::MultiTouchTrackballManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
|
||||
keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
|
||||
@ -444,6 +498,8 @@ int main( int argc, char **argv )
|
||||
|
||||
viewer.setCameraManipulator( keyswitchManipulator.get() );
|
||||
}
|
||||
|
||||
//viewer.getEventHandlers().push_front(new DumpEventHandler());
|
||||
|
||||
// add the state manipulator
|
||||
osg::ref_ptr<osgGA::StateSetManipulator> ssManipulator = new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet());
|
||||
|
@ -13,6 +13,22 @@
|
||||
#include <osgViewer/api/IOS/GraphicsWindowIOS>
|
||||
|
||||
|
||||
@interface MyViewController : UIViewController
|
||||
|
||||
- (BOOL)shouldAutorotate;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation MyViewController
|
||||
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation iphoneViewerAppDelegate
|
||||
|
||||
@synthesize _window;
|
||||
@ -148,7 +164,11 @@ private:
|
||||
for(osgGA::GUIEventAdapter::TouchData::iterator i = ea.getTouchData()->begin(); i != ea.getTouchData()->end(); ++i, ++j)
|
||||
{
|
||||
const osgGA::GUIEventAdapter::TouchData::TouchPoint& tp = (*i);
|
||||
_mats[j]->setMatrix(osg::Matrix::translate(tp.x, ea.getWindowHeight() - tp.y, 0));
|
||||
if (ea.getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS)
|
||||
_mats[j]->setMatrix(osg::Matrix::translate(tp.x, ea.getWindowHeight() - tp.y, 0));
|
||||
else
|
||||
_mats[j]->setMatrix(osg::Matrix::translate(tp.x, tp.y, 0));
|
||||
|
||||
_mats[j]->setNodeMask(0xffff);
|
||||
|
||||
std::ostringstream ss;
|
||||
@ -227,55 +247,62 @@ private:
|
||||
|
||||
//get the screen size
|
||||
CGRect lFrame = [[UIScreen mainScreen] bounds];
|
||||
unsigned int w = lFrame.size.width;
|
||||
unsigned int h = lFrame.size.height;
|
||||
unsigned int w = lFrame.size.width * [[UIScreen mainScreen] scale];
|
||||
unsigned int h = lFrame.size.height * [[UIScreen mainScreen] scale];
|
||||
|
||||
//create the viewer
|
||||
_viewer = new osgViewer::Viewer();
|
||||
|
||||
|
||||
/*
|
||||
if(1) {
|
||||
|
||||
// If you want full control over the graphics context / window creation, please uncomment this section
|
||||
|
||||
// create the main window at screen size
|
||||
self._window = [[UIWindow alloc] initWithFrame: lFrame];
|
||||
|
||||
//show window
|
||||
[_window makeKeyAndVisible];
|
||||
// If you want full control over the graphics context / window creation, please uncomment this section
|
||||
|
||||
// create the main window at screen size
|
||||
self._window = [[UIWindow alloc] initWithFrame: lFrame];
|
||||
|
||||
//show window
|
||||
[_window makeKeyAndVisible];
|
||||
|
||||
UIView* parent_view = [[UIView alloc] initWithFrame: CGRectMake(0,0, w, h)];
|
||||
parent_view.backgroundColor = [UIColor redColor];
|
||||
[self._window addSubview: parent_view];
|
||||
MyViewController* view_controller = [[MyViewController alloc] init];
|
||||
view_controller.view = parent_view;
|
||||
self._window.rootViewController = view_controller;
|
||||
|
||||
|
||||
//create our graphics context directly so we can pass our own window
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
|
||||
// Init the Windata Variable that holds the handle for the Window to display OSG in.
|
||||
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowIOS::WindowData(parent_view);
|
||||
|
||||
// Setup the traits parameters
|
||||
traits->x = 50;
|
||||
traits->y = 50;
|
||||
traits->width = w-100;
|
||||
traits->height = h-100;
|
||||
traits->depth = 16; //keep memory down, default is currently 24
|
||||
traits->windowDecoration = false;
|
||||
traits->doubleBuffer = true;
|
||||
traits->sharedContext = 0;
|
||||
traits->setInheritedWindowPixelFormat = true;
|
||||
traits->samples = 4;
|
||||
traits->sampleBuffers = 1;
|
||||
|
||||
traits->inheritedWindowData = windata;
|
||||
|
||||
|
||||
//create our graphics context directly so we can pass our own window
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
|
||||
// Init the Windata Variable that holds the handle for the Window to display OSG in.
|
||||
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowIOS::WindowData(_window);
|
||||
|
||||
// Setup the traits parameters
|
||||
traits->x = 0;
|
||||
traits->y = 0;
|
||||
traits->width = w;
|
||||
traits->height = h;
|
||||
traits->depth = 16; //keep memory down, default is currently 24
|
||||
traits->windowDecoration = false;
|
||||
traits->doubleBuffer = true;
|
||||
traits->sharedContext = 0;
|
||||
traits->setInheritedWindowPixelFormat = true;
|
||||
traits->samples = 4;
|
||||
traits->sampleBuffers = 1;
|
||||
|
||||
traits->inheritedWindowData = windata;
|
||||
|
||||
// Create the Graphics Context
|
||||
osg::ref_ptr<osg::GraphicsContext> graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
|
||||
// if the context was created then attach to our viewer
|
||||
if(graphicsContext)
|
||||
{
|
||||
_viewer->getCamera()->setGraphicsContext(graphicsContext);
|
||||
_viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
|
||||
// Create the Graphics Context
|
||||
osg::ref_ptr<osg::GraphicsContext> graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
|
||||
// if the context was created then attach to our viewer
|
||||
if(graphicsContext)
|
||||
{
|
||||
_viewer->getCamera()->setGraphicsContext(graphicsContext);
|
||||
_viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//create root
|
||||
|
@ -675,13 +675,14 @@ public:
|
||||
|
||||
void addTouchPoint(unsigned int id, TouchPhase phase, float x, float y, unsigned int tapCount = 0);
|
||||
|
||||
void setTouchData(TouchData* td) { _touchData = td; }
|
||||
TouchData* getTouchData() const { return _touchData.get(); }
|
||||
bool isMultiTouchEvent() const { return (_touchData.valid()); }
|
||||
|
||||
|
||||
inline float getTouchPointNormalizedX(unsigned int ndx) const {
|
||||
return (getTouchData()->get(ndx).x-_Xmin)/(_Xmax-_Xmin)*2.0f-1.0f;
|
||||
}
|
||||
|
||||
|
||||
inline float getTouchPointNormalizedY(unsigned int ndx) const {
|
||||
if (_mouseYOrientation==Y_INCREASING_UPWARDS)
|
||||
return (getTouchData()->get(ndx).y-_Ymin)/(_Ymax-_Ymin)*2.0f-1.0f;
|
||||
|
@ -37,7 +37,8 @@ enum Operation
|
||||
LOAD,
|
||||
EVENT,
|
||||
JUMP,
|
||||
FORWARD_EVENT
|
||||
FORWARD_MOUSE_EVENT,
|
||||
FORWARD_TOUCH_EVENT
|
||||
};
|
||||
|
||||
struct JumpData
|
||||
|
@ -67,8 +67,11 @@ GUIEventAdapter::GUIEventAdapter(const GUIEventAdapter& rhs,const osg::CopyOp& c
|
||||
_mouseYOrientation(rhs._mouseYOrientation),
|
||||
_scrolling(rhs._scrolling),
|
||||
_tabletPen(rhs._tabletPen),
|
||||
_touchData(rhs._touchData)
|
||||
{}
|
||||
_touchData(NULL)
|
||||
{
|
||||
if(TouchData* td = rhs.getTouchData())
|
||||
setTouchData(osg::clone(td, copyop));
|
||||
}
|
||||
|
||||
GUIEventAdapter::~GUIEventAdapter()
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ void MultiTouchTrackballManipulator::handleMultiTouchDrag(const GUIEventAdapter*
|
||||
osg::Vec2 delta = ((pt_1_last - pt_1_now) + (pt_2_last - pt_2_now)) / 2.0f;
|
||||
|
||||
float scale = _distance / 3.0f;
|
||||
|
||||
|
||||
// osg::notify(osg::ALWAYS) << "drag: " << delta << " scale: " << scale << std::endl;
|
||||
|
||||
panModel( delta.x() * scale, delta.y() * scale);
|
||||
|
@ -715,13 +715,13 @@ class TUIO2DCursorRequestHandler : public OscReceivingDevice::RequestHandler {
|
||||
public:
|
||||
|
||||
struct Cursor {
|
||||
std::string source;
|
||||
std::string end_point;
|
||||
unsigned int id, frameId;
|
||||
osg::Vec2f pos, vel;
|
||||
float accel;
|
||||
osgGA::GUIEventAdapter::TouchPhase phase;
|
||||
|
||||
Cursor() : source(), id(0), frameId(0), pos(), vel(), accel(), phase(osgGA::GUIEventAdapter::TOUCH_UNKNOWN) {}
|
||||
Cursor() : end_point(), id(0), frameId(0), pos(), vel(), accel(), phase(osgGA::GUIEventAdapter::TOUCH_UNKNOWN) {}
|
||||
|
||||
};
|
||||
struct EndpointData {
|
||||
@ -764,9 +764,12 @@ public:
|
||||
|
||||
if (what == "source")
|
||||
{
|
||||
args >> str;
|
||||
_endpointData[end_point].source = std::string(str);
|
||||
updateSourceIdMap(_endpointData[end_point].source);
|
||||
args >> str;
|
||||
_endpointData[end_point].source = std::string(str);
|
||||
updateSourceIdMap(_endpointData[end_point].source);
|
||||
|
||||
_endpointData[end_point].unhandled.clear();
|
||||
_endpointData[end_point].mayClearUnhandledPointer = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -786,10 +789,8 @@ public:
|
||||
{
|
||||
osc::int32 id;
|
||||
args >> id;
|
||||
_endpointData[source].unhandled.insert(id);
|
||||
_endpointData[end_point].unhandled.insert(id);
|
||||
}
|
||||
_endpointData[source].mayClearUnhandledPointer = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (what == "set")
|
||||
@ -803,9 +804,9 @@ public:
|
||||
|
||||
Cursor& c(_alive[source][id]);
|
||||
args >> c.pos.x() >> c.pos.y() >> c.vel.x() >> c.vel.y() >> c.accel >> osc::EndMessage;
|
||||
c.source = source;
|
||||
c.frameId = frame_id;
|
||||
_endpointData[source].unhandled.insert(id);
|
||||
c.end_point = end_point;
|
||||
_endpointData[end_point].unhandled.insert(id);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -840,51 +841,50 @@ public:
|
||||
|
||||
// remove all touchpoints which are not transmitted via alive-message, dispatching TOUCH_ENDED
|
||||
|
||||
EndpointData& endpoint_data(_endpointData[source]);
|
||||
if (endpoint_data.mayClearUnhandledPointer)
|
||||
unsigned int source_id = getSourceId(source);
|
||||
|
||||
std::vector<unsigned int> to_delete;
|
||||
|
||||
for(CursorMap::iterator k = i->second.begin(); k != i->second.end(); ++k)
|
||||
{
|
||||
unsigned int source_id = getSourceId(source);
|
||||
|
||||
std::vector<unsigned int> to_delete;
|
||||
|
||||
for(CursorMap::iterator k = i->second.begin(); k != i->second.end(); ++k)
|
||||
EndpointData& endpoint_data(_endpointData[k->second.end_point]);
|
||||
/*if (!endpoint_data.mayClearUnhandledPointer)
|
||||
{
|
||||
//create a unique touchpoint-id
|
||||
unsigned int touch_id = (source_id << 16) + k->first;
|
||||
|
||||
std::set<unsigned int>& unhandled(endpoint_data.unhandled);
|
||||
if ((unhandled.find(k->first) == unhandled.end()))
|
||||
{
|
||||
std::cout << "deleting: " << k->first << std::endl;
|
||||
to_delete.push_back(k->first);
|
||||
|
||||
float win_x = k->second.pos.x();
|
||||
float win_y = k->second.pos.y();
|
||||
|
||||
if (!event)
|
||||
event = queue->touchEnded(touch_id, osgGA::GUIEventAdapter::TOUCH_ENDED, win_x, win_y, 1);
|
||||
else
|
||||
event->addTouchPoint(touch_id, osgGA::GUIEventAdapter::TOUCH_ENDED, win_x, win_y, 1);
|
||||
}
|
||||
}
|
||||
// remove "dead" cursors
|
||||
for(std::vector<unsigned int>::iterator k = to_delete.begin(); k != to_delete.end(); ++k)
|
||||
{
|
||||
_alive[source].erase(i->second.find(*k));
|
||||
}
|
||||
continue;
|
||||
}*/
|
||||
|
||||
//create a unique touchpoint-id
|
||||
unsigned int touch_id = (source_id << 16) + k->first;
|
||||
|
||||
endpoint_data.mayClearUnhandledPointer = false;
|
||||
endpoint_data.unhandled.clear();
|
||||
std::set<unsigned int>& unhandled(endpoint_data.unhandled);
|
||||
if ((unhandled.find(k->first) == unhandled.end()))
|
||||
{
|
||||
// std::cout << "deleting: " << k->first << " from " << k->second.end_point << std::endl;
|
||||
to_delete.push_back(k->first);
|
||||
|
||||
float win_x = k->second.pos.x();
|
||||
float win_y = k->second.pos.y();
|
||||
|
||||
if (!event)
|
||||
event = queue->touchEnded(touch_id, osgGA::GUIEventAdapter::TOUCH_ENDED, win_x, win_y, 1);
|
||||
else
|
||||
event->addTouchPoint(touch_id, osgGA::GUIEventAdapter::TOUCH_ENDED, win_x, win_y, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// remove "dead" cursors
|
||||
for(std::vector<unsigned int>::iterator k = to_delete.begin(); k != to_delete.end(); ++k)
|
||||
{
|
||||
_alive[source].erase(i->second.find(*k));
|
||||
}
|
||||
|
||||
if (i->second.size() == 0)
|
||||
{
|
||||
// std::cout << "removing endpoint" << source << std::endl;
|
||||
_endpointData.erase(_endpointData.find(source));
|
||||
_alive.erase(_alive.find(source));
|
||||
// _alive.erase(_alive.find(source));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// send all alive touchpoints
|
||||
for(ApplicationCursorMap::iterator i = _alive.begin(); i != _alive.end(); ++i)
|
||||
{
|
||||
@ -912,6 +912,7 @@ public:
|
||||
{
|
||||
event->addTouchPoint(touch_id, down ? osgGA::GUIEventAdapter::TOUCH_BEGAN : osgGA::GUIEventAdapter::TOUCH_MOVED, win_x, win_y);
|
||||
}
|
||||
|
||||
c.phase = osgGA::GUIEventAdapter::TOUCH_MOVED;
|
||||
}
|
||||
}
|
||||
@ -921,6 +922,7 @@ public:
|
||||
{
|
||||
event->setInputRange(0, 0, 1.0, 1.0);
|
||||
event->setTime(queue->getTime());
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,6 +999,9 @@ OscReceivingDevice::OscReceivingDevice(const std::string& server_address, int li
|
||||
addRequestHandler(new OscDevice::StandardRequestHandler("/osg/set_user_value", true));
|
||||
|
||||
addRequestHandler(new OscDevice::StandardRequestHandler("", false));
|
||||
|
||||
// getEventQueue()->setFirstTouchEmulatesMouse(false);
|
||||
|
||||
setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_LOW);
|
||||
start();
|
||||
}
|
||||
|
@ -31,12 +31,10 @@ OscSendingDevice::OscSendingDevice(const std::string& address, int port, unsigne
|
||||
, _delayBetweenSendsInMilliSecs( (_numMessagesPerEvent > 1) ? delay_between_sends_in_millisecs : 0)
|
||||
, _msgId(0)
|
||||
, _lastEvent(NULL)
|
||||
, _finishMultiTouchSequence(false)
|
||||
{
|
||||
setCapabilities(SEND_EVENTS);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
OSG_NOTICE << "OscDevice :: sending events to " << address << ":" << port << " ";
|
||||
#ifdef OSC_HOST_LITTLE_ENDIAN
|
||||
OSG_NOTICE << "(little endian)";
|
||||
@ -164,23 +162,24 @@ bool OscSendingDevice::sendUIEventImpl(const osgGA::GUIEventAdapter &ea, MsgIdTy
|
||||
|
||||
case osgGA::GUIEventAdapter::PUSH:
|
||||
beginSendInputRange(ea, msg_id);
|
||||
sendMultiTouchData(ea);
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/press") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
if (!sendMultiTouchData(ea))
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/press") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
_oscStream << osc::EndBundle;
|
||||
do_send = true;
|
||||
break;
|
||||
|
||||
case osgGA::GUIEventAdapter::RELEASE:
|
||||
beginSendInputRange(ea, msg_id);
|
||||
sendMultiTouchData(ea);
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/release") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
if (!sendMultiTouchData(ea))
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/release") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
_oscStream << osc::EndBundle;
|
||||
do_send = true;
|
||||
break;
|
||||
|
||||
case osgGA::GUIEventAdapter::DOUBLECLICK:
|
||||
beginSendInputRange(ea, msg_id);
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/doublepress") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
if (!sendMultiTouchData(ea))
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/doublepress") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
|
||||
_oscStream << osc::EndBundle;
|
||||
do_send = true;
|
||||
break;
|
||||
@ -188,8 +187,8 @@ bool OscSendingDevice::sendUIEventImpl(const osgGA::GUIEventAdapter &ea, MsgIdTy
|
||||
case osgGA::GUIEventAdapter::MOVE:
|
||||
case osgGA::GUIEventAdapter::DRAG:
|
||||
beginSendInputRange(ea, msg_id);
|
||||
sendMultiTouchData(ea);
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/motion") << ea.getX() << ea.getY() << osc::EndMessage;
|
||||
if (!sendMultiTouchData(ea))
|
||||
_oscStream << osc::BeginMessage("/osgga/mouse/motion") << ea.getX() << ea.getY() << osc::EndMessage;
|
||||
_oscStream << osc::EndBundle;
|
||||
do_send = true;
|
||||
break;
|
||||
@ -227,10 +226,21 @@ bool OscSendingDevice::sendUIEventImpl(const osgGA::GUIEventAdapter &ea, MsgIdTy
|
||||
|
||||
if (do_send)
|
||||
{
|
||||
OSG_INFO << "OscDevice :: sending ui-event per OSC " << std::endl;
|
||||
// OSG_INFO << "OscDevice :: sending ui-event per OSC " << std::endl;
|
||||
|
||||
_transmitSocket.Send( _oscStream.Data(), _oscStream.Size() );
|
||||
_oscStream.Clear();
|
||||
|
||||
if (_finishMultiTouchSequence)
|
||||
{
|
||||
// if the last touch-point ended we'll need to send an empty tuio-bundle, so the receiver gets a chance to clean up
|
||||
beginBundle(msg_id);
|
||||
beginMultiTouchSequence();
|
||||
_oscStream << osc::EndBundle;
|
||||
_transmitSocket.Send( _oscStream.Data(), _oscStream.Size() );
|
||||
_oscStream.Clear();
|
||||
_finishMultiTouchSequence = false;
|
||||
}
|
||||
}
|
||||
|
||||
return do_send;
|
||||
@ -273,21 +283,28 @@ void OscSendingDevice::beginSendInputRange(const osgGA::GUIEventAdapter &ea, Msg
|
||||
}
|
||||
|
||||
|
||||
void OscSendingDevice::beginMultiTouchSequence() {
|
||||
|
||||
void OscSendingDevice::sendMultiTouchData(const osgGA::GUIEventAdapter &ea)
|
||||
{
|
||||
if(!ea.isMultiTouchEvent())
|
||||
return;
|
||||
|
||||
std::string application_name;
|
||||
getUserValue("tuio_application_name", application_name);
|
||||
|
||||
if (application_name.empty())
|
||||
application_name = std::string("OpenSceneGraph ") + osgGetVersion() + "@127.0.0.1";
|
||||
|
||||
osgGA::GUIEventAdapter::TouchData* touch_data = ea.getTouchData();
|
||||
|
||||
_oscStream << osc::BeginMessage("/tuio/2Dcur") << "source" << application_name.c_str() << osc::EndMessage;
|
||||
_oscStream << osc::BeginMessage("/tuio/2Dcur") << "fseq" << static_cast<osc::int32>(_msgId) << osc::EndMessage;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool OscSendingDevice::sendMultiTouchData(const osgGA::GUIEventAdapter &ea)
|
||||
{
|
||||
if(!ea.isMultiTouchEvent())
|
||||
return false;
|
||||
|
||||
beginMultiTouchSequence();
|
||||
|
||||
osgGA::GUIEventAdapter::TouchData* touch_data = ea.getTouchData();
|
||||
|
||||
_oscStream << osc::BeginMessage("/tuio/2Dcur") << "alive";
|
||||
for(osgGA::GUIEventAdapter::TouchData::iterator i = touch_data->begin(); i != touch_data->end(); ++i)
|
||||
@ -295,23 +312,33 @@ void OscSendingDevice::sendMultiTouchData(const osgGA::GUIEventAdapter &ea)
|
||||
_oscStream << osc::EndMessage;
|
||||
|
||||
unsigned int j(0);
|
||||
unsigned int num_ended(0);
|
||||
for(osgGA::GUIEventAdapter::TouchData::iterator i = touch_data->begin(); i != touch_data->end(); ++i, ++j)
|
||||
{
|
||||
float x = (ea.getTouchPointNormalizedX(j) + 1.0) / 2.0;
|
||||
float y =(ea.getTouchPointNormalizedY(j) + 1.0) / 2.0;
|
||||
|
||||
// flip y if origin is not top/left
|
||||
if(ea.getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
|
||||
y *= -1;
|
||||
|
||||
float vel_x(0), vel_y(0), accel(0);
|
||||
if (_lastEvent.valid())
|
||||
{
|
||||
|
||||
// TODO: add velocity + acceleration
|
||||
}
|
||||
|
||||
_oscStream << osc::BeginMessage("/tuio/2Dcur") << "set" << static_cast<osc::int32>(i->id) << x << y << vel_x << vel_y << accel << osc::EndMessage;
|
||||
if(i->phase == osgGA::GUIEventAdapter::TOUCH_ENDED)
|
||||
num_ended++;
|
||||
}
|
||||
|
||||
_oscStream << osc::BeginMessage("/tuio/2Dcur") << "fseq" << static_cast<osc::int32>(_msgId) << osc::EndMessage;
|
||||
|
||||
_lastEvent = new osgGA::GUIEventAdapter(ea);
|
||||
|
||||
_finishMultiTouchSequence = (num_ended == touch_data->getNumTouchPoints());
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +65,8 @@ private:
|
||||
bool sendUIEventImpl(const osgGA::GUIEventAdapter &ea,MsgIdType msg_id);
|
||||
void beginBundle(MsgIdType msg_id);
|
||||
void beginSendInputRange(const osgGA::GUIEventAdapter& ea, MsgIdType msg_id);
|
||||
void sendMultiTouchData(const osgGA::GUIEventAdapter& ea);
|
||||
void beginMultiTouchSequence();
|
||||
bool sendMultiTouchData(const osgGA::GUIEventAdapter& ea);
|
||||
int getButtonNum(const osgGA::GUIEventAdapter& ea);
|
||||
void sendUserDataContainer(const std::string& key, const osg::UserDataContainer* udc, bool asBundle, MsgIdType msg_id);
|
||||
std::string transliterateKey(const std::string& key) const;
|
||||
@ -76,6 +77,7 @@ private:
|
||||
unsigned int _numMessagesPerEvent, _delayBetweenSendsInMilliSecs;
|
||||
osc::int64 _msgId;
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> _lastEvent;
|
||||
bool _finishMultiTouchSequence;
|
||||
|
||||
};
|
||||
|
||||
|
@ -2020,12 +2020,19 @@ void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& const
|
||||
OSG_INFO<<"click_to_run ["<<cur->contents<<"]"<<std::endl;
|
||||
constructor.layerClickToDoOperation(cur->contents,osgPresentation::RUN, jumpData);
|
||||
}
|
||||
else if (match(cur->name, "forward_mouse_event_to_device"))
|
||||
else if (match(cur->name,"forward_mouse_event_to_device") || match(cur->name,"forward_event_to_device"))
|
||||
{
|
||||
osgPresentation::JumpData jumpData;
|
||||
|
||||
OSG_ALWAYS<<"forward_mouse_event_to_device ["<<cur->contents<<"]"<<std::endl;
|
||||
constructor.layerClickToDoOperation(cur->contents,osgPresentation::FORWARD_EVENT, jumpData);
|
||||
OSG_INFO<<"forward_mouse_event_to_device ["<<cur->contents<<"]"<<std::endl;
|
||||
constructor.layerClickToDoOperation(cur->contents,osgPresentation::FORWARD_MOUSE_EVENT, jumpData);
|
||||
}
|
||||
else if (match(cur->name,"forward_touch_event_to_device"))
|
||||
{
|
||||
osgPresentation::JumpData jumpData;
|
||||
|
||||
OSG_INFO<<"forward_touch_event_to_device ["<<cur->contents<<"]"<<std::endl;
|
||||
constructor.layerClickToDoOperation(cur->contents,osgPresentation::FORWARD_TOUCH_EVENT, jumpData);
|
||||
}
|
||||
else if (match(cur->name, "click_to_load"))
|
||||
{
|
||||
|
@ -149,7 +149,8 @@ void KeyEventHandler::doOperation()
|
||||
OSG_NOTICE<<"Requires jump "<<std::endl;
|
||||
break;
|
||||
}
|
||||
case(osgPresentation::FORWARD_EVENT):
|
||||
case(osgPresentation::FORWARD_MOUSE_EVENT):
|
||||
case(osgPresentation::FORWARD_TOUCH_EVENT):
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,14 @@ bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
|
||||
hitr!=intersections.end();
|
||||
++hitr)
|
||||
{
|
||||
if (_operation == FORWARD_EVENT)
|
||||
if (_operation == FORWARD_MOUSE_EVENT)
|
||||
{
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> cloned_ea = osg::clone(&ea);
|
||||
|
||||
// clear touch-data as this prevents sending the event as mouse-event
|
||||
cloned_ea->setTouchData(NULL);
|
||||
|
||||
// reproject mouse-coord
|
||||
const osg::BoundingBox bb(hitr->drawable->getBound());
|
||||
const osg::Vec3& p(hitr->localIntersectionPoint);
|
||||
|
||||
@ -85,8 +90,53 @@ bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
|
||||
cloned_ea->setY(ea.getYmin() + transformed_y * (ea.getYmax() - ea.getYmin()));
|
||||
cloned_ea->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
|
||||
|
||||
|
||||
// std::cout << transformed_x << "/" << transformed_x << " -> " << cloned_ea->getX() << "/" <<cloned_ea->getY() << std::endl;
|
||||
|
||||
SlideEventHandler::instance()->forwardEventToDevices(cloned_ea.get());
|
||||
}
|
||||
else if ((_operation == FORWARD_TOUCH_EVENT) && ea.isMultiTouchEvent())
|
||||
{
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> cloned_ea = osg::clone(&ea);
|
||||
osgGA::GUIEventAdapter::TouchData* touch_data = cloned_ea->getTouchData();
|
||||
|
||||
|
||||
|
||||
// reproject touch-points
|
||||
const osg::BoundingBox bb(hitr->drawable->getBound());
|
||||
|
||||
osg::Camera* camera = viewer->getCamera();
|
||||
osg::Matrix matrix = osg::computeLocalToWorld(hitr->nodePath, false) * camera->getViewMatrix() * camera->getProjectionMatrix();
|
||||
matrix.postMult(camera->getViewport()->computeWindowMatrix());
|
||||
|
||||
osg::Matrixd inverse;
|
||||
inverse.invert(matrix);
|
||||
|
||||
// transform touch-points into local coord-system
|
||||
unsigned int j(0);
|
||||
for(osgGA::GUIEventAdapter::TouchData::iterator i = touch_data->begin(); i != touch_data->end(); ++i, ++j)
|
||||
{
|
||||
osg::Vec3 local = osg::Vec3(i->x, i->y, 0) * inverse;
|
||||
|
||||
// std::cout << local << " hit: " << hitr->localIntersectionPoint << std::endl;
|
||||
|
||||
local.x() = (local.x() - bb.xMin()) / (bb.xMax() - bb.xMin());
|
||||
local.z() = (local.z() - bb.zMin()) / (bb.zMax() - bb.zMin());
|
||||
|
||||
local.x() = (ea.getXmin() + local.x() * (ea.getXmax() - ea.getXmin()));
|
||||
local.z() = (ea.getYmin() + local.z() * (ea.getYmax() - ea.getYmin()));
|
||||
|
||||
// std::cout << ea.getX() << "/" << ea.getY() << " -- " << i->x << " " << i->y << " -> " << local.x() <<"/" << local.z() << std::endl;
|
||||
|
||||
i->x = local.x();
|
||||
i->y = local.z();
|
||||
}
|
||||
|
||||
|
||||
// std::cout << transformed_x << "/" << transformed_x << " -> " << cloned_ea->getX() << "/" <<cloned_ea->getY() << std::endl;
|
||||
|
||||
|
||||
SlideEventHandler::instance()->forwardEventToDevices(cloned_ea.get());
|
||||
}
|
||||
else
|
||||
@ -206,7 +256,8 @@ void PickEventHandler::doOperation()
|
||||
OSG_INFO<<"Requires jump "<<std::endl;
|
||||
break;
|
||||
}
|
||||
case(osgPresentation::FORWARD_EVENT):
|
||||
case(osgPresentation::FORWARD_MOUSE_EVENT):
|
||||
case(osgPresentation::FORWARD_TOUCH_EVENT):
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -869,19 +869,25 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect)
|
||||
NSSet *allTouches = [event touchesMatchingPhase: NSTouchPhaseAny inView: self];
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> osg_event(NULL);
|
||||
|
||||
NSRect bounds = [self bounds];
|
||||
|
||||
for(unsigned int i=0; i<[allTouches count]; i++)
|
||||
{
|
||||
|
||||
NSTouch *touch = [[allTouches allObjects] objectAtIndex:i];
|
||||
NSPoint pos = [touch normalizedPosition];
|
||||
osg::Vec2 pixelPos(pos.x * bounds.size.width, (pos.y) * bounds.size.height);
|
||||
pos.x *= bounds.size.width;
|
||||
pos.y *= bounds.size.height;
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup:FALSE];
|
||||
if (!osg_event) {
|
||||
osg_event = _win->getEventQueue()->touchBegan(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
} else {
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchBegan(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y);
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
osg_event->setInputRange(0, 0, bounds.size.width, bounds.size.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -897,12 +903,18 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect)
|
||||
{
|
||||
NSTouch *touch = [[allTouches allObjects] objectAtIndex:i];
|
||||
NSPoint pos = [touch normalizedPosition];
|
||||
osg::Vec2 pixelPos(pos.x * bounds.size.width, (pos.y) * bounds.size.height);
|
||||
pos.x *= bounds.size.width;
|
||||
pos.y *= bounds.size.height;
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup:FALSE];
|
||||
if (!osg_event) {
|
||||
osg_event = _win->getEventQueue()->touchMoved(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
} else {
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchMoved(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y);
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
osg_event->setInputRange(0, 0, bounds.size.width, bounds.size.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -914,17 +926,24 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect)
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> osg_event(NULL);
|
||||
NSRect bounds = [self bounds];
|
||||
|
||||
|
||||
for(unsigned int i=0; i<[allTouches count]; i++)
|
||||
{
|
||||
NSTouch *touch = [[allTouches allObjects] objectAtIndex:i];
|
||||
NSPoint pos = [touch normalizedPosition];
|
||||
osg::Vec2 pixelPos(pos.x * bounds.size.width, (pos.y) * bounds.size.height);
|
||||
pos.x *= bounds.size.width;
|
||||
pos.y *= bounds.size.height;
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup: TRUE];
|
||||
if (!osg_event) {
|
||||
osg_event = _win->getEventQueue()->touchEnded(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), 1);
|
||||
} else {
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), 1);
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchEnded(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y, 1);
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
osg_event->setInputRange(0, 0, bounds.size.width, bounds.size.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pos.x, pos.y, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -580,11 +580,17 @@ typedef std::map<void*, unsigned int> TouchPointsIdMapping;
|
||||
osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)];
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup: FALSE];
|
||||
|
||||
if (!osg_event) {
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchBegan(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
} else {
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
@ -603,11 +609,17 @@ typedef std::map<void*, unsigned int> TouchPointsIdMapping;
|
||||
osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)];
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup: FALSE];
|
||||
|
||||
if (!osg_event) {
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchMoved(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
} else {
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[super touchesMoved:touches withEvent:event];
|
||||
@ -626,11 +638,17 @@ typedef std::map<void*, unsigned int> TouchPointsIdMapping;
|
||||
CGPoint pos = [touch locationInView:self];
|
||||
osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)];
|
||||
unsigned int touch_id = [self computeTouchId: touch mayCleanup: TRUE];
|
||||
if (!osg_event) {
|
||||
if (!osg_event)
|
||||
{
|
||||
osg_event = _win->getEventQueue()->touchEnded(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), [touch tapCount]);
|
||||
} else {
|
||||
osg_event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg_event->addTouchPoint(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), [touch tapCount]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
|
@ -927,6 +927,11 @@ void Viewer::eventTraversal()
|
||||
{
|
||||
event->setY((event->getYmax()-event->getY())+event->getYmin());
|
||||
event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
|
||||
if(event->isMultiTouchEvent()) {
|
||||
for(osgGA::GUIEventAdapter::TouchData::iterator itr = event->getTouchData()->begin(); itr != event->getTouchData()->end(); itr++) {
|
||||
itr->y = event->getYmax() - itr->y + event->getYmin();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user