OSC通信
こんにちは。muchoです。もうすぐお花見のシーズンですね。
さてさて、cinderにはフルスクリーンになる機能があるんですが、
プロジェクターや別のモニターでフルスクリーンにして、
手元のPCでフルスクリーン画面の方をコントロールしたい!
ということでアプリが2個になってしまうのですが、
描画プログラムとパラメーターを制御するプログラムと分割してみました。
OSCはデフォルトのままでは動かないので、blocks以下にライブラリを入れてください。
ライブラリはこちらから
https://github.com/cinder/Cinder/tree/master/blocks/osc
追加リンカファイル
$(CINDER_PATH)/blocks/osc/lib/macosx/osc.a
追加インクルード
$(CINDER_PATH)/blocks/osc/include
OSCでの通信は以下のデータを使います。
・送信先(IPアドレス)
・ポート
・アドレス(変数名のようなもの)
・値の型(int,float,stringのいずれか)
・値
以下の抜粋サンプルではアドレスをプログラムの固有IDと変数名から生成するような
形にしてます。
[code lang="cpp"]
//-----------------------------------------------------
// senderApp
#include "OscSender.h"
class senderAPP : public AppBasic {
public:
void setup();
void update();
void sendString(string address, vector arg);
void sendInt(string address, vector arg);
void sendFloat(string address, vector arg);
osc::Sender sender;
std::string host;
std::string prefix;
int port;
};
void senderAPP::setup()
{
host = "localhost";
prefix = "/devjam_osc";
port = 3000;
sender.setup(host, port);
}
void senderApp::update()
{
sendFloat("quat", wxyz);
sendFloat("colora", rgba);
sendFloat("position", xyz);
}
void senderApp::sendString(string address, vector arg)
{
osc::Message message;
message.setRemoteEndpoint(host, port);
message.setAddress(prefix + "/" + address);
for(int i = 0; i < arg.size(); i++){
message.addStringArg(arg[i]);
}
sender.sendMessage(message);
}
void senderApp::sendInt(string address, vector arg)
{
osc::Message message;
message.setRemoteEndpoint(host, port);
message.setAddress(prefix + "/" + address);
for(int i = 0; i < arg.size(); i++){
message.addIntArg(arg[i]);
}
sender.sendMessage(message);
}
void senderApp::sendFloat(string address, vector arg)
{
osc::Message message;
message.setRemoteEndpoint(host, port);
message.setAddress(prefix + "/" + address);
for(int i = 0; i < arg.size(); i++){
message.addFloatArg(arg[i]);
}
sender.sendMessage(message);
}
//-----------------------------------------------------
// listenerApp
#include "OscListener.h"
class listenerApp : public AppBasic {
public:
void prepareSettings( Settings *settings );
void setup();
void update();
osc::Listener listener;
std::string prefix;
};
void listenerApp::prepareSettings( Settings *settings )
{
settings->enableSecondaryDisplayBlanking( false );
}
void listenerApp::setup()
{
prefix = "devjam_osc";
listener.setup(3000);
}
void listenerApp::update()
{
while (listener.hasWaitingMessages()) {
osc::Message message;
listener.getNextMessage(&message);
string adr = message.getAddress();
vector substrings = split(adr, "/");
if(substrings[0] == prefix){
if(substrings[1] == "quat") {
float qw = message.getArgAsFloat(0);
float qx = message.getArgAsFloat(1);
float qy = message.getArgAsFloat(2);
float qz = message.getArgAsFloat(3);
Quaternion oscQuat = Quaternion(qw, qx, qy, qz);
}
if(substrings[1] == "colora") {
float vr = message.getArgAsFloat(0);
float vg = message.getArgAsFloat(1);
float vb = message.getArgAsFloat(2);
float va = message.getArgAsFloat(3);
ColorA oscColor = ColorA(vr, vg, vb, va);
}
if(substrings[1] == "position") {
float px = message.getArgAsFloat(0);
float py = message.getArgAsFloat(1);
float pz = message.getArgAsFloat(2);
Vec3f oscPos = Vec3f(px, py, pz);
}
}
}
}
[/code]
そして・・・できたサンプルがこちら左が送信側プログラム、右が受信側です。


にしてもインターフェースを作るにはcinderは不向きなので、
コントローラー側はflashで作ろうと思います。