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:
Robert Osfield 2014-01-23 15:37:48 +00:00
parent 09c09628ac
commit a96ad565c7
15 changed files with 368 additions and 145 deletions

View File

@ -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() );
@ -445,6 +499,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());
ssManipulator->setKeyEventToggleTexturing('e');

View File

@ -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
// 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];
// create the main window at screen size
self._window = [[UIWindow alloc] initWithFrame: lFrame];
//show window
[_window makeKeyAndVisible];
//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;
//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);
// 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 = 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;
// 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;
traits->inheritedWindowData = windata;
// Create the Graphics Context
osg::ref_ptr<osg::GraphicsContext> graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get());
// 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));
// 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

View File

@ -675,6 +675,7 @@ 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()); }

View File

@ -37,7 +37,8 @@ enum Operation
LOAD,
EVENT,
JUMP,
FORWARD_EVENT
FORWARD_MOUSE_EVENT,
FORWARD_TOUCH_EVENT
};
struct JumpData

View File

@ -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()
{

View File

@ -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;
continue;
}*/
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);
//create a unique touchpoint-id
unsigned int touch_id = (source_id << 16) + 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)
std::set<unsigned int>& unhandled(endpoint_data.unhandled);
if ((unhandled.find(k->first) == unhandled.end()))
{
_alive[source].erase(i->second.find(*k));
}
// std::cout << "deleting: " << k->first << " from " << k->second.end_point << std::endl;
to_delete.push_back(k->first);
endpoint_data.mayClearUnhandledPointer = false;
endpoint_data.unhandled.clear();
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();
}

View File

@ -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,11 +283,7 @@ void OscSendingDevice::beginSendInputRange(const osgGA::GUIEventAdapter &ea, Msg
}
void OscSendingDevice::sendMultiTouchData(const osgGA::GUIEventAdapter &ea)
{
if(!ea.isMultiTouchEvent())
return;
void OscSendingDevice::beginMultiTouchSequence() {
std::string application_name;
getUserValue("tuio_application_name", application_name);
@ -285,9 +291,20 @@ void OscSendingDevice::sendMultiTouchData(const osgGA::GUIEventAdapter &ea)
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;
}

View File

@ -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;
};

View File

@ -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"))
{

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}
}
@ -915,16 +927,23 @@ 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);
}
}

View File

@ -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];

View File

@ -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