SpaceNavigator を Flash で使う(Mac 編)


SpaceNavigator っていうデバイスがありまして。むかーし Google Earth をこれで操作しているムービーをみましてですね一度触ってみたいよねーと思っていたところ、前回の大阪てら子持ってきてた人がいまして。そんときは単に Google Earth で遊ぶだけで終わったんだけど、今回、この SpaceNavigator を Flash で使えるようにするライブラリ&サーバーを作ってきた人がいまして。Flash からは直接 SpaceNavigator には接続できないので Python でサーバーを書いてそれと XMLSocket で通信してごにょごにょみたいな。Spark project にコミットしてあるみたいなんだけど、どうやら Windows の DLL を呼び出しているらしく Mac では使えない。(追記:ブログ発見した。

んで、使えるようにした。

最近 OSCulator っていうアプリをいじくってまして(某書籍サンプル用に)。これはなにかというと OSC というプロトコルでメッセージを受信して MIDI 信号に変換したりキーボードとかマウス操作に変換したり、逆に Wii リモコンとか SpaceNavigator のセンサーの値を OSC メッセージとして送信したりできるソフト。そう SpaceNavigator に対応してるの。つまり Flash で OSC が受信できれば SpaceNavigator が Flash で使えるちゅーわけです。はーい、知ってる人は知っている、Flash で OSC といえば flosc。SpaceNavigator → OSCulator → flosc → Flash ってつなげてやるとようやく Flash で SpaceNavigator のコントローラーの値が取得できるというわけ。AS3 で flosc に接続するにはこのクラスを使う。AS3 のコードだけ書いてもあんまし意味ないけどこんな感じで値を受け取る。

package {

    import com.bit101.components.HUISlider;

    import flash.display.Sprite;
    import flash.events.Event;

    import it.h_umus.osc.OSCConnection;
    import it.h_umus.osc.OSCConnectionEvent;
    import it.h_umus.osc.OSCMessage;

    [SWF(backgroundColor=0x808080, frameRate=60)]

    public class SpaceNavigator extends Sprite {

        private var _conn:OSCConnection;

        private var _transX:HUISlider;
        private var _transY:HUISlider;
        private var _transZ:HUISlider;
        private var _rotX:HUISlider;
        private var _rotY:HUISlider;
        private var _rotZ:HUISlider;

        public function SpaceNavigator() {
            _conn = new OSCConnection();
            _conn.addEventListener(Event.CONNECT, _onConnection);
            _conn.connect('localhost', 3000);

            _transX = new HUISlider(this, 10, 10, 'Translate X');
            _transY = new HUISlider(this, 10, 30, 'Translate Y');
            _transZ = new HUISlider(this, 10, 50, 'Translate Z');
            _transX.minimum = _transY.minimum = _transZ.minimum = -1.0;
            _transX.maximum = _transY.maximum = _transZ.maximum = 1.0;
            _transX.labelPrecision = _transY.labelPrecision = _transZ.labelPrecision = 3;

            _rotX = new HUISlider(this, 10, 80, 'Rotation X');
            _rotY = new HUISlider(this, 10, 100, 'Rotation Y');
            _rotZ = new HUISlider(this, 10, 120, 'Rotation Z');
            _rotX.minimum = _rotY.minimum = _rotZ.minimum = -1.0;
            _rotX.maximum = _rotY.maximum = _rotZ.maximum = 1.0;
            _rotX.labelPrecision = _rotY.labelPrecision = _rotZ.labelPrecision = 3;
        }

        private function _onConnection(e:Event):void {
            _conn.addEventListener(OSCConnectionEvent.OSC_PACKET_IN, _onPacketIn);
        }

        private function _onPacketIn(e:OSCConnectionEvent):void {
            for each (var msg:OSCMessage in e.data.messages) {
                switch (msg.name) {
                    case '/sp/1/trans/xyz':
                        _transX.value = Number(msg.getArgumentValue(0));
                        _transY.value = Number(msg.getArgumentValue(1));
                        _transZ.value = Number(msg.getArgumentValue(2));
                        break;
                    case '/sp/1/rot/xyz':
                        _rotX.value = Number(msg.getArgumentValue(0));
                        _rotY.value = Number(msg.getArgumentValue(1));
                        _rotZ.value = Number(msg.getArgumentValue(2));
                        break;
                }
            }
        }
    }
}

半分ぐらいは値を表示するためのコードだな。まあ Mac でもすげえ簡単に SpaceNavigator つかえますよちゅーことで。SpaceNavigator はなかなかおもしろいデバイスなので Google Earth 探索以外になんかうまく使えるといいんだけどなー。このへんの話のもうちょい詳しい感じの解説が、来月発売される某書籍に掲載されてるので買ったらいいよっていう宣伝でした。ばいちゃ。