Babylon.jsで空を自由に飛びたいな


はい。タケコプタ○。

・Granage | HollowCradle
http://hollowcradle.cf/granage/index.html

というわけで、今回はタイトル通りBabylon.jsを使って空を飛んで見ようと思いました。
そしてお試し頂けた通り、見事空を飛ぶことが出来ました。

ちょいちょい変なところで引っかかったりして、2日潰しちゃいましたけど、何とか完成してよかったです。


もうちょっと高速に飛ぼうか迷いましたが、スマホを考えるとこれくらいが良いのかなと。
スマホのモニターじゃちょっとサイズ的にも画質的にも物足りない感ありますけど、PCだと想像以上に気持ちいいです。

VRだともっと気持ちいいんでしょうね。
Babylon.jsはVRも作れるらしいので、機会があればやってみたいものです。


Babylon.js楽しい。
っていうか、世界作るの楽しい。

もっともっと色んな世界を作れるようになりたいと思った2日間でございました。




今回のソースコード。


HTML
<body>
<canvas id='canvas' oncontextmenu="return false;">This Browser Not Support <code>canvas</code> Element</canvas>
<script src='https://preview.babylonjs.com/babylon.js'></script>
<script src='https://code.jquery.com/pep/0.4.1/pep.js'></script>
</body>

CSS
html, body{
    width:100%;
    height:100%;
    overflow:hidden;
}

#canvas{
    touch-action: none;
}

Javascript
if (BABYLON.Engine.isSupported()) {
    const canvas = document.getElementById('canvas');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    let speed = 5;

    let is_mobile = false;
    let ua = navigator.userAgent;

    if (ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0) {
        is_mobile = true;
    }

    function create_scene(engine) {
        let scene = new BABYLON.Scene(engine);

        let camera = set_camera(is_mobile, scene);

        camera.attachControl(canvas, true);

        let light = new BABYLON.PointLight('Omni', new BABYLON.Vector3(5000, 2600, -5000), scene);

        let lens_flare_system = new BABYLON.LensFlareSystem('LensFrareSystem', light, scene);
        let flare0 = new BABYLON.LensFlare(0.2, 0, new BABYLON.Color3(1, 1, 1), 'img/lens5.png', lens_flare_system);
        let flare1 = new BABYLON.LensFlare(0.5, 0.2, new BABYLON.Color3(0.5, 0.5, 1), 'img/lens4.png', lens_flare_system);
        let flare2 = new BABYLON.LensFlare(0.2, 0.1, new BABYLON.Color3(1, 1, 1), 'img/lens4.png', lens_flare_system);
        let flare3 = new BABYLON.LensFlare(0.4, 0.4, new BABYLON.Color3(1, 0.5, 1), 'img/Flare.png', lens_flare_system);
        let flare4 = new BABYLON.LensFlare(0.1, 0.6, new BABYLON.Color3(1, 1, 1), 'img/lens5.png', lens_flare_system);
        let flare5 = new BABYLON.LensFlare(0.3, 0.8, new BABYLON.Color3(1, 1, 1), 'img/lens4.png', lens_flare_system);

        for (let i = 0; i < 10; i++) {
            create_sky_sphere(`skysphere${i}`, scene);
        }

        let skybox0 = BABYLON.Mesh.CreateSphere('skybox0', 16, 4000.0, scene);
        skybox0.rotation.y = Math.PI * 1.6;
        let skybox0_material = new BABYLON.StandardMaterial('skybox0', scene);
        skybox0_material.backFaceCulling = false;
        skybox0_material.reflectionTexture = new BABYLON.CubeTexture('img/TropicalSunnyDay/TropicalSunnyDay', scene);
        skybox0_material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
        skybox0_material.disableLighting = true;
        skybox0.material = skybox0_material;

        let skybox1 = BABYLON.Mesh.CreateSphere('skybox1', 16, 10000.0, scene);
        let skybox1_material = new BABYLON.StandardMaterial('skybox1', scene);
        skybox1_material.backFaceCulling = false;
        skybox1_material.reflectionTexture = new BABYLON.CubeTexture('img/cloudylightrays/CloudyLightRays', scene);
        skybox1_material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
        skybox1_material.disableLighting = true;
        skybox1.material = skybox1_material;

        let ground_texture = new BABYLON.Texture('img/Ground.jpg', scene);
        ground_texture.vScale = ground_texture.uScale = 2.0;
        let ground_material = new BABYLON.StandardMaterial('groundMaterial', scene);
        ground_material.diffuseTexture = ground_texture;
        let ground = BABYLON.Mesh.CreateGround('ground', 1028, 1028, 32, scene, false);
        ground.position.y = -1;
        ground.material = ground_material;

        let camera_euler = new BABYLON.Vector3();

        if(is_mobile){
            scene.registerBeforeRender(function () {
                camera_euler = camera.rotationQuaternion.toEulerAngles();
                camera.position.x += speed * Math.sin(camera_euler.y);
                camera.position.y -= speed * Math.sin(camera_euler.x);
                camera.position.z += speed * Math.cos(camera_euler.y);
            });
        }else{
            scene.registerBeforeRender(function () {
                camera.position.x += speed * Math.sin(camera.rotation.y);
                camera.position.y -= speed * Math.sin(camera.rotation.x);
                camera.position.z += speed * Math.cos(camera.rotation.y);
            });    
        }

        return scene;
    }

    function set_camera(flag_mobile, scene) {
        if (flag_mobile) {
            let camera = new BABYLON.DeviceOrientationCamera('DCamera', new BABYLON.Vector3(0, 10, 0), scene);
            return camera;
        }
        else{
            let camera = new BABYLON.TouchCamera('Camera', new BABYLON.Vector3(100, 100, 100), scene);
            return camera;
        }
    }

    function create_sky_sphere(name, scene) {
        let skysphere = BABYLON.Mesh.CreateSphere(name, 10, Math.floor(Math.random() * 300), scene);
        skysphere.position = new BABYLON.Vector3(1200 - Math.floor(Math.random() * 2400), 1200 - Math.floor(Math.random() * 2400), 1200 - Math.floor(Math.random() * 2400));
        let skysphere_material = new BABYLON.StandardMaterial(name, scene);
        skysphere_material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
        skysphere_material.alpha = 0.5;
        skysphere.material = skysphere_material;
    }

    function init() {
        let engine = new BABYLON.Engine(canvas, true);
        window.addEventListener('resize', function () {
            engine.resize();
        })

        let scene = create_scene(engine);

        engine.runRenderLoop(function () {
            scene.render();
        });

        // scene.debugLayer.show();
    }

    init();
}



Babylon.jsについては以下参照。


公式ドキュメント。

・Babylon.js Documentation
https://doc.babylonjs.com/


ソースコードを見れて、いじれる公式サンプル集。

・EXAMPLES | Babylon.js
https://doc.babylonjs.com/examples/


Babylon.jsのGitHubページ。

・Babylon.js · GitHub
https://github.com/BabylonJS


この中にはAssetsが置いてたりします。

・Website/Assets at master · BabylonJS/Website · GitHub
https://github.com/BabylonJS/Website/tree/master/Assets


その他参考。

・Positioning,Rotating,Scaling | Babylon.js
https://doc.babylonjs.com/features/position,_rotation,_scaling

・DevidceOrientationCamera | Babylon.js Playground
http://www.babylonjs-playground.com/#AOYVP

・Control camera with mobile - Questions & Answers - HTML5 Game Devs Forum
http://www.html5gamedevs.com/topic/24592-control-camera-with-mobile/

・Android の Chrome で開発者ツールを使う方法
https://qiita.com/hojishi/items/12b726f8b02ef3d713e4

・Rotation Values of DeviceOrientationCamera - Questions & Answers - HTML5 Game Devs Forum
http://www.html5gamedevs.com/topic/29921-rotation-values-of-deviceorientationcamera/


今回も色んなサイトにお世話になりました。
この場にてお礼を申し上げます。

ありがとうございました。
また誰かの助けとなりますように。


コメント