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, vectorarg); 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で作ろうと思います。