From Stephan Huber, added event sending support into osgGA::Device along with implementation on this into the osc plugin. Added osgoscdevice example to demonstate this in action.

This commit is contained in:
Robert Osfield
2012-11-28 10:43:58 +00:00
parent 694e603d15
commit 8b231ba8e3
13 changed files with 574 additions and 950 deletions

View File

@@ -16,6 +16,8 @@
using namespace osgGA;
Device::Device()
: osg::Object()
, _capabilities(UNKNOWN)
{
setEventQueue(new EventQueue);
}
@@ -26,6 +28,21 @@ Device::Device(const Device& es, const osg::CopyOp& copyop):
setEventQueue(new EventQueue);
}
void Device::sendEvent(const GUIEventAdapter& event)
{
OSG_WARN << "Device::sendEvent not implemented!" << std::endl;
}
void Device::sendEvents(const EventQueue::Events& events)
{
for(EventQueue::Events::const_iterator i = events.begin(); i != events.end(); i++)
{
sendEvent(**i);
}
}
Device::~Device()
{
}

View File

@@ -6,8 +6,8 @@ SET(TARGET_SRC
osc/OscPrintReceivedElements.cpp
osc/OscReceivedElements.cpp
osc/OscTypes.cpp
OscDevice.cpp
OscProxyEventHandler.cpp
OscReceivingDevice.cpp
OscSendingDevice.cpp
ReaderWriterOscDevice.cpp
)
@@ -25,8 +25,8 @@ SET(TARGET_H
osc/OscPrintReceivedElements.h
osc/OscReceivedElements.h
osc/OscTypes.h
OscProxyEventHandler.hpp
OscDevice.hpp
OscReceivingDevice.hpp
OscSendingDevice.hpp
)
if(WIN32)

View File

@@ -1,598 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "OscDevice.hpp"
#include <OpenThreads/Thread>
#include <osgDB/FileUtils>
#include "osc/OscPrintReceivedElements.h"
#include "osc/OscHostEndianness.h"
class StandardRequestHandler : public OscDevice::RequestHandler {
public:
StandardRequestHandler() : OscDevice::RequestHandler("") {}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
OSG_NOTICE << "OscDevice :: unhandled request: " << full_request_path << std::endl;
for(osc::ReceivedMessageArgumentIterator itr = m.ArgumentsBegin(); itr != m.ArgumentsEnd(); ++itr)
{
OSG_NOTICE << " " << (*itr) << std::endl;
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << ": fall-through request-handler, catches all requests w/o registered handler and report them to the console";
}
};
class SetMouseInputRangeRequestHandler : public OscDevice::RequestHandler {
public:
SetMouseInputRangeRequestHandler()
: OscDevice::RequestHandler("/osgga/mouse/set_input_range")
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
float x_min(-1.0f), y_min(-1.0f), x_max(1.0f), y_max(1.0f);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> x_min >> y_min >> x_max >> y_max >> osc::EndMessage;
getDevice()->getEventQueue()->setMouseInputRange(x_min, y_min, x_max, y_max);
return true;
}
catch(osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float x_min, float y_min, float x_max, float y_max): sets the mouse-input-range" << std::dec;
}
};
class SetMouseOrientationRequestHandler : public OscDevice::RequestHandler {
public:
SetMouseOrientationRequestHandler()
: OscDevice::RequestHandler("/osgga/mouse/y_orientation_increasing_upwards")
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
bool increasing_upwards(false);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >>increasing_upwards >> osc::EndMessage;
getDevice()->getEventQueue()->getCurrentEventState()->setMouseYOrientation(
increasing_upwards ? osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS : osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);
return true;
}
catch(osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float x_min, float y_min, float x_max, float y_max): sets the mouse-input-range" << std::dec;
}
};
class KeyCodeRequestHandler : public OscDevice::RequestHandler {
public:
KeyCodeRequestHandler(bool handle_key_press)
: OscDevice::RequestHandler(std::string("/osgga/key/") + ((handle_key_press) ? "press" : "release"))
, _handleKeyPress(handle_key_press)
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
osc::int32 keycode(0);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> keycode >> osc::EndMessage;
if (_handleKeyPress)
getDevice()->getEventQueue()->keyPress(keycode, getLocalTime());
else
getDevice()->getEventQueue()->keyRelease(keycode, getLocalTime());
return true;
}
catch(osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(int keycode): send KEY_" << (_handleKeyPress ? "DOWN" : "UP");
}
private:
bool _handleKeyPress;
};
class KeyPressAndReleaseRequestHandler : public OscDevice::RequestHandler {
public:
KeyPressAndReleaseRequestHandler()
: OscDevice::RequestHandler("/osgga/key/press_and_release")
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
osc::int32 keycode(0);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> keycode >> osc::EndMessage;
getDevice()->getEventQueue()->keyPress(keycode, getLocalTime());
getDevice()->getEventQueue()->keyRelease(keycode, getLocalTime());
return true;
}
catch(osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(int keycode): send KEY_DOWN and KEY_UP";
}
private:
bool _handleKeyPress;
};
class MouseMotionRequestHandler : public OscDevice::RequestHandler {
public:
MouseMotionRequestHandler()
: OscDevice::RequestHandler("/osgga/mouse/motion")
, _lastX(0.0f)
, _lastY(0.0f)
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> _lastX >> _lastY >> osc::EndMessage;
getDevice()->getEventQueue()->mouseMotion(_lastX, _lastY, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float x, float y): send mouse motion";
}
float getLastX() const { return _lastX; }
float getLastY() const { return _lastY; }
private:
float _lastX, _lastY;
};
class MouseScrollRequestHandler : public OscDevice::RequestHandler {
public:
MouseScrollRequestHandler()
: OscDevice::RequestHandler("/osgga/mouse/scroll")
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
osc::int32 sm(osgGA::GUIEventAdapter::SCROLL_NONE);
float delta_x(0.0f), delta_y(0.0f);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> sm >> delta_x >> delta_y >> osc::EndMessage;
if (sm != osgGA::GUIEventAdapter::SCROLL_NONE)
getDevice()->getEventQueue()->mouseScroll((osgGA::GUIEventAdapter::ScrollingMotion)sm, getLocalTime());
if ((delta_x != 0.0f) || (delta_y != 0.0f))
getDevice()->getEventQueue()->mouseScroll2D(delta_x, delta_y, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(int scroll_motion, float x, float y): send mouse scroll-motion";
}
};
class MouseButtonToggleRequestHandler : public OscDevice::RequestHandler {
public:
MouseButtonToggleRequestHandler(const std::string& btn_name, MouseMotionRequestHandler* mm_handler)
: OscDevice::RequestHandler("/osgga/mouse/toggle/"+btn_name)
, _mmHandler(mm_handler)
, _btnNum(atoi(btn_name.c_str()))
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
float down(0.0f);
try {
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> down >> osc::EndMessage;
if (down > 0)
getDevice()->getEventQueue()->mouseButtonPress(_mmHandler->getLastX(), _mmHandler->getLastY(), _btnNum, getLocalTime());
else
getDevice()->getEventQueue()->mouseButtonRelease(_mmHandler->getLastX(), _mmHandler->getLastY(), _btnNum, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float down): toggle mouse button";
}
private:
osg::observer_ptr<MouseMotionRequestHandler> _mmHandler;
int _btnNum;
};
class MouseButtonRequestHandler : public OscDevice::RequestHandler {
public:
enum Mode { PRESS, RELEASE, DOUBLE_PRESS};
MouseButtonRequestHandler(Mode mode)
: OscDevice::RequestHandler("")
, _mode(mode)
{
switch(mode) {
case PRESS:
setRequestPath("/osgga/mouse/press");
break;
case RELEASE:
setRequestPath("/osgga/mouse/release");
break;
case DOUBLE_PRESS:
setRequestPath("/osgga/mouse/doublepress");
break;
}
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
float x(0.0f), y(0.0f);
osc::int32 btn(0);
try {
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> x >> y >> btn >> osc::EndMessage;
switch (_mode) {
case PRESS:
getDevice()->getEventQueue()->mouseButtonPress(x,y, btn, getLocalTime());
break;
case RELEASE:
getDevice()->getEventQueue()->mouseButtonRelease(x,y, btn, getLocalTime());
break;
case DOUBLE_PRESS:
getDevice()->getEventQueue()->mouseDoubleButtonPress(x,y, btn, getLocalTime());
break;
}
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float x, float y, int btn): send mouse ";
switch (_mode) {
case PRESS:
out << "press"; break;
case RELEASE:
out << "release"; break;
case DOUBLE_PRESS:
out << "double press"; break;
}
}
private:
Mode _mode;
};
class PenPressureRequestHandler : public OscDevice::RequestHandler {
public:
PenPressureRequestHandler()
: OscDevice::RequestHandler("/osgga/pen/pressure")
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
float pressure(0.0f);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> pressure >> osc::EndMessage;
getDevice()->getEventQueue()->penPressure(pressure, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float pressure): send pen pressure";
}
};
class PenProximityRequestHandler : public OscDevice::RequestHandler {
public:
PenProximityRequestHandler(bool handle_enter)
: OscDevice::RequestHandler(std::string("/osgga/pen/proximity/") + ((handle_enter) ? std::string("enter") : std::string("leave")))
, _handleEnter(handle_enter)
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
osc::int32 pt(osgGA::GUIEventAdapter::UNKNOWN);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> pt >> osc::EndMessage;
getDevice()->getEventQueue()->penProximity((osgGA::GUIEventAdapter::TabletPointerType)pt, _handleEnter, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(int table_pointer_type): send pen proximity " << (_handleEnter ? "enter":"leave");
}
private:
bool _handleEnter;
};
class PenOrientationRequestHandler : public OscDevice::RequestHandler {
public:
PenOrientationRequestHandler()
: OscDevice::RequestHandler("/osgga/pen/orientation")
, _lastX(0.0f)
, _lastY(0.0f)
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m)
{
try {
float rotation(0.0f), tilt_x(0.0f), tilt_y(0.0f);
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
args >> rotation >> tilt_x >> tilt_y >> osc::EndMessage;
getDevice()->getEventQueue()->penOrientation(tilt_x, tilt_y, rotation, getLocalTime());
return true;
}
catch (osc::Exception e) {
handleException(e);
}
return false;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << "(float rotation, float tilt_x, float tilt_y): send pen orientation";
}
float getLastX() const { return _lastX; }
float getLastY() const { return _lastY; }
private:
float _lastX, _lastY;
};
OscDevice::OscDevice(const std::string& server_address, int listening_port)
: osgGA::Device()
, OpenThreads::Thread()
, osc::OscPacketListener()
, _listeningAddress(server_address)
, _listeningPort(listening_port)
, _socket(NULL)
, _map()
{
OSG_NOTICE << "OscDevice :: listening on " << server_address << ":" << listening_port << " ";
#ifdef OSC_HOST_LITTLE_ENDIAN
OSG_NOTICE << "(little endian)";
#elif OSC_HOST_BIG_ENDIAN
OSG_NOTICE << "(big endian)";
#endif
OSG_NOTICE << std::endl;
_socket = new UdpListeningReceiveSocket(IpEndpointName( server_address.c_str(), listening_port ), this);
addRequestHandler(new KeyCodeRequestHandler(false));
addRequestHandler(new KeyCodeRequestHandler(true));
addRequestHandler(new KeyPressAndReleaseRequestHandler());
addRequestHandler(new SetMouseInputRangeRequestHandler());
addRequestHandler(new SetMouseOrientationRequestHandler());
MouseMotionRequestHandler* mm_handler = new MouseMotionRequestHandler();
addRequestHandler(mm_handler);
addRequestHandler(new MouseButtonRequestHandler(MouseButtonRequestHandler::PRESS));
addRequestHandler(new MouseButtonRequestHandler(MouseButtonRequestHandler::RELEASE));
addRequestHandler(new MouseButtonRequestHandler(MouseButtonRequestHandler::DOUBLE_PRESS));
addRequestHandler(new MouseScrollRequestHandler());
addRequestHandler(new MouseButtonToggleRequestHandler("1", mm_handler));
addRequestHandler(new MouseButtonToggleRequestHandler("2", mm_handler));
addRequestHandler(new MouseButtonToggleRequestHandler("3", mm_handler));
addRequestHandler(new PenPressureRequestHandler());
addRequestHandler(new PenOrientationRequestHandler());
addRequestHandler(new PenProximityRequestHandler(true));
addRequestHandler(new PenProximityRequestHandler(false));
addRequestHandler(new StandardRequestHandler());
start();
}
OscDevice::~OscDevice()
{
_socket->AsynchronousBreak();
join();
delete _socket;
}
void OscDevice::run()
{
_socket->Run();
}
void OscDevice::ProcessMessage( const osc::ReceivedMessage& m, const IpEndpointName& remoteEndpoint )
{
std::string in_request_path(m.AddressPattern());
std::string request_path = in_request_path + "/";
std::size_t pos(std::string::npos);
bool handled(false);
do {
pos = request_path.find_last_of('/', pos-1);
if (pos != std::string::npos)
{
std::string mangled_path = request_path.substr(0, pos);
std::pair<RequestHandlerMap::iterator,RequestHandlerMap::iterator> range = _map.equal_range(mangled_path);
for(RequestHandlerMap::iterator i = range.first; i != range.second; ++i)
{
OSG_INFO << "OscDevice :: handling " << mangled_path << " with " << i->second << std::endl;
if (i->second->operator()(mangled_path, in_request_path, m) && !handled)
handled = true;
}
}
} while ((pos != std::string::npos) && (pos > 0) && !handled);
}
void OscDevice::ProcessPacket( const char *data, int size, const IpEndpointName& remoteEndpoint )
{
OSG_INFO << "OscDevice :: receiving " << size << " bytes of data ..." << std::endl;
try {
osc::OscPacketListener::ProcessPacket(data, size, remoteEndpoint);
}
catch(const osc::Exception& e) {
OSG_WARN << "OscDevice :: could not process UDP-packet: " << e.what() << std::endl;
}
catch(...) {
OSG_WARN << "OscDevice :: could not process UDP-packet because of an exception!" << std::endl;
}
}
void OscDevice::addRequestHandler(RequestHandler* handler)
{
if (handler)
{
_map.insert(std::make_pair(handler->getRequestPath(), handler));
handler->setDevice(this);
}
}
void OscDevice::describeTo(std::ostream& out) const
{
out << "OscDevice :: listening on " << _listeningAddress << ":" << _listeningPort << std::endl;
out << std::endl;
for(RequestHandlerMap::const_iterator i = _map.begin(); i != _map.end(); ++i)
{
const RequestHandler* handler(i->second.get());
out << "OscDevice :: ";
handler->describeTo(out);
out << std::endl;
}
}

View File

@@ -1,112 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#pragma once
#include <osg/Referenced>
#include <OpenThreads/Thread>
#include <osgGA/Device>
#include <osc/OscPacketListener.h>
#include <ip/UdpSocket.h>
class OscDevice : public osgGA::Device, OpenThreads::Thread, osc::OscPacketListener {
public:
class RequestHandler : public osg::Referenced {
public:
RequestHandler(const std::string& request_path)
: osg::Referenced()
, _requestPath(request_path)
, _device(NULL)
{
}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& m) = 0;
const std::string& getRequestPath() const { return _requestPath; }
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << ": no description available";
}
protected:
void setDevice(OscDevice* device) { _device = device; }
OscDevice* getDevice() const { return _device; }
/// set the request-path, works only from the constructor
void setRequestPath(const std::string& request_path) { _requestPath = request_path; }
void handleException(const osc::Exception& e)
{
OSG_WARN << "OscDevice :: error while handling " << getRequestPath() << ": " << e.what() << std::endl;
}
double getLocalTime() const { return getDevice()->getEventQueue()->getTime(); }
private:
std::string _requestPath;
OscDevice* _device;
friend class OscDevice;
};
typedef std::multimap<std::string, osg::ref_ptr<RequestHandler> > RequestHandlerMap;
OscDevice(const std::string& server_address, int listening_port);
~OscDevice();
virtual void checkEvents() {}
virtual void run();
virtual void ProcessMessage( const osc::ReceivedMessage& m, const IpEndpointName& remoteEndpoint );
virtual void ProcessPacket( const char *data, int size, const IpEndpointName& remoteEndpoint );
void addRequestHandler(RequestHandler* handler);
void describeTo(std::ostream& out) const;
friend std::ostream& operator<<(std::ostream& out, const OscDevice& device)
{
device.describeTo(out);
return out;
}
private:
std::string _listeningAddress;
unsigned int _listeningPort;
UdpListeningReceiveSocket* _socket;
RequestHandlerMap _map;
};
class SendKeystrokeRequestHandler : public OscDevice::RequestHandler {
public:
SendKeystrokeRequestHandler(const std::string& request_path, int key) : OscDevice::RequestHandler(request_path), _key(key) {}
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const osc::ReceivedMessage& arguments)
{
getDevice()->getEventQueue()->keyPress(_key);
getDevice()->getEventQueue()->keyRelease(_key);
return true;
}
virtual void describeTo(std::ostream& out) const
{
out << getRequestPath() << ": send KEY_DOWN + KEY_UP, code: 0x" << std::hex << _key << std::dec;
}
private:
int _key;
};

View File

@@ -1,173 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "OscProxyEventHandler.hpp"
#include "osc/OscHostEndianness.h"
static const unsigned long BUFFER_SIZE = 2048;
OscProxyEventHandler::OscProxyEventHandler(const std::string& address, int port)
: osgGA::GUIEventHandler()
, _transmitSocket(IpEndpointName(address.c_str(), port))
, _buffer(new char[BUFFER_SIZE])
, _oscStream(_buffer, BUFFER_SIZE)
, _firstRun(true)
{
OSG_NOTICE << "OscDevice :: sending events to " << address << ":" << port << " ";
#ifdef OSC_HOST_LITTLE_ENDIAN
OSG_NOTICE << "(little endian)";
#elif OSC_HOST_BIG_ENDIAN
OSG_NOTICE << "(big endian)";
#endif
OSG_NOTICE << std::endl;
}
OscProxyEventHandler::~OscProxyEventHandler()
{
delete[] (_buffer);
}
bool OscProxyEventHandler::handle (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *, osg::NodeVisitor *)
{
bool do_send(false);
switch(ea.getEventType())
{
case osgGA::GUIEventAdapter::FRAME:
if (_firstRun)
{
_firstRun = false;
sendInit(ea);
do_send = true;
}
break;
case osgGA::GUIEventAdapter::RESIZE:
sendInit(ea);
do_send = true;
break;
case osgGA::GUIEventAdapter::SCROLL:
_oscStream << osc::BeginMessage("/osgga/mouse/scroll") << ea.getScrollingMotion() << ea.getScrollingDeltaX() << ea.getScrollingDeltaY() << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::PEN_PRESSURE:
_oscStream
<< osc::BeginMessage("/osgga/pen/pressure")
<< ea.getPenPressure()
<< osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::PEN_ORIENTATION:
_oscStream
<< osc::BeginMessage("/osgga/pen/orientation")
<< ea.getPenRotation()
<< ea.getPenTiltX()
<< ea.getPenTiltY()
<< osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::PEN_PROXIMITY_ENTER:
_oscStream
<< osc::BeginMessage("/osgga/pen/proximity/enter")
<< ea.getTabletPointerType()
<< osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::PEN_PROXIMITY_LEAVE:
_oscStream
<< osc::BeginMessage("/osgga/pen/proximity/leave")
<< ea.getTabletPointerType()
<< osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::PUSH:
_oscStream << osc::BeginMessage("/osgga/mouse/press") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::RELEASE:
_oscStream << osc::BeginMessage("/osgga/mouse/release") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::DOUBLECLICK:
_oscStream << osc::BeginMessage("/osgga/mouse/doublepress") << ea.getX() << ea.getY() << getButtonNum(ea) << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::MOVE:
case osgGA::GUIEventAdapter::DRAG:
_oscStream << osc::BeginMessage("/osgga/mouse/motion") << ea.getX() << ea.getY() << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::KEYDOWN:
_oscStream << osc::BeginMessage("/osgga/key/press") << ea.getKey() << osc::EndMessage;
do_send = true;
break;
case osgGA::GUIEventAdapter::KEYUP:
_oscStream << osc::BeginMessage("/osgga/key/release") << ea.getKey() << osc::EndMessage;
do_send = true;
break;
default:
break;
}
if (do_send)
{
OSG_INFO << "OscDevice :: sending event per OSC " << std::endl;
_transmitSocket.Send( _oscStream.Data(), _oscStream.Size() );
_oscStream.Clear();
}
return false;
}
int OscProxyEventHandler::getButtonNum(const osgGA::GUIEventAdapter& ea)
{
switch(ea.getButton())
{
case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
return 1;
break;
case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
return 2;
break;
case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
return 3;
break;
default:
return -1;
}
return -1;
}
void OscProxyEventHandler::sendInit(const osgGA::GUIEventAdapter &ea)
{
_oscStream << osc::BeginBundle();
_oscStream << osc::BeginMessage("/osgga/resize") << ea.getWindowX() << ea.getWindowY() << ea.getWindowWidth() << ea.getWindowHeight() << osc::EndMessage;
_oscStream << osc::BeginMessage("/osgga/mouse/set_input_range") << ea.getXmin() << ea.getYmin() << ea.getXmax() << ea.getYmax() << osc::EndMessage;
_oscStream << osc::BeginMessage("/osgga/mouse/y_orientation_increasing_upwards") << (bool)(ea.getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS) << osc::EndMessage;
_oscStream << osc::EndBundle;
}

View File

@@ -1,39 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#pragma once
#include <osgGA/GUIEventHandler>
#include <ip/UdpSocket.h>
#include <osc/OscOutboundPacketStream.h>
class OscProxyEventHandler : public osgGA::GUIEventHandler {
public:
OscProxyEventHandler(const std::string& address, int port);
~OscProxyEventHandler();
virtual bool handle (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *, osg::NodeVisitor *);
private:
void sendInit(const osgGA::GUIEventAdapter& ea);
int getButtonNum(const osgGA::GUIEventAdapter& ea);
UdpTransmitSocket _transmitSocket;
char* _buffer;
osc::OutboundPacketStream _oscStream;
bool _firstRun;
};

View File

@@ -17,6 +17,9 @@
*
* the osc-plugin can return an osgGA::Device which handles various osc-messages
* and puts them into the event-queue of the app
* you can set arbitrary values via /osg/set_user_value, these values
* are set on the attached UserDataConntainer (see below)
*
* To open the osc-device for receiving do something like this:
*
* std::string filename = "<your-port-number-to-listen-on>.receiver.osc";
@@ -26,6 +29,12 @@
* The plugin supports the following option: documentRegisteredHandlers, which will
* dump all registered handlers to the console. The device registers some convenient
* handlers to remote control a p3d-presentation.
*
* you can feed a osgPresentation::PropertyManager into the plugin and set values on it via
* "/p3d/set_value key value" or "/p3d/set_value/key value"
* Additionally the plugin listens for
* "/osg/set_user_value key value" or "/osg/set_user_value/key value" and set the transmitted value on the
* UserDataContainer of the device.
*
*
* The plugin supports forwarding most of the events per osc to another host.
@@ -48,8 +57,9 @@
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include "OscDevice.hpp"
#include "OscProxyEventHandler.hpp"
#include "OscSendingDevice.hpp"
#include "OscReceivingDevice.hpp"
#include <osgPresentation/PropertyManager>
@@ -80,7 +90,7 @@ class ReaderWriterOsc : public osgDB::ReaderWriter
std::string server_address = file_name.substr(0,file_name.find(':'));
std::string server_port = file_name.substr(file_name.find(':') + 1);
return new OscProxyEventHandler(server_address, atoi(server_port.c_str()));
return new OscSendingDevice(server_address, atoi(server_port.c_str()));
}
else
{
@@ -99,7 +109,7 @@ class ReaderWriterOsc : public osgDB::ReaderWriter
}
try {
osg::ref_ptr<OscDevice> device = new OscDevice(server_address, port);
osg::ref_ptr<OscReceivingDevice> device = new OscReceivingDevice(server_address, port);
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slide/first", osgGA::GUIEventAdapter::KEY_Home));
@@ -120,7 +130,8 @@ class ReaderWriterOsc : public osgDB::ReaderWriter
device->addRequestHandler(new SendKeystrokeRequestHandler("/osgviewer/home", ' '));
device->addRequestHandler(new SendKeystrokeRequestHandler("/osgviewer/stats", 's'));
if ((options && (options->getPluginStringData("documentRegisteredHandlers") == "true")))
{

View File

@@ -195,7 +195,6 @@ public:
IpEndpointName temp = IpEndpointNameFromSockaddr(bindSockAddr);
char address[30];
temp.AddressAndPortAsString(address);
printf("UdpSocket::Bind() %s \n", address);
}
if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) {
throw std::runtime_error("unable to bind udp socket\n");
@@ -425,7 +424,6 @@ public:
timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
timeoutPtr = &timeout;
}
printf("UdpSocket::Run() waiting for select \n");
if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
throw std::runtime_error("select failed\n");
}
@@ -443,7 +441,6 @@ public:
i != socketListeners_.end(); ++i ){
if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
printf("UdpSocket::Run() reading from socket \n");
int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
if( size > 0 ){
i->first->ProcessPacket( data, size, remoteEndpoint );