iup-stack/iup/srctuio/tuio/TuioServer.cpp

635 lines
22 KiB
C++
Raw Permalink Normal View History

2023-02-20 16:44:45 +00:00
/*
TUIO C++ Library
Copyright (c) 2005-2017 Martin Kaltenbrunner <martin@tuio.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
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 GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
#include "TuioServer.h"
#include "UdpSender.h"
using namespace TUIO;
using namespace osc;
TuioServer::TuioServer()
:full_update (false)
,periodic_update (false)
,objectProfileEnabled (true)
,cursorProfileEnabled (true)
,blobProfileEnabled (true)
,source_name (NULL)
{
OscSender *oscsend = new UdpSender();
initialize(oscsend);
}
TuioServer::TuioServer(const char *host, int port)
:full_update (false)
,periodic_update (false)
,objectProfileEnabled (true)
,cursorProfileEnabled (true)
,blobProfileEnabled (true)
,source_name (NULL)
{
OscSender *oscsend = new UdpSender(host,port);
initialize(oscsend);
}
TuioServer::TuioServer(OscSender *oscsend)
:full_update (false)
,periodic_update (false)
,objectProfileEnabled (true)
,cursorProfileEnabled (true)
,blobProfileEnabled (true)
,source_name (NULL)
{
initialize(oscsend);
}
void TuioServer::initialize(OscSender *oscsend) {
senderList.push_back(oscsend);
int size = oscsend->getBufferSize();
oscBuffer = new char[size];
oscPacket = new osc::OutboundPacketStream(oscBuffer,size);
fullBuffer = new char[size];
fullPacket = new osc::OutboundPacketStream(oscBuffer,size);
objectUpdateTime = TuioTime(currentFrameTime);
cursorUpdateTime = TuioTime(currentFrameTime);
blobUpdateTime = TuioTime(currentFrameTime);
if (cursorProfileEnabled) sendEmptyCursorBundle();
if (objectProfileEnabled) sendEmptyObjectBundle();
if (blobProfileEnabled) sendEmptyBlobBundle();
invert_x = false;
invert_y = false;
invert_a = false;
}
TuioServer::~TuioServer() {
initFrame(TuioTime::getSessionTime());
stopUntouchedMovingCursors();
stopUntouchedMovingObjects();
stopUntouchedMovingBlobs();
initFrame(TuioTime::getSessionTime());
removeUntouchedStoppedCursors();
removeUntouchedStoppedObjects();
removeUntouchedStoppedBlobs();
if (cursorProfileEnabled) sendEmptyCursorBundle();
if (objectProfileEnabled) sendEmptyObjectBundle();
if (blobProfileEnabled) sendEmptyBlobBundle();
delete []oscBuffer;
delete oscPacket;
delete []fullBuffer;
delete fullPacket;
if (source_name) delete[] source_name;
for (unsigned int i=0;i<senderList.size();i++)
delete senderList[i];
}
void TuioServer::addOscSender(OscSender *sender) {
// add source address if previously local
/*if ((source_name) && (primary_sender->isLocal()) && (senderList.size()==1)) {
setSourceName(source_name);
}*/
// resize packets to smallest transport method
unsigned int size = sender->getBufferSize();
if (size<oscPacket->Capacity()) {
osc::OutboundPacketStream *temp = oscPacket;
oscPacket = new osc::OutboundPacketStream(oscBuffer,size);
delete temp;
temp = fullPacket;
fullPacket = new osc::OutboundPacketStream(oscBuffer,size);
delete temp;
}
senderList.push_back(sender);
}
void TuioServer::deliverOscPacket(osc::OutboundPacketStream *packet) {
for (unsigned int i=0;i<senderList.size();i++)
senderList[i]->sendOscPacket(packet);
}
void TuioServer::setSourceName(const char *name, const char *ip) {
if (!source_name) source_name = new char[256];
sprintf(source_name,"%s@%s",name,ip);
}
void TuioServer::setSourceName(const char *src) {
if (!source_name) source_name = new char[256];
/*if (senderList[0]->isLocal()) {
sprintf(source_name,"%s",src);
} else {*/
char hostname[64];
char *source_addr = NULL;
struct hostent *hp = NULL;
struct in_addr *addr = NULL;
gethostname(hostname, 64);
hp = gethostbyname(hostname);
if (hp==NULL) {
sprintf(hostname, "%s.local", hostname);
hp = gethostbyname(hostname);
}
if (hp!=NULL) {
for (int i = 0; hp->h_addr_list[i] != 0; ++i) {
addr = (struct in_addr *)(hp->h_addr_list[i]);
//std::cout << inet_ntoa(*addr) << std::endl;
source_addr = inet_ntoa(*addr);
}
} else {
//generate a random internet address
srand ( (unsigned int)time(NULL) );
int32 r = rand();
addr = (struct in_addr*)&r;
source_addr = inet_ntoa(*addr);
}
sprintf(source_name,"%s@%s",src,source_addr);
//}
std::cout << "tuio/src " << source_name << std::endl;
}
void TuioServer::commitFrame() {
TuioManager::commitFrame();
if(updateObject) {
startObjectBundle();
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<OBJ_MESSAGE_SIZE) {
sendObjectBundle(currentFrame);
startObjectBundle();
}
TuioObject *tobj = (*tuioObject);
if ((full_update) || (tobj->getTuioTime()==currentFrameTime)) addObjectMessage(tobj);
}
objectUpdateTime = TuioTime(currentFrameTime);
sendObjectBundle(currentFrame);
} else if (objectProfileEnabled && periodic_update) {
TuioTime timeCheck = currentFrameTime - objectUpdateTime;
if(timeCheck.getSeconds()>=update_interval) {
objectUpdateTime = TuioTime(currentFrameTime);
startObjectBundle();
if (full_update) {
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<OBJ_MESSAGE_SIZE) {
sendObjectBundle(currentFrame);
startObjectBundle();
}
addObjectMessage(*tuioObject);
}
}
sendObjectBundle(currentFrame);
}
}
updateObject = false;
if(updateCursor) {
startCursorBundle();
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<CUR_MESSAGE_SIZE) {
sendCursorBundle(currentFrame);
startCursorBundle();
}
TuioCursor *tcur = (*tuioCursor);
if ((full_update) || (tcur->getTuioTime()==currentFrameTime)) addCursorMessage(tcur);
}
cursorUpdateTime = TuioTime(currentFrameTime);
sendCursorBundle(currentFrame);
} else if (cursorProfileEnabled && periodic_update) {
TuioTime timeCheck = currentFrameTime - cursorUpdateTime;
if(timeCheck.getSeconds()>=update_interval) {
cursorUpdateTime = TuioTime(currentFrameTime);
startCursorBundle();
if (full_update) {
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<CUR_MESSAGE_SIZE) {
sendCursorBundle(currentFrame);
startCursorBundle();
}
addCursorMessage(*tuioCursor);
}
}
sendCursorBundle(currentFrame);
}
}
updateCursor = false;
if(updateBlob) {
startBlobBundle();
for (std::list<TuioBlob*>::iterator tuioBlob =blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<BLB_MESSAGE_SIZE) {
sendBlobBundle(currentFrame);
startBlobBundle();
}
TuioBlob *tblb = (*tuioBlob);
if ((full_update) || (tblb->getTuioTime()==currentFrameTime)) addBlobMessage(tblb);
}
blobUpdateTime = TuioTime(currentFrameTime);
sendBlobBundle(currentFrame);
} else if (blobProfileEnabled && periodic_update) {
TuioTime timeCheck = currentFrameTime - blobUpdateTime;
if(timeCheck.getSeconds()>=update_interval) {
blobUpdateTime = TuioTime(currentFrameTime);
startBlobBundle();
if (full_update) {
for (std::list<TuioBlob*>::iterator tuioBlob =blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++) {
// start a new packet if we exceed the packet capacity
if ((oscPacket->Capacity()-oscPacket->Size())<BLB_MESSAGE_SIZE) {
sendBlobBundle(currentFrame);
startBlobBundle();
}
addBlobMessage(*tuioBlob);
}
}
sendBlobBundle(currentFrame);
}
}
updateBlob = false;
}
void TuioServer::sendEmptyCursorBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "alive" << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "fseq" << -1 << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::startCursorBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "alive";
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++) {
/*if ((*tuioCursor)->getTuioState()!=TUIO_ADDED)*/ (*oscPacket) << (int32)((*tuioCursor)->getSessionID());
}
(*oscPacket) << osc::EndMessage;
}
void TuioServer::addCursorMessage(TuioCursor *tcur) {
//if (tcur->getTuioState()==TUIO_ADDED) return;
float xpos = tcur->getX();
float xvel = tcur->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = tcur->getY();
float yvel = tcur->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
(*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "set";
(*oscPacket) << (int32)(tcur->getSessionID()) << xpos << ypos;
(*oscPacket) << xvel << yvel << tcur->getMotionAccel();
(*oscPacket) << osc::EndMessage;
}
void TuioServer::sendCursorBundle(long fseq) {
(*oscPacket) << osc::BeginMessage( "/tuio/2Dcur") << "fseq" << (int32)fseq << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::sendEmptyObjectBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "alive" << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "fseq" << -1 << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::startObjectBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "alive";
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++) {
(*oscPacket) << (int32)((*tuioObject)->getSessionID());
}
(*oscPacket) << osc::EndMessage;
}
void TuioServer::addObjectMessage(TuioObject *tobj) {
float xpos = tobj->getX();
float xvel = tobj->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = tobj->getY();
float yvel = tobj->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
float angle = tobj->getAngle();
float rvel = tobj->getRotationSpeed();
if (invert_a) {
angle = 2.0f*(float)M_PI - angle;
rvel = -1 * rvel;
}
(*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "set";
(*oscPacket) << (int32)(tobj->getSessionID()) << tobj->getSymbolID() << xpos << ypos << angle;
(*oscPacket) << xvel << yvel << rvel << tobj->getMotionAccel() << tobj->getRotationAccel();
(*oscPacket) << osc::EndMessage;
}
void TuioServer::sendObjectBundle(long fseq) {
(*oscPacket) << osc::BeginMessage( "/tuio/2Dobj") << "fseq" << (int32)fseq << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::sendEmptyBlobBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "alive" << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "fseq" << -1 << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::startBlobBundle() {
oscPacket->Clear();
(*oscPacket) << osc::BeginBundleImmediate;
if (source_name) (*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "source" << source_name << osc::EndMessage;
(*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "alive";
for (std::list<TuioBlob*>::iterator tuioBlob = blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++) {
/*if ((*tuioBlob)->getTuioState()!=TUIO_ADDED)*/ (*oscPacket) << (int32)((*tuioBlob)->getSessionID());
}
(*oscPacket) << osc::EndMessage;
}
void TuioServer::addBlobMessage(TuioBlob *tblb) {
//if (tblb->getTuioState()==TUIO_ADDED) return;
float xpos = tblb->getX();
float xvel = tblb->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = tblb->getY();
float yvel = tblb->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
float angle = tblb->getAngle();
float rvel = tblb->getRotationSpeed();
if (invert_a) {
angle = 2.0f*(float)M_PI - angle;
rvel = -1 * rvel;
}
(*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "set";
(*oscPacket) << (int32)(tblb->getSessionID()) << xpos << ypos << angle << tblb->getWidth() << tblb->getHeight() << tblb->getArea();
(*oscPacket) << xvel << yvel << rvel << tblb->getMotionAccel() << tblb->getRotationAccel();
(*oscPacket) << osc::EndMessage;
}
void TuioServer::sendBlobBundle(long fseq) {
(*oscPacket) << osc::BeginMessage( "/tuio/2Dblb") << "fseq" << (int32)fseq << osc::EndMessage;
(*oscPacket) << osc::EndBundle;
deliverOscPacket( oscPacket );
}
void TuioServer::sendFullMessages() {
// prepare the cursor packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "source" << source_name << osc::EndMessage;
// add the cursor alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "alive";
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++)
(*fullPacket) << (int32)((*tuioCursor)->getSessionID());
(*fullPacket) << osc::EndMessage;
// add all current cursor set messages
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++) {
// start a new packet if we exceed the packet capacity
if ((fullPacket->Capacity()-fullPacket->Size())<CUR_MESSAGE_SIZE) {
// add the immediate fseq message and send the cursor packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
// prepare the new cursor packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "source" << source_name << osc::EndMessage;
// add the cursor alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "alive";
for (std::list<TuioCursor*>::iterator tuioCursor = cursorList.begin(); tuioCursor!=cursorList.end(); tuioCursor++)
(*fullPacket) << (int32)((*tuioCursor)->getSessionID());
(*fullPacket) << osc::EndMessage;
}
float xpos = (*tuioCursor)->getX();
float xvel = (*tuioCursor)->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = (*tuioCursor)->getY();
float yvel = (*tuioCursor)->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
// add the actual cursor set message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "set";
(*fullPacket) << (int32)((*tuioCursor)->getSessionID()) << xpos << ypos;
(*fullPacket) << xvel << yvel <<(*tuioCursor)->getMotionAccel();
(*fullPacket) << osc::EndMessage;
}
// add the immediate fseq message and send the cursor packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dcur") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
// prepare the object packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "source" << source_name << osc::EndMessage;
// add the object alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "alive";
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++)
(*fullPacket) << (int32)((*tuioObject)->getSessionID());
(*fullPacket) << osc::EndMessage;
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++) {
// start a new packet if we exceed the packet capacity
if ((fullPacket->Capacity()-fullPacket->Size())<OBJ_MESSAGE_SIZE) {
// add the immediate fseq message and send the object packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
// prepare the new object packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "source" << source_name << osc::EndMessage;
// add the object alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "alive";
for (std::list<TuioObject*>::iterator tuioObject = objectList.begin(); tuioObject!=objectList.end(); tuioObject++)
(*fullPacket) << (int32)((*tuioObject)->getSessionID());
(*fullPacket) << osc::EndMessage;
}
float xpos = (*tuioObject)->getX();
float xvel = (*tuioObject)->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = (*tuioObject)->getY();
float yvel = (*tuioObject)->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
float angle = (*tuioObject)->getAngle();
float rvel = (*tuioObject)->getRotationSpeed();
if (invert_a) {
angle = 2.0f*(float)M_PI - angle;
rvel = -1 * rvel;
}
// add the actual object set message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "set";
(*fullPacket) << (int32)((*tuioObject)->getSessionID()) << (*tuioObject)->getSymbolID() << xpos << ypos << angle;
(*fullPacket) << xvel << yvel << rvel << (*tuioObject)->getMotionAccel() << (*tuioObject)->getRotationAccel();
(*fullPacket) << osc::EndMessage;
}
// add the immediate fseq message and send the object packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dobj") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
// prepare the blob packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "source" << source_name << osc::EndMessage;
// add the object alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "alive";
for (std::list<TuioBlob*>::iterator tuioBlob = blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++)
(*fullPacket) << (int32)((*tuioBlob)->getSessionID());
(*fullPacket) << osc::EndMessage;
for (std::list<TuioBlob*>::iterator tuioBlob = blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++) {
// start a new packet if we exceed the packet capacity
if ((fullPacket->Capacity()-fullPacket->Size())<BLB_MESSAGE_SIZE) {
// add the immediate fseq message and send the object packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
// prepare the new blob packet
fullPacket->Clear();
(*fullPacket) << osc::BeginBundleImmediate;
if (source_name) (*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "source" << source_name << osc::EndMessage;
// add the blob alive message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "alive";
for (std::list<TuioBlob*>::iterator tuioBlob = blobList.begin(); tuioBlob!=blobList.end(); tuioBlob++)
(*fullPacket) << (int32)((*tuioBlob)->getSessionID());
(*fullPacket) << osc::EndMessage;
}
float xpos = (*tuioBlob)->getX();
float xvel = (*tuioBlob)->getXSpeed();
if (invert_x) {
xpos = 1 - xpos;
xvel = -1 * xvel;
}
float ypos = (*tuioBlob)->getY();
float yvel = (*tuioBlob)->getYSpeed();
if (invert_y) {
ypos = 1 - ypos;
yvel = -1 * yvel;
}
float angle = (*tuioBlob)->getAngle();
float rvel = (*tuioBlob)->getRotationSpeed();
if (invert_a) {
angle = 2.0f*(float)M_PI - angle;
rvel = -1 * rvel;
}
// add the actual blob set message
(*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "set";
(*fullPacket) << (int32)((*tuioBlob)->getSessionID()) << xpos << ypos << angle << (*tuioBlob)->getWidth() << (*tuioBlob)->getHeight() << (*tuioBlob)->getArea();
(*fullPacket) << xvel << yvel << rvel << (*tuioBlob)->getMotionAccel() << (*tuioBlob)->getRotationAccel();
(*fullPacket) << osc::EndMessage;
}
// add the immediate fseq message and send the blob packet
(*fullPacket) << osc::BeginMessage( "/tuio/2Dblb") << "fseq" << -1 << osc::EndMessage;
(*fullPacket) << osc::EndBundle;
deliverOscPacket( fullPacket );
}