SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

JavaScriptとWebGLによるはじめての3Dプログラミング

「three.js」でつくるお手軽3Dマンガ作成ソフト - 中編

JavaScriptとWebGLによるはじめての3Dプログラミング(2)

ダウンロード サンプル (335.2 KB)

クォータニオンによる回転

クォータニオンによる回転
クォータニオンによる回転

 3Dプログラミングで回転状態を表現する方法には、「オイラー角」と「クォータニオン」(四元数)があります。「オイラー角」はXYZの3次元で向きを表す方法で、「クォータニオン」はその名のとおり、4つの値で向きを表す方法です。

 オイラー角は、人間が直観的に分かりやすい3軸で回転状態を表します。しかし、ある回転状態から、別の回転状態に移行する際の計算が大変です。クォータニオンは、人間には理解しにくい表現ですが、同じような計算をする際に、簡単に計算を行うことができます。

 また、オイラー角では、XYZの3軸が重なってしまった際に、回転の制御に難が生じる「ジンバルロック」という状態に陥ります。しかし、クォータニオンでは、そういった問題は生じません。

 「three.js」のデフォルトの回転系はオイラー角です。しかし、3Dオブジェクトの「useQuaternion」属性を「true」にすることで、クォータニオンで回転制御を行えるようになります。この場合に注意が必要な点は、それ以降「rotation」属性を使用した回転の制御ができなくなってしまうことです。

 「rotation」は、オイラー角で回転状態を表すための属性です。クォータニオンを利用する場合は「quaternion」属性を利用します。「quaternion」属性には、「x」「y」「z」「w」という4つの値が用意されています。

 「three.js」では、このクォータニオンの計算を行ったり、オイラー角をクォータニオンに変換するための関数が用意されています。

 以下、クォータニオンによる回転を行う「crocro.bc.useQuaternion.js」を掲載します。

「crocro.bc.useQuaternion.js」
//= サンプル:クォータニオンによる操作

//== クォータニオンによる操作
crocro.bc.useQuaternion = function() {
    // 変数の初期化
    var d3 = crocro.bc.d3;    // 3D格納用

    // 要素の作成と格納
    var cube = crocro.bc.mkColCube();
    d3.scene.add(cube);

    // クォータニオンを使う(mesh.rotationは無視される)
    cube.useQuaternion = true;

    crocro.bc.render();

    // マウス操作の作成
    d3.tgt = cube;
    crocro.bc.useQuaternion_setMouse();

    // 終了処理
    crocro.bc.setFinalize(function() {
        crocro.bc.d3.tgt = null;
    })
};

//== マウス操作の作成
crocro.bc.useQuaternion_setMouse = function() {
    // 変数の初期化
    var d3 = crocro.bc.d3;    // 3D格納用
    var cntnr = crocro.bc.cntnr;    // コンテナー

    var isAct = false;
    var posX, posY;
    var rttVec = new THREE.Vector3(0, 0, 0);
    var rttQuat = new THREE.Quaternion();

    // マウス操作
    var msStrt = function(event) {
        isAct = true;    // 動作状態に移行

        // 位置の取得
        posX = event.pageX;
        posY = event.pageY;
    };
    var msMv = function(event) {
        // 動作状態でなければ終了
        if (! isAct) {return;}

        // 位置の取得
        var newX = event.pageX;
        var newY = event.pageY;

        // 回転ベクトルの作成
        var x = newY - posY;
        var y = newX - posX;
        var z = 0;
        rttVec.set(
            x * 2 * Math.PI / 360,
            y * 2 * Math.PI / 360,
            z * 2 * Math.PI / 360
        );

        // オイラー角からクォータニオンに変換
        rttQuat.setFromEuler(rttVec);

        // クォータニオンの合成
        d3.tgt.quaternion.multiply(rttQuat);    // 掛け算

        // 位置の更新
        posX = newX;
        posY = newY;

        // レンダリング
        crocro.bc.render();
    };
    var msEnd = function() {
        isAct = false;    // 動作状態を解除
    };

    // マウス操作の登録
    cntnr.mousedown(msStrt);
    cntnr.mousemove(msMv);
    cntnr.mouseup(msEnd);
    $(window).blur(msEnd);
}

 今回の記事は以上です。次回は応用編として、集中線やフキダシ、箱人形の作成、そしてそれらのオブジェクトや部品をまとめて、マウスで操作するサンプルを作成して解説します。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
JavaScriptとWebGLによるはじめての3Dプログラミング連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7209 2013/06/24 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー