Files
OpenSceneGraph/src/osgPlugins/osc/ReaderWriterOscDevice.cpp

161 lines
7.2 KiB
C++
Executable File

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 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.
*/
/*
* ReadMe
*
* the osc-plugin can return an osgGA::Device which handles various osc-messages
* and puts them into the event-queue of the app
* To open the osc-device for receiving do something like this:
*
* std::string filename = "<your-port-number-to-listen-on>.receiver.osc";
* osgGA::Device* device = dynamic_cast<osgGA::Device*>(osgDB::readObjectFile(filename));
*
* and add that device to your viewer
* 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.
*
*
* The plugin supports forwarding most of the events per osc to another host.
* It uses a special event-handler, which forwards the events. To get this
* event-handler, do something like this:
*
* std::string filename = "<target-address>:<target-port>.sender.osc";
* osgGA::GUIEventHandler* event_handler = dynamic_cast<osgGA::GUIEventHandler*>(osgDB::readObjectFile(filename));
*
* and add that event handler as the first event handler to your viewer/app
*
*
* TODO:
* - add multitouch support, preferably using the TUIO-protocol
* - be more tolerant with given filenames
*/
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include "OscDevice.hpp"
#include "OscProxyEventHandler.hpp"
class ReaderWriterOsc : public osgDB::ReaderWriter
{
public:
ReaderWriterOsc()
{
supportsExtension("osc", "Virtual Device Integration via a OSC_receiver");
supportsOption("documentRegisteredHandlers", "dump a documentation of all registered REST-handler to the console");
}
virtual const char* className() const { return "OSC Virtual Device Integration plugin"; }
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
{
if (osgDB::getFileExtension(file) == "osc")
{
std::string file_name = osgDB::getNameLessExtension(file);
if (osgDB::getFileExtension(file_name) == "sender")
{
file_name = osgDB::getNameLessExtension(file_name);
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()));
}
else
{
// defaults to receiver
file_name = osgDB::getNameLessExtension(file_name);
if (file_name.find(':') == std::string::npos) {
file_name = "0.0.0.0:" + file_name;
}
std::string server_address = file_name.substr(0,file_name.find(':'));
std::string server_port = file_name.substr(file_name.find(':') + 1);
int port = atoi(server_port.c_str());
if (port <= 0)
{
OSG_WARN << "ReaderWriterOsc :: can't get valid port from " << osgDB::getNameLessAllExtensions(file) << std::endl;
port = 8000;
}
try {
osg::ref_ptr<OscDevice> device = new OscDevice(server_address, port);
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slide/first", osgGA::GUIEventAdapter::KEY_Home));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slide/last", osgGA::GUIEventAdapter::KEY_End));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slide/next", osgGA::GUIEventAdapter::KEY_Right));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slide/previous", osgGA::GUIEventAdapter::KEY_Left));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/layer/next", osgGA::GUIEventAdapter::KEY_Down));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/layer/previous", osgGA::GUIEventAdapter::KEY_Up));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slideorlayer/next", osgGA::GUIEventAdapter::KEY_Page_Down));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/slideorlayer/previous", osgGA::GUIEventAdapter::KEY_Page_Up));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/unpause", 'o'));
device->addRequestHandler(new SendKeystrokeRequestHandler("/p3d/pause", 'p'));
device->addRequestHandler(new SendKeystrokeRequestHandler("/osgviewer/home", ' '));
device->addRequestHandler(new SendKeystrokeRequestHandler("/osgviewer/stats", 's'));
if ((options && (options->getPluginStringData("documentRegisteredHandlers") == "true")))
{
std::cout << *device << std::endl;
}
return device.release();
}
catch(const osc::Exception& e)
{
OSG_WARN << "OscDevice :: could not register UDP listener : " << e.what() << std::endl;
return ReadResult::ERROR_IN_READING_FILE;
}
catch(const std::exception& e)
{
OSG_WARN << "OscDevice :: could not register UDP listener : " << e.what() << std::endl;
return ReadResult::ERROR_IN_READING_FILE;
}
catch(...)
{
OSG_WARN << "OscDevice :: could not register UDP listener" << std::endl;
return ReadResult::ERROR_IN_READING_FILE;
}
}
}
return ReadResult::FILE_NOT_HANDLED;
}
};
// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(osc, ReaderWriterOsc)