Qiita投稿3つ目の初心者です。よろしくお願いいたします。
前書き
弊社の地図ガチ勢上司より、OpenStreetMapの誕生日が本日8月9日なので、OpenStreetMapかつ地元観光資源で記事を書くのだフハハハハ…という話があり、今回の記事を書くに至りました。
OpenStreetMap
の誕生日ってなんだろうと思い調べてみると、 OpenStreetMap.org
のドメイン名取得の記念日とのことです。
参考:
Birthday - OpenStreetMap Wiki
Celebrate the 16th OSM anniversary!
OpenStreetMapさん、お誕生日おめでとうございます!
記事の内容としては、OpenStreetMap(OSM)の3DマップとA-Frameを使ってWebVRを作ってみたと同じようなことをしていきますが、osmファイルのファイルフォーマット変換に別のツールを使った方法があるので、それぞれの変換結果を比較して、どちらを使うか選択しようと思います。また、今回2つのマップモデルを一つの空間に設置するので、移動を簡単にするため瞬間移動ギミックを追加したWebVRを構築していこうと思います。
前提環境
- OS:Windows 10
- Webブラウザ:FireFox 55以降 記事中では78.0.2を使用
- Blender:2.8X 記事中では2.83.2を使用(今回は比較のための参照使用のみです)
1. OpenStreetMapから3Dマップデータを取得
取得方法の詳細はOpenStreetMap(OSM)の3DマップとA-Frameを使ってWebVRを作ってみたをご参照ください。
今回は、会津若松鶴ヶ城、飯盛山さざえ堂を取り出していきます。
1.1. 会津若松鶴ヶ城
1.2. 飯盛山さざえ堂
2. OSMファイルを変換
A-FrameではOSMファイルは直接読み込めないため、glTFファイルもしくはOBJファイルへ変換する必要があります。
※A-Frameの公式ドキュメントによると、glTFが推奨されています。理由としては、表現力が高いこと、アニメーションがつけれること…など。
参考:3D Models - A-Frame
2.1. OBJファイルとMTLファイルへ変換
OpenStreetMap公式から紹介されているOSM2Worldを使用して、OSMファイルからOBJファイルとMTLファイルへ変換が行えます。
OBJファイルがモデルの形状(ジオメトリ)情報を持ち、MTLファイルがモデル表面の色など質感(マテリアル)情報を持ちます。
2.1.1. OSM2Worldの使い方
OSM2World Downloadの0.2.0をダウンロードします。
ダウンロードしたZIPを解凍し、 OSM2World.jar
をダブルクリックで起動します。
OSM2World はJRE(Java Runtime Environment) 1.6 以降を必要とします。
とのことなので、起動できなかった場合はJREの導入をしましょう。
起動できた画面は下記です。
起動出来たら、上部メニューのFile>Open OSM fileからOSMファイルを開きます。読み込み完了まで少し時間がかかります。
上部メニューのFile>Export OBJ fileから保存先を指定すると、OBJファイルと同じフォルダに対応するMTLファイルが出力されます。出力完了まで少し時間がかかります。
2.2. Blenderアドオンで読み込んだものと比較
下記が、Blenderアドオン blender-osm
で読み込んだもの
※ blender-osm
の使用方法はOpenStreetMap(OSM)の3DマップとA-Frameを使ってWebVRを作ってみたをご参照ください。
下記が、 OSM2World
で変換したOBJ、MTLファイルを読み込んだもの
木が生えましたね。用途によって使い分けができそうです。
今回のようにVR観賞用としては、にぎやかな方がいいと思うので、 OSM2World
の結果を採用です。この前はglTFファイルの読み込みを行っていたので、今回はOBJファイルをそのまま使ってみます。
3. WebVRの構築
鶴ヶ城とさざえ堂の2つのマップモデルを読み込み、そのまま移動するのは大変なので、それぞれを瞬時に行き来できる瞬間移動ギミックを追加します。
3.1. HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, VR Aizu!</title>
<!-- aframe-extras requires 0.9.X aframe -->
<script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script>
<!-- https://github.com/donmccurdy/aframe-extras -->
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v6.1.0/dist/aframe-extras.min.js"></script>
<script src="script/teleport.js"></script>
</head>
<body>
<a-scene background="color: #EEEEEE">
<a-assets>
<a-asset-item id="shiro-obj" src="models/shiro.obj"></a-asset-item>
<a-asset-item id="shiro-mtl" src="models/shiro.obj.mtl"></a-asset-item>
<a-asset-item id="sazaedo-obj" src="models/sazaedo.obj"></a-asset-item>
<a-asset-item id="sazaedo-mtl" src="models/sazaedo.obj.mtl"></a-asset-item>
</a-assets>
<!-- light -->
<a-light color="#FFEEEE" position="-1 1 0"></a-light>
<a-light color="#333" type="ambient"></a-light>
<!-- objects -->
<a-entity id="shiro"
position="0 0 0"
rotation="0 0 0"
obj-model="obj: #shiro-obj; mtl: #shiro-mtl"
scale="1 1 1"
shadow="">
</a-entity>
<a-entity id="sazaedo"
position="0 60 -640"
rotation="0 0 0"
obj-model="obj: #sazaedo-obj; mtl: #sazaedo-mtl"
scale="1 1 1"
shadow="">
</a-entity>
<!-- movement control -->
<a-entity id="rig"
movement-controls
position="0 0 0">
<a-entity camera
position="0 1.6 0"
look-controls="pointerLockEnabled: true">
</a-entity>
<a-entity id="ctlL" laser-controls="hand: left"></a-entity>
<a-entity id="ctlR" laser-controls="hand: right"></a-entity>
</a-entity>
</a-scene>
</body>
</html>
index.html
のフォルダ階層に、 models
フォルダを作成し、上記で出力したOBJファイル、MTLファイルを入れています。同様にして script
フォルダを作成し、 teleport.js
ファイルを入れています。
3.2. JavaScriptコード
window.addEventListener('load', function (event){
const ctlL = document.getElementById("ctlL");
const ctlR = document.getElementById("ctlR");
const rig = document.getElementById("rig");
//Trigger Released
ctlL.addEventListener('triggerup', function (event) {
rig.setAttribute('position', {x: 0, y: 0, z: 0});
});
ctlR.addEventListener('triggerup', function (event) {
rig.setAttribute('position', {x: 0, y: 60, z: -640});
});
});
コントローラーのトリガーボタンが離されたタイミングで発生するイベントに、プレイヤーの位置を変更するギミックを設定しています。
- 左手のコントローラーのトリガーアップ:{x: 0, y: 0, z: 0}地点(鶴ヶ城)へ移動
- 右手のコントローラーのトリガーアップ:{x: 0, y: 60, z: -640}地点(さざえ堂)へ移動
3.3. 配置関係
実際の配置関係とは異なりますが、さざえ堂のマップからお城を眺められたら面白いかなぁ…という思いでさざえ堂マップの配置を少し高い位置へ配置してみました。
4. VRで実行した様子
レッツバーチャル会津観光!
VRで会津観光してみた#会津観光 #aframe #VR #WebVR #OpenStreetMap #OpenStreetMap16
— syntan (@synsyntan) August 9, 2020
地図データ:© OpenStreetMap contributors
Happy Birthday OpenStreetMap🎂 pic.twitter.com/KHIrxYo7x8
ライセンス
記事中で使用した、オープンソースライブラリ、3Dモデルのライセンスです。
コード
- A-Frame:The MIT License Copyright © 2015-2017 A-Frame authors.
- aframe-extras:The MIT License (MIT) Copyright (c) 2016 Don McCurdy
地図データ
- © OpenStreetMap contributors