Qiita投稿初心者です。よろしくお願いいたします。
前書き
前回のOpenStreetMap(OSM)の3DマップとA-Frameを使ってWebVRを作ってみたで作成した東京駅前が誰もいなくて寂しかったので、お手軽にGoogle Polyの3Dモデルを読み込んで、遊んでみようと思います。
Polyの3Dモデルは前回のOpenStreetMapの3Dマップデータと同様に、ダウンロードしてローカルから読み込むこともできますが、PolyはAPIが公開されているので、せっかくなのでAPI経由で読み込んでみようと思います。
前提環境
- Webブラウザ:FireFox 55以降 記事中では78.0.2を使用
1. Google Poly API使用準備
1.1. APIキーの取得
@fromkkさまのPoly APIをARKitで使ってみる の APIの利用方法
の記述が詳しいです。APIキーが取得できれば完了です。
1.2. APIを試しに呼んでみる
https://poly.googleapis.com/v1/assets/9C-MLNfxaor?key=[ここに1.1.で取得したAPIキー]
をブラウザで開くと、Polyのモデルの情報が入ったJSONが返ってくるのが確認できると思います。
{
"name": "assets/9C-MLNfxaor",
"displayName": "Fox",
"authorName": "Jake Blakeley",
"createTime": "2019-09-03T19:45:04.338524Z",
"updateTime": "2020-08-03T10:01:52.552642Z",
"formats": [
{
"root": {
以下省略...
例示したURLの 9C-MLNfxaor
というのが3Dモデルの識別子です。この識別子はPolyで3Dモデル閲覧ページのURLから、確認することができます。例えば 9C-MLNfxaor
の閲覧ページはhttps://poly.google.com/view/9C-MLNfxaorです。
1.3. APIリファレンス
APIを呼んで戻ってくる値についてはここの記述が詳しいです。
Poly API 公式リファレンス
2. A-FrameへPolyの3Dモデルの読み込み
※今回はサーバーサイドの実装無しにHTMLとJavaScriptのみで実装するので、JavaScript内にAPIキーをベタ打ちしていきますが、本来はサーバーサイドでAPIを呼び出して、APIキーは秘匿するべきだろうと思います。その点あらかじめご了承ください。
2.1. HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, VR Poly!</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/callPolyApi.js"></script>
</head>
<body>
<a-scene background="color: #EEEEEE">
<a-assets>
<a-asset-item id="map" src="models/map.glb"></a-asset-item>
</a-assets>
<!-- light -->
<a-light color="#FFEEEE" position="-1 1 0"></a-light>
<!-- objects -->
<a-entity id="map"
position="0 0 0"
rotation="0 0 0"
gltf-model="models/map.glb"
scale="1 1 1"
shadow="">
</a-entity>
<a-entity id="polyModel"></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>
</a-scene>
</body>
</html>
前回からの変更点は
-
script/callPolyApi.js
の読み込みの追加 -
id="polyModel"
のエンティティ追加
です。
2.2. JavaScriptコード
var request = new XMLHttpRequest();
request.open('GET', 'https://poly.googleapis.com/v1/assets/9C-MLNfxaor?key=[APIキー]', true);
request.responseType = 'json';
request.onload = function () {
var data = this.response;
console.log(data);
var gltfUrl = ""
data.formats.forEach(element => {
if(element.formatType == "GLTF2"){
gltfUrl = element.root.url;
}
});
document.getElementById("polyModel").setAttribute("gltf-model",gltfUrl);
};
request.send();
XMLHttpRequest
を使用してAPIを呼び出し、得られたJSONから GLTF2
のurlを取得して、id="polyModel"
のエンティティに追記しています。
2.3. 実行の様子
いでよfox!!
駅のモデルがローカル、foxがネットワーク経由なせいか、foxが少し遅れて登場します。
foxさん近い近い!!
召喚座標とカメラの座標が同じなので、ドアップ登場になりました。
カメラをひいてみるとこんな感じです。
あらかわいい。ライトが画面左からの指向性ライト1つのみなので、右側が暗くてディテールが見えていないですね。
3. シーンの調整
コードと実行結果を行ったり来たりで調整することも可能ですが、A-Frameにはシーン調整に便利なインスペクターが用意されています。呼び出し方法は、シーンを表示しているブラウザ上で Ctrl
+ Alt
+ i
です。
参考:Visual Inspector & Dev Tools
3.1. A-Frame インスペクター
Ctrl
+ Alt
+ i
で開いた画面
インスペクターはブラウザの開発者ツールのように、コードを変更し変更結果をすぐに確認できるツールです。開発者ツールと同様に元のファイルを変更するものではないので、変更した値を使用したい場合は手動でのコピペが必要です。
インスペクタ―でのカメラの操作は以下の通りです。
- マウス左ボタンを押下しドラッグ:カメラの角度変更
- マウス右ボタンを押下しドラッグ:カメラの平行移動
- マウス中ボタン(スクロールボタン)を押下し上下ドラッグ:カメラの前後移動
3.2. 環境光の追加
まずはfoxのディテールが見えるように環境光を追加しましょう。
画面左上の「+」ボタンをクリックすると、新しいエンティティが追加され、画面右側に追加したエンティティのプロパティが表示されます。
上部の <a-entity>
をクリックするとコンポーネントの選択画面が表示されるので、 light
を選択します。
lightのプロパティ設定は、
- color:#333
- type:ambient
追加したエンティティのコードは、プロパティ設定画面の右上のボタンからコピーできます。
コピーした文字列は以下です
<a-entity light="type: ambient; color: #333"></a-entity>
これをindex.htmlに追記すると、そのまま使用できます。
追記位置は、 <!-- light -->
と <!-- objects -->
の間あたりにでも。
3.3. 位置調整
次に、カメラの初期位置とfoxの初期位置が同じなので、位置を調整しましょう。
調整対象は <a-entity polyModel>
です。
画面左のメニューで <a-entity polyModel>
を選択すると、foxの周りに青い線でボックス、foxの手前に緑赤青の矢印が表示されます。
青い矢印を左クリックドラッグで後ろに動かすとfoxが画面後ろに移動し、画面右のプロパティのpositionの三つ目の値が変更されます。
これで位置調整は完了です。
ライティングの調整と同様に、HTMLをコピーすると以下の文字列が得られます。
<a-entity id="polyModel" position="0 0 -6.97721" gltf-model="https://poly.googleapis.com/downloads/fp/1596448912552642/9C-MLNfxaor/fgIw32pFZy_/model.gltf"></a-entity>
これは、APIを経由せずモデルを直接読み込むコードとなるため、 position="0 0 -6.97721"
のみindex.htmlへ追記しましょう。
3.4. 調整後のHTMLコード全文
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, VR Poly!</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/callPolyApi.js"></script>
</head>
<body>
<a-scene background="color: #EEEEEE">
<a-assets>
<a-asset-item id="map" src="models/map.glb"></a-asset-item>
</a-assets>
<!-- light -->
<a-light color="#FFEEEE" position="-1 1 0"></a-light>
<a-entity light="type: ambient; color: #333"></a-entity>
<!-- objects -->
<a-entity id="map"
position="0 0 0"
rotation="0 0 0"
gltf-model="models/map.glb"
scale="1 1 1"
shadow="">
</a-entity>
<a-entity id="polyModel" position="0 0 -6.97721"></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>
</a-scene>
</body>
</html>
3.5. 調整後の実行の様子
4. VRで実行した様子
いざHMDをかぶってfoxさんに会いに行きましょう。
HMDやキーボードでの操作は前回の記事をご参照ください。
思ってたよりずっと大きい!!なでなでしたい!!
そして人気が無い東京駅前に一匹の大きい狐が佇んでると、とてもファンタジー。
あと、gifアニメーションだと長い動画がアップロードできないので、ツイート動画の埋め込みしたいなあと思うところ…。次はツイッターアカウントを用意したいですね。
ライセンス
記事中で使用した、オープンソースライブラリ、3Dモデルのライセンスです。
コード
- A-Frame:The MIT License Copyright © 2015-2017 A-Frame authors.
- aframe-extras:The MIT License (MIT) Copyright (c) 2016 Don McCurdy
記事内で使用したPolyの3Dモデル
- Fox copyright Jake Blakeley CC-BY https://poly.google.com/view/9C-MLNfxaor
地図データ
- © OpenStreetMap contributors