1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

スマートシティ開発に使えるかもしれないWebSDKの話

Last updated at Posted at 2024-03-04

はじめに

防災や観光など都市開発などをテーマとした場合の開発手法を色々と試しています。
様々な要件定義によっていろいろな開発手法が考えられますが、自身が受ける案件の中でよく挙げられる点は、

「VRやARなどに対応したい、高齢者や子供でも簡単に使えるようにしたい、開発の予算はない」

といったものです。

こうした要件の中で、最近、試しているのが、「ブラウザアプリ」による開発です。

アプリ開発の場合は、UnityやFlutterなどOSの違いを吸収してくれるSDKもありますが、
iOSの場合などはTestFlightの使い方などを習得する必要がある点や、仮に貸出用のスマートフォンなどを手配した場合、キッティングにかかる時間も多いため、ちょっとしたものをサクッと提供する場合には、ブラウザアプリの提供が欠かせません。

侮る事なかれブラウザゲームの現状

WebAssembly(通称Wasm)は、ブラウザゲームの開発に革命をもたらした技術の一つです。WebAssemblyは、ウェブブラウザで実行可能な低レベルのバイナリフォーマットです。これにより、C、C++、Rustなどの言語で書かれたコードをウェブブラウザで実行することが可能になります。WebAssemblyはJavaScriptよりも高速に実行できるため、ウェブアプリケーションやゲームにおいて、より複雑な計算や高度なグラフィックス処理が求められる場合に特に有用です。

ワークショップなどで活用することのできるブラウザSDK

0->1でのものづくりの際には、ゲームエンジンの活用が欠かせません。ゲームエンジンはグラフィックスのレンダリング、物理演算、音声、スクリプティング、アニメーション、人工知能、ネットワーキングなど、ゲーム開発に必要な多くの機能やコンポーネントを提供します。ゲームエンジンは、開発者がゼロから全てをコーディングする代わりに、これらの準備された機能を使用して、ゲームの独自の要素やロジックに集中できるように設計されています。

今回はブラウザをテーマとしているので、ブラウザ開発によく用いられるゲームエンジンをご紹介します。
Babylon.js(microsoft)、three.js、Cesium、Filament (google)

今回は、地図などを主体とした仕組みでの活用が想定されるCesiumと、
汎用的なMicrosoft社のBabylonの2つをテーマとして簡単な仕組みを提供する流れを作りたいと思います。

1.Hostingサーバーの準備

何をやるにも、まずはサーバーの準備が必要です。
自分のローカルマシンで立ち上げてlocalhostでアクセスする方法もありますが、
作ったものを誰かに見てもらうということが大事、ということで、今回はGlitchと呼ばれるホスティングサーバーをご紹介しいます。

Hostingサーバーの準備

Glichにアクセス
https://glitch.com/signin

右上のNew Projectを押下する

スクリーンショット 2024-03-05 8.30.04.png

glitch-hello-websiteを押下する

スクリーンショット 2024-03-05 8.30.11.png

左のファイルリストからindex.htmlを押下して、プログラミングをしよう

スクリーンショット 2024-03-05 8.30.40.png

右上のShareを押下して、LivesiteのURLをコピーして、誰かに見てもらおう

スクリーンショット 2024-03-05 8.31.57.png

2.Cesiumを使ってみよう

2-0.GlichのAssetsに下記の3Dモデルを読み込んでみてください。

スクリーンショット 2024-03-05 8.30.58.png

読み込んだ後、CopyURLを押下してリンクをコピーしよう

スクリーンショット 2024-03-05 8.31.05.png

2-1.Glichのindex.htmlに下記のコードをペーストしてみてください。

ソースコードをコピーする

スクリーンショット 2024-03-11 20.09.09.png

コンテンツを追加したい場合は、表示したい地図の座標をGoogleMapで調べよう

スクリーンショット 2024-03-11 15.09.59.png

簡単な内容

      var target = viewer.entities.add({
        name : 'かわまちてらす閖上',
        // 緯度経度
        position: Cesium.Cartesian3.fromDegrees(140.94808025489982,38.17948338366141),
        point: {
          pixelSize: 16,
          color: Cesium.Color.YELLOW
        },
        label : {
          text: 'かわまちてらす閖上',
          font: 'bold 12pt Hiragino Maru Gothic ProN',
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 10,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -16)
        }
      });

function createModel(lon,lat,h, url) {
  var position = Cesium.Cartesian3.fromDegrees(lon,lat,h);
  var heading = Cesium.Math.toRadians(150);
  var pitch = Cesium.Math.toRadians(0);
  var roll = Cesium.Math.toRadians(0);
  var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  var orientation = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr
  );
  var entity = viewer.entities.add({
    name: url,
    position: position,
    orientation: orientation,
    model: {
      uri: url,
      scale: 100,
    },
  });
}
createModel(140.94808025489982,38.17948338366141, 10, "./models/kaisendon.glb");

2-3.Sandcastleをみてみる

Cesium には、CesiumJS の機能を試すことができるインタラクティブな環境として、Cesium Sandcastle というものが用意されています。コードを書き換えるだけでサンプルに手を加えることが可能となっています。

3.Babylonを使ってみよう

2-0.GlichのAssetsに下記の3Dモデルを読み込んでみてください。

スクリーンショット 2024-03-05 8.30.58.png

読み込んだ後、CopyURLを押下してリンクをコピーしよう

スクリーンショット 2024-03-05 8.31.05.png

2-1.Glichのindex.htmlに下記のコードをペーストしてみてください。

3-e.完成イメージ

スクリーンショット 2024-03-06 12.36.51.png

3-e.コード開設

シーンを作成して、重力と衝突を発生させる

        var scene = new BABYLON.Scene(engine);
        scene.enablePhysics();
        scene.checkCollisions = true;
        scene.collisionsEnabled = true;
        scene.collisionEnabled = true;
        scene.gravity = new BABYLON.Vector3(0, -9.81, 0);

ライトとカメラ、地面を作って準備

        var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 2, -20), scene);
        camera.setTarget(BABYLON.Vector3.Zero());
        camera.attachControl(canvas, true);
        camera.checkCollisions = true;
        camera.applyGravity = true;
        camera.ellipsoid = new BABYLON.Vector3(2, 2, 2);
        camera.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5);
        camera.attachControl(canvas, true);
        camera.speed = 0.3;
        var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
        light.intensity = 0.8;
var ground = BABYLON.Mesh.CreateGround("ground1", 1000, 1000, 2, scene);
        ground.receiveShadows = true;
        ground.checkCollisions = true;
        ground.physicsImpostor = new BABYLON.PhysicsImpostor(ground, BABYLON.PhysicsImpostor.BoxImpostor, {
          mass: 0,
          friction: 0.7,
          restitution: 1.5,
        }, scene);

海鮮丼を剛体にする

          BABYLON.SceneLoader.ImportMeshAsync("", "./gltf/", "kaisendon.glb").then((result) => {
            var box3 = BABYLON.Mesh.CreateBox("crate", 2, scene);
            box3.position = new BABYLON.Vector3(0, 30, 0); 
            box3.checkCollisions = true;
            box3.applyGravity = true;
            box3.showBoundingBox = true;
            box3.visibility = 0;
            //質量や摩擦係
            box3.physicsImpostor = new BABYLON.PhysicsImpostor(box3, BABYLON.PhysicsImpostor.BoxImpostor, {
              mass: 2,
              restitution: 0,
              friction: 1,
            }, scene);
            result.meshes[0].scaling.x = 20;
            result.meshes[0].scaling.y = 20;
            result.meshes[0].scaling.z = 20;
            result.meshes[0].position = new BABYLON.Vector3(0, 29, 0);
            box3.addChild(result.meshes[0]);
          });

ボタンを作ろう

        let advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI");
        var button1 = BABYLON.GUI.Button.CreateSimpleButton("but1", "kaisendon");
        button1.width = "150px"
        button1.height = "40px";
        button1.color = "white";
        button1.cornerRadius = 20;
        button1.background = "black";
        button1.onPointerUpObservable.add(function () {
          addObject();
        });
        advancedTexture.addControl(button1);

3Dデータを自分で作ってみよう

事前にscanierseやlumaaiなどで撮影したデータを.glbファイルに変換させて利用する準備をしよう。

撮影したデータをGLTFでダウンロード

スクリーンショット 2024-03-06 12.29.16.png

スクリーンショット 2024-03-06 12.29.25.png

または、こちらで用意したサンプルデータをダウンロードできます

ダウンロードした.glbファイルをビューアーを用いることで立体的にみることができます。
https://gltf-viewer.donmccurdy.com/

VRにも対応できる

VR対応
https://www.youtube.com/watch?v=OqA8Xr3Njaw

電車走行(3画面分割)
https://oggata.github.io/train-demo/

動物パズル
https://oggata.github.io/animalmashup/

マップを探索するサンプル
https://playground.babylonjs.com/#0VHCTL#32

スケートボード
https://playground.babylonjs.com/#XMEL56#7

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?