cluster OSCHandleを使用して、照明エフェクトを制御する(サンプルあり)
clusterにとうとうOSCが実装されました。
今回は照明エフェクトをOSCで制御してみたのでOSCのちょっとした説明と、作ったスクリプトの紹介です。音楽系イベントなどでぜひ使ってみてください。まずはOSCを受信してみる
まずはシンプルにOSCを受信して、ログに出力してみましょう。ドキュメントにサンプルスクリプトが載っています。
このスクリプトをPlayerScriptに設定し、
_.oscHandle.onReceive(messages => {
const lines = [];
messages.forEach((message, i) => {
const { address, timestamp, values } = message;
lines.push(`== message [${i + 1}/${messages.length}]`);
lines.push(`address: ${address}`);
lines.push(`timestamp: ${new Date(timestamp).toLocaleString()}`);
values.forEach((value, j) => {
lines.push(`= value [${j + 1}/${values.length}]`);
lines.push(`getInt(): ${value.getInt()}`);
lines.push(`getFloat(): ${value.getFloat()}`);
lines.push(`getAsciiString(): ${value.getAsciiString()}`);
lines.push(`getBlobAsUint8Array(): ${value.getBlobAsUint8Array()}`);
lines.push(`getBlobAsUtf8String(): ${value.getBlobAsUtf8String()}`);
lines.push(`getBool(): ${value.getBool()}`);
});
});
_.log(lines.join("\n"));
});
同じオブジェクトのScriptable Itemでは以下のコードでPlayerScriptをインタラクトしたプレイヤーにセットします。
$.onInteract((playerHandle) => {
$.setPlayerScript(playerHandle);
});
QLC+からOSCを送信する
今回はOSCを送信するソフトウェアとして、QLC+を使用します。
以下の手順でOSCを送信できるように設定します。- QLC+を開いて、画面下のタブから
Input/Outputs (入力/出力設定)
を開く - OSCの出力先にするIPアドレスのOSC欄の
Output (出力)
にチェックを入れる
- スパナとドライバーのボタンからOSCプラグイン設定を開き、
Output Address
にOSCの出力先にするIPアドレスを設定し、Output Port
に9000
を設定する
先ほどの受信したOSCメッセージをログに出力するサンプルスクリプトを、ワールドにアップロードしてそのオブジェクトをインタラクトします。これでインタラクトしたユーザーのPCでOSCが受信状態になります。
QLC+では画面下のタブからSimple Desk(シンプル卓)を開き、1~512番までのフェーダーを操作することで、OSCメッセージが送信され、OSCメッセージの内容がログに出力されるはずです。
OSCってなに?
まずはOSCの仕組みについて知っておきましょう。UDP通信の方式で、以下のような構造のデータをやり取りします。
/address/0 int:255 float:0.5
OSCではアドレス、数値の型と数値の3つのメッセージがやりとりされ、一つのアドレスで複数の数値を送信することも可能です。このような構造をOSCメッセージと呼びます。
cluster scriptでOSCを使用する
まずclusterスクリプトでOSCを受信するには、Playerスクリプト上でoscHandle.onReceive
を呼び出して使用します。
_.oscHandle.onReceive(messages => {
});
コールバックで渡されるmessages
に、受信されたOSCメッセージが配列で渡されます。(配列で複数の)
次のように取得されたmessagesからOSCメッセージをひとつづつ取得して、アドレスごとに処理を分岐することができます。
_.oscHandle.onReceive(messages => {
messages.forEach((message, i) => {
switch (message.address) {
case "/light/intensity:
// ここに/light/intensityのOSCメッセージが受信されたときの処理
break;
case "/light/color":
// ここに/light/colorのOSCメッセージが受信されたときの処理
break;
default:
break;
}
});
});
message.values
でOSCメッセージに含まれる値の配列を取得できます。
values
の配列の中に含まれるそれぞれの要素から値を取得するには、取得する値の型に応じた関数を使用する必要があります。
_.oscHandle.onReceive(messages => {
messages.forEach((message, i) => {
switch (message.address) {
case "/light/intensity:
message.values.forEach((value, j) => {
// ここで、それぞれの値を取り出す処理などを書く
$.log(value.getFloat()); // valueをFloatとして取得
});
break;
...
}
});
});
受信したOSCメッセージは、sendToでほかのアイテムに送信できます。
_.sendTo(itemHandle, "intensity", message.values[0].getFloat());
受信側のスクリプトはこのようになります。
$.onReceive((messageType, arg, sender) => {
switch (messageType) {
case "intensity":
$.log(arg); //OSCを受信して送信されたメッセージintensityの値をログに出力
break;
default:
break;
}
}, { player: true });
サンプルプロジェクト
改変など自由にご利用下さい。
サンプルプロジェクトの構成
ClusterOscLighting/
├─ Materials/
├─ Scenes/
│ ├─ QlcSampleScene `QLC+によるDMXサンプル`
│ ├─ S2lSampleScene `Sound2Lightによるオーディオリアクティブサンプル`
├─ Scripts/
│ ├─ qlc/
│ │ ├─ qlcListner_player.js `QLC+からのOSCを受信するPlayerスクリプト`
│ │ ├─ qlcMaterial_item.js `qlcListnerからのOSCをマテリアルに反映するItemスクリプト`
│ ├─ s2l/
│ │ ├─ s2lListner_player.js `Sound2LightからのOSCを受信するPlayerスクリプト`
│ │ ├─ s2lMaterial_item `s2lListner_playerからのOSCをマテリアルに反映するItemスクリプト`
│ ├─ attachOscListner_item.js `PlayerスクリプトをプレイヤーにセットするためのItemスクリプト`
QlcSampleScene
QLC+でビームライトの色、明るさをコントロールするサンプルです。
アップロードし、ボタンを押してOSC受信状態にすることで、シンプル卓からR,G,B,Intensityの順でコントロールが可能です。
(QLC+の詳細な使い方は割愛しますが、個々の工夫次第ではとても細かなステージ演出が可能になります)
S2lSampleScene
Sound2Lightでマイク入力から入力されたオーディオをリアルタイムに分析し、4つの周波数帯域でビームライトを点滅させるサンプルです。
Sound2Lightのセットアップ
Sound2Lightを開き、画面左中央のSettingsを開き、以下に設定を変更します。
項目 | 設定値 |
---|---|
OSC IP Address | OSCの出力先アドレス |
OSC Protcool | UDP |
OSC UDP Tx Port | 9000 |
OSC UDP Rx Port | 無視 |
Console Type | 無視 |
Input | ソースにする音源があ流れる音声デバイス |
画面下のOSC Messageの列で、左からChannnelNumberをChannnel 1
Channel 2
の順に設定し、それぞれのModeをLevel
に設定してください。
サンプルをアップロードして、ボタンを押してOSC受信状態にしたうえで音楽を再生することで音楽に合わせて照明が点滅するはずです。
Discussion