gl.enchant.js を使ってプリミティブビューアーを作ってみた

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

gl.enchant.js と一緒に配布されている primitive.gl.enchant.js で定義されているプリミティブを表示する プリミティブビューアーを作りました.

プログラムはダウンロードできるようにしてあるので, 開発の参考にしていただければ幸いです.

sample-img

Sample And Download

今回制作したビューアはこちらから見れます.

プリミティブ名へのリンクをクリックするとそのプリミティブが表示されます.

また, ビューアー自体は, クエリ文字列(url の ?~)で指定した名前のプリミティブを表示するように作っています. なので, Sprite3D を継承しているオブジェクトであれば ユーザー定義のモデルでも表示可能です.

キーボード, マウス, タッチでオブジェクトを回転させることができます. ジンバルロック対応はしていません. glMarix.js がクォータニオングがサポートしていたので気が向いたらちゃんと置き換えます.

ダウンロードはこちらからできます.

Code

今回制作したビューアの全体コードです.

<!DOCTYPE html>

<html>
    
    <head>
        <meta charset="UTF-8">
        <title>gl.enchant.js - Primitive Viewer</title>
        <style>
            * {
                margin: 0px;
                padding: 0px;
            }
        </style>
        <script type="text/javascript" src="../js/gl.enchant.js/glMatrix-0.9.5.min.js"></script>
        <script type="text/javascript" src="../js/gl.enchant.js/enchant.js"></script>
        <script type="text/javascript" src="../js/gl.enchant.js/gl.enchant.js"></script>
        <script type="text/javascript" src="../js/gl.enchant.js/primitive.gl.enchant.js"></script>
        <script>
            // おまじない
            enchant();
            
            window.onload = function() {
                var game = new Game(640, 640);
                game.fps = 60;
                game.keybind(90, 'a');// z
                game.keybind(88, 'b');// x
                
                // プリミティブ名を取得
                var prim_name   = document.location.search.substr(1); // search の値をプリミティブ名として使う
                var prim_type   = window[prim_name];
                if (!prim_type) {
                    alert("おいおい, '" + prim_name + "' なんて名前のプリミティブは存在しないぜ! 今回はとりあえず 'Cube' を表示しておくが次からは気をつけてくれよな!!");
                    prim_type = window["Cube"];
                }
                
                game.onload = function() {
                    // 3D 用シーン生成
                    var scene = new Scene3D();
                    
                    // ライト生生
                    var light = new DirectionalLight(); // 平行光源生成
                    light.directionZ =-1;               // 向き
                    light.color = [1.0, 1.0, 1.0];      // 色
                    scene.setDirectionalLight(light);   // scene にセット
                    
                    // カメラ生成
                    var camera = new Camera3D();                                // カメラ生成
                    camera.x = 0; camera.y = 5; camera.z = -10;                 // カメラ位置をセット
                    camera.centerX = 0; camera.centerY = 0; camera.centerZ = 0; // 注視点をセット
                    scene.setCamera(camera);                                    // scene にセット
                    
                    // 床生成
                    var floor = new Plane();                        // 板ポリ生生
                    floor.x = 0; floor.y = -2; floor.z = 0;         // 位置をセット
                    mat4.rotateX(floor.rotation, -90*Math.PI/180);  // 90度回転
                    floor.scale(10, 10, 10);                        // 200 倍
                    floor.mesh.setBaseColor("#ff4444");             // 床の色を変更
                    scene.addChild(floor);                          // scene にセット
                    
                    // プリミティブ生成
                    var prim = new prim_type();     // プリミティブ生成
                    prim.x = prim.y = prim.z = 0;   // 位置をセット
                    scene.addChild(prim);           // scene にセット
                    
                    // モデルを回転
                    var phi   = 0;      // X軸回転値
                    var theta = 0;      // Y軸回転値
                    var offsetX = 0;    // touch の offsetX
                    var offsetY = 0;    // touch の offsetY
                    var matrix = new mat4.create(); // 回転行列用マトリックスバッファ
                    
                    // タッチイベント登録
                    game.rootScene.addEventListener("touchstart", function(e) {
                        offsetX = e.x;
                        offsetY = e.y;
                    });
                    game.rootScene.addEventListener("touchmove", function(e) {
                        // タッチによる回転
                        theta += (e.x -offsetX) / 160;  // 差分/160だけ回転
                        offsetX = e.x;
                        phi += (e.y - offsetY) / 160;   // 差分/160だけ回転
                        offsetY = e.y;
                    });
                    
                    // 更新イベント登録
                    game.rootScene.addEventListener("enterframe", function(e)
                    {
                        var input = game.input;
                        
                        // 十字キーによる回転
                        if (game.input.up)    { phi -= 0.05; }
                        if (game.input.down)  { phi += 0.05; }
                        if (game.input.right) { theta += 0.05; }
                        if (game.input.left)  { theta -= 0.05; }
                        
                        // Y軸, X軸回転行列を作成
                        mat4.identity(matrix);          // 単位行列化
                        mat4.rotateY(matrix, theta);    // Y軸回転
                        mat4.rotateX(matrix, phi);      // X軸回転
                        // 回転行列をセット
                        prim.rotation = matrix;
                    });
                };
                
                game.start();
            };
        </script>
    </head>
    <body>
        <h1>gl.enchant.js - Primitive Viewer</h1>
    </body>
</html>

次回は, ウォークスルー(3D空間を動きまわるやつ)のサンプルを作ったのでそれについてのエントリーを書きます.

ちなみにこんなのです. 十字キーで移動, スペースキーで視点切り替え.

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT