PLATEAUでSTYLYの都市XRを作る！

# やりたいこと
都市テンプレートがないところでもSTYLYの都市Xを作りたい！！

- STYLYの都市XRについては以下参照

https://styly.cc/ja/manual/xr-urban-spaces-starter-guide/

# モチベーション
- STYLYには都市テンプレートという簡単に都市XRが作成できるテンプレートがありますが、まだまだ対応ロケーションが少ない
- 私の住む新潟市の都市テンプレートは、古町、万代島と新潟駅からやや遠いところなので現地確認が大変
    - おそらく駅から古町や万代島までの人流や観光資源を作りたいとい意図があるんだとは思います🥲

# 概要
## 使うもの
* PLATEAU CityGML [新潟市2023年モデル]
* Unity(or Unreal Engine) [UE 5.3.2]
* PLATEAU SDK for Unity (or Unreal) [PLATEAU SDK for Unreal v2.2.1]
* STYLY Studio [2024/5時点]
    * [ ]内はこの記事を描くにあたり使用したバージョン

PLATEAUについての詳細は公式ページ参照

https://www.mlit.go.jp/plateau/about/

## ざっくり手順
1. PLATEAUのCityGMLをPLATEAU SDK for Unity (or Unreal)を使ってGLTFに変換
1. 変換したGLTF(PLATEAU都市3Dモデル)をSTYLY Studioにアップロード
1. 都市3DモデルにModifierのAR Occlusion Maskを追加してAR Occlusionとして利用する
1. 何らかの方法でARシーン起動時の位置と方向を合わせて、都市モデルと現実の事物を重ね合わせる

⇒ 都市XR完成！

以下、詳細手順を解説していきます

# PLATEAU CityGMLのGLTF変換
* [PLATEAU SDK for Unity]または[PLATEAU SDK for Unreal]を使用して、PLATEAUのCityGMLをGLTFに変換します。

https://project-plateau.github.io/PLATEAU-SDK-for-Unity/

https://project-plateau.github.io/PLATEAU-SDK-for-Unreal/


:::note warn
以下手順は筆者の手元で環境セットアップ済みだった[PLATEAU SDK for Unreal]を使用して検証しています。
[PLATEAU SDK for Unity]でも同様の操作は可能と思いますが未検証です。
:::


## PLATEAU SDKのインストール
公式マニュアルに従いPLATEAU SDKをインストールします。


https://project-plateau.github.io/PLATEAU-SDK-for-Unity/manual/Installation.html

https://project-plateau.github.io/PLATEAU-SDK-for-Unreal/manual/Installation.html

Unity(or Unreal Enigen)が未インストールの場合は合わせてインストール＆セットアップします。
特にこだわりがなければPLATEAU SDKの想定バージョンのUnity(or Unreal Enigen)を使用します。
想定バージョンは以下リリースページで確認できます。

https://github.com/Project-PLATEAU/PLATEAU-SDK-for-Unity/releases

https://github.com/Project-PLATEAU/PLATEAU-SDK-for-Unreal/releases

## PLATEAU CityGMLをダウンロードする
G空間情報センターのからCityGMLをダウンロードします。

https://www.geospatial.jp/ckan/dataset/plateau

使用する都市を選択してCityGMLをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/936ef8da-8916-8314-3784-7447e4e048da.png)


ZIP展開するとファイルサイズかなり大きいので注意（新潟市2023年モデルは90GB程度😂）
PLATEAU SDK経由でサーバーからもダウンロードできますが、Unrealでは土地起伏に地図テクスチャを貼れなかったのでローカルでダウンロードする手順をとしています。

## PLATEAU CityGMLをインポートする
インポートの基本的な操作は公式マニュアルをご参照ください。

https://project-plateau.github.io/PLATEAU-SDK-for-Unity/manual/ImportCityModels.html

https://project-plateau.github.io/PLATEAU-SDK-for-Unreal/manual/ImportCityModels.html

都市XRで使用する範囲を選択してインポートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/30cd769d-7193-0dd3-e30a-ff31f39cc804.png)

どのような都市XRコンテンツを作りたいかにもよりますが、今回は以下を最大LOD2でインポートします。
位置関係や後述の位置合わせがしやすいようにテクスチャもインポートしています。
ただし、あくまでもテクスチャは制作補助でしかないため（完成したシーンには表示しないため）、STYLY Studioやシーンの起動が重くなるのが嫌ならなしでも問題ありません。
* 建築物
* 都市設備（あれば）
* 起伏（位置合わせに使う地図テクスチャのため、モデルとしては不要）

以下は不要なのでインポートしません。
* 道路
* 植生
* 災害リスク
* 土地利用
* 都市計画決定情報

PLATEAU(CityGML)のLODについては以下を参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/8234775d-588b-0000-75af-49b24cc6afff.png)
引用元：https://www.mlit.go.jp/plateau/learning/tpc01-2/

### インポートについての所感
* ほぼ高層ビルのみの都市部ならLOD1(屋根形状なし)でもいいかもしれません
* 背の低い建物や特徴的な屋根形状の建物がある場合はLOD2の方が良いと思います
* また極めて限定的な範囲で都市XR作品ならLOD3以上とするのもありかも
* ただし、当然ながらLODを上げるとその分（サイズ、頂点数が増え）シーンのロードが遅くなるのでご注意ください
* 当然ながら使いたいLODのPLATEAUのモデルが用意されていることが前提となります
* どのLODが用意されているかの調査方法などは以下過去記事もご参照ください
    * PLATEAU VIEW 2.0時代記事なので、現在のPLATEAU VIEW 3.0と多少操作が異なるのでご注意ください（その内アップデートします。期待せずお待ちください。。。。）

https://qiita.com/fubuky35/items/6d961a5c5c0dbc909eb7

### インポート設定スクリーンショット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/f3bd3660-b8fb-133f-7fe5-5ff479f94989.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/fb0d9e70-7134-8ea1-f5f2-410fc66fdc2a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/3c4cb0d9-a38e-3b7c-faf1-f4337ca6a1f6.png)

## CityGMLのGLTF変換(エクスポート)
変換（エクスポート）機能の基本的な操作は公式マニュアルをご参照ください。

https://project-plateau.github.io/PLATEAU-SDK-for-Unity/manual/ExportCityModels.html

https://project-plateau.github.io/PLATEAU-SDK-for-Unreal/manual/ExportCityModels.html

エクスポート前に[モデル修正]で[重複する地物を非表示]にチェックがついていることを確認します。この後、表示されている地物のみをGLTFにエクスポートするためです。
また、不要な地物があればチェックを外して非表示にしエクスポート対象外とます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/2beddd59-3e1a-fdd2-166f-00d2e6f0ae7e.png)

今回は[出力形式: GLTF]、[フォーマット: ASCII]でエクスポートしました。
（他のファイルフォーマットでも大丈夫かもしれませんが未検証です。）
不要な地物を変換しないように[非表示モデルを出力する]はチェックOFFしています。
また、シーンの原点付近に都市モデルが表示された方が、STYLY Studioで編集する際に都合がよいので[座標設定: ローカル座標]としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/732a1ac8-c68c-afee-ba31-85892b435770.png)

# STYLY StudioへのGLTFモデルのアップロード
エクスポートすると複数のGLTFモデルができるので、GLTFモデル単位（フォルダ単位）でZipファイルに圧縮してSTYLY Studioにアップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/878ef9a9-15bf-e0d7-5d4d-1e76dc3b5f19.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/cad46ebc-08c9-aff9-8250-6ef7d28d9d01.png)

Zip圧縮したGLTFのアップロードはSTYLY StudioのMy uploads > 3D Modelから行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/7f3b03f0-a4dd-6a14-5069-883884a298c8.png)

なぜか土地起伏(dem)はアップロードできなかったので、テクスチャのみ画像としてアップしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/f68b9636-4d6c-949d-6949-d7aac8b3d1f5.png)

また、PLATEAU SDK for Unrealのバグか土地起伏に貼られた地図テクスチャもおかしかったので、実際は地理院タイルを直接取得するなどごにょごにょしています。
（2区画分インポートしたのに、両区画に同じ地図テクスチャが貼られていました。。。なぜ😭）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/fd57b383-cd66-401c-c177-7f46f55ee83b.png)

https://maps.gsi.go.jp/development/ichiran.html

参考：土地起伏(dem)に地理院タイルを貼る話（SDKが地図テクスチャに対応する前の話）

https://qiita.com/yoshikawa-hiroyuki/items/6935a9705b3144774fd1

# STYLY Sceneに都市モデルの追加 + AR Occlussin Maskの追加
アップロードした都市モデルをすべてSTYLY Sceneに追加します。
座標設定をローカル座標にしているので特に調整しなくとも地物同士の位置関係が合います。
都市モデルが暗くて見づらいならDirectional Lightの角度をぐりぐりしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/d37a7744-c018-1fd9-9fbc-be9b6e17a67c.png)

位置合わせしやすいように地図テクスチャ（image）もFloor Square Screenに貼って追加します。
都市モデルと地図テクスチャの位置合わせは手動で拡縮、移動、回転して合わせています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/1e7b6db0-1de1-ae77-4050-238db3c895d6.png)

都市モデルにAR Occlussin MaskのModifierを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/d63dd1c6-08f2-e081-489e-2967143a38d9.png)
これで都市モデルはARシーンにおいてAR Occlussinとなり、カメラ画像＝現実風景は透過しますが、3Dモデルを透過しなくなります。この都市モデル（AR Occlussin）と現実の建物がぴったり合うようにARシーンを表示できれば、現実の建物にAR表示した3Dモデルが遮蔽される表現＝都市XRができるというわけです。

AR Occlussin Maskの概念についてもう少し知りたい場合は以下もご参照ください。

https://www.docswell.com/s/kitposition/ZM32GK-2022-06-05-174216

# 都市モデルと現実の建物の位置合わせ（ARシーン起動の位置と角度の決定）
最後に何らかの方法で都市モデルと現実の建物の位置合わせします。

現実の地物とARの位置合わせはロケーションマーカー(QRコード、Immersal機能)を使うのが正攻法っぽいです。しかし、ロケーションマーカはProプラン（月5万円～）からなので、さすがに個人で気軽には試せないです:cry:

参考：
STYLY料金プラン

https://styly.cc/ja/pro/

Immersal機能

https://styly.cc/ja/manual/ar-immersal-starter-guide/

なので今回はARシーン起動時にタップする位置（ここがARシーンの原点(0,0,0)となる）とスマホの向きを固定するというアナログな方法を使っていきます。

GoogleMap（航空地図）、Googleストリートビュー、現地調査などで位置と方向を決めやすい地形を探します。ARシーン起動時に床面を検知してタップする必要があるので、起動時にタップする位置は道路（地面）を選んだ方が良いと思います。オブジェなどの方がわかりやすいですが、床面検知の問題でうまくいかない気がします。（未検証）

今回は以下の歩道の半円状レンガ模様を使います。★の位置に立って✕をタップしてARシーンを起動する想定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/bed23895-1f3a-39ad-86c4-0b203fcf9f10.png)

シーンの起動位置、方向が決まったら、ARシーンの原点が都市モデルの決めた位置、方向になるよう都市モデルを回転・移動します。都市モデル関連のオブジェクトをすべて選択した状態で一括回転・移動するとズレません。（ただし、自力で貼った地理院タイルは除く。。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/6c3be787-be28-a9a9-efbd-98e5b3e36c5c.png)

地理院タイルが粗くてわかりずらいですが頑張って位置を合わせます。正直STYLY Studio上だけでこねこねしていてもぴったり合わせるのは難しいので最初は大体でいいと思います。実際に現地でシーンを起動して調整しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/60bea142-7dbd-d5cb-86b4-0e535071c5e8.png)

個人的な考えですが、都市XRは現地で実運用に沿って調整することがとても重要だと考えています。いわゆる三現主義「現場（現地）、現物（実際の見え方）、現実（実運用）」です。

# ARシーンの仕上げ
次に、位置合わせとAR Occlussinが上手く機能しているか確認するためのモデルを追加します。今回はゴリラを追加しました。（スクリーンショットでは雰囲気がわかりやすいようにAR Occlussin Maskを一時的にOFFにしています。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/90cb3672-9d1c-c3b2-3bd2-95b0bc094e48.png)

またEnable AR Occlusionも削除しておきます。これがあるとAR Occlusion対応端末(LiDAR付きのiPhoneなど)で遠く(5m以上くらい？)のオブジェクトが表示されなくなるためです。基本的に遠くにコンテンツを表示することが多い都市XRの場合は削除しておいた方が無難と思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/3ef36db0-d5a9-ef1e-40f5-db5c893109f9.png)
参考：

https://styly.cc/ja/manual/occlusion-manual/

https://jp.forum.styly.cc/support/discussions/topics/70000508550

最後に不要な地図テクスチャを非表示にします。これでシーンは完成です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/758c49fd-1780-673d-0d04-e4ea4806b4b9.png)

## 補足: PLATEAUのクレジットについて
シーンを公開する場合はPLATEAUのクレジットをお忘れなく。
（地理院タイルはシーンに表示しないのでクレジットは不要のはず）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/33190ed7-dfcf-d0a7-36f0-8b3b209d49b1.png)

クレジットの表記内容については、最新のPLATEAUサイトポリシーをご確認ください。

https://www.mlit.go.jp/plateau/site-policy/

# 現地確認！！
ここまで出来たら現地でARシーンを起動して確認します！
（歩道のど真ん中で恥ずかしかった。。。）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">位置合わせが雑だから＋都市XRテンプレートと違って途中でキャリブレーションが走らないからか、動くとズレが目立つな🥲<a href="https://twitter.com/hashtag/STYLY?src=hash&amp;ref_src=twsrc%5Etfw">#STYLY</a> <a href="https://t.co/c7cPCAobIi">https://t.co/c7cPCAobIi</a> <a href="https://t.co/hYbCtTtMvB">pic.twitter.com/hYbCtTtMvB</a></p>&mdash; fubuky35 (@fubuki35) <a href="https://twitter.com/fubuki35/status/1785598245596766304?ref_src=twsrc%5Etfw">May 1, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ちょっとズレてるけど、自作都市XRが出来たと言っていいはず！

## 今回の検証で作成したシーンはこちら

https://gallery.styly.cc/scene/7520d4a5-f61e-4380-b512-2820958a5878

シーンの起動が結構遅いです:disappointed_relieved:
広範囲の都市モデルをインポートしすぎたのかもしれません。（Blenderなどで頂点数を調整した方がよかったかも。）

# 所感など
* AndroidスマホとiPadでやってみましたが毎回同じズレ方なので、調整を頑張れば都市テンプレート並みの精度はできそうでした（都市テンプレートも特徴点がない場所で起動すると割とズレることもありますし。。。）
* エリア内ならどこでもシーンを起動できる都市テンプレートと違い、今回使ったアナログ方式はシーン起動に制約が大きいので複数人で同時に体験する運用は難しそう
* 都市テンプレートと違い途中でキャリブレーションが掛からないので動き回る体験は難しそう
* 逆に調整次第で、都市テンプレートでは（おそらく）実現できないビルの屋上や窓からの都市XRを作成できる気がする！
* 2DUISet(Tips)で起動方法の説明（立ち位置とアップ位置の説明）を作ってみたら、タップ後にしか表示されなくて本末転倒でした。。。（いい方法知っていたら教えてください:sob:）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3196409/1ad8e220-1f07-0633-db67-cb1f1507aa4f.png)
* STYLY製作者は基本的にUnityを使っていると思うので、いつか[PLATEAU SDK for Unity]でも検証して記事を更新したい

# 最後に
みんなSTYLYで都市XR作ろうぜ！

以上です！