spacelyのブログ

Spacely Engineer's Blog

VRの部屋に家具を置いてみた

「AI空間設計」とは?

スペースリーは360度VRを活用したサービスを提供しています。2016年のサービスリリース以来、VRを使ったさまざまな機能を開発してきました。そして、今年の3月に「AI空間設計」という機能をリリースしました!!360度パノラマで撮影した部屋のVR空間の中に、実際に販売されている家具などを配置することができるサービスで、本物の家具を置くことなく部屋のレイアウトを自由に試すことができます!残念ながらスペースリーは事業者様向けのサービスなので、実際に操作していただくことはできないのですが、こちらのページの動画でサービスの雰囲気を知っていただければと思います。

「AI空間設計」の構成

スペースリーはフロントエンドのフレームワークとしてVue.jsを採用しており、AI空間設計はVue.jsとA-Frameを組み合わせて実装されています。A-FrameとはMozillaが開発したOSSで、HTMLファイルにA-Frameのカスタムエレメントを追加していくことで、Three.jsなどによる追加実装をすることなくVR空間を実装することができるフレームワークです。スペースリーでは「AIサイズ推定」という部屋の中の寸法をVR空間で測定できるサービスに初めてA-Frameを採用し、それに続く第2弾として「AI空間設計」のサービスにA-Frameを採用しました。今回はそんな「AI空間設計」の基本的な機能を実装してみましょう!

「AI空間設計」を実装してみよう!

実際の「AI空間設計」と同じようにVue.js + A-Frameの構成で実装していきます。本記事で全ての実装を0から解説すると大変なので、VR空間の実装のポイントとなる部分の解説に止めたいと思います。完全な実装は下記のリポジトリから確認できるようにしていますので、 git clone git@github.com:3dstylee/vhs-example.git して動かしてみてください!

https://github.com/3dstylee/vhs-example

部屋のVR空間を作ってみる

A-FrameでVR空間を作るのはめちゃめちゃ簡単です。a-scene のタグを設置するだけです。

<a-scene></a-scene>

これだけだと真っ白な画面が表示されるだけでわかりにくいですが、例えばこのようにちょっとコードを書き加えるだけでVR空間であることがわかります。

<a-scene>
  <a-box position="0 1 -3" rotation="45 20 45" color="#64B" />
</a-scene>

f:id:kensei18:20210908183107p:plain

それでは実際の部屋の空間を作ってみましょう。と言っても、これまた簡単です。a-sky というタグを追加するだけです。

<a-scene>
  <a-assets>
    <img id="sky_img" src="./assets/room.jpg" />
  </a-assets>
  <a-sky id="sky" src="#sky_img" />
</a-scene>

a-sky だけではなく、a-assets というタグも追加していますが、これは使用する画像や3Dファイルをキャッシュしてくれる機能です。ここで画像を読み込むことによって、例えば空間の画像を入れ替えたりする際に、事前に読み込みを完了しておくことができるので、切り替えをスムーズに行うことができます(なので今回はそれほど意味がないです(笑)あくまで紹介です)。ここで読み込んだファイルは、idを指定しておくことで、a-assetsの外にあるa-skyのようなタグから呼び出すことができます。上記の./assets/room.jpgは部屋の360度パノラマ画像です。

f:id:kensei18:20210908183159p:plain

この画像を見て、なんとなく360度パノラマ画像が空間全体に表示されていることはわかると思いますが、実際にはどのように表示されているのでしょうか?A-FrameにはVisual Inspectorという開発ツールが用意されていて、A-Frameの空間上で <ctrl> + <alt> + <i>をするとインスペクタモードに切り替わります。そのモードに入り、カメラを思いっきり引くと、VRがどのように表現されているのかがハッキリわかります。

f:id:kensei18:20210908183240p:plain

ぱっと見は本当に部屋の中にいるように見えますが、実際は大きな球体の空にパノラマ画像を投影しているのでした!最初に見た部屋は上画像の赤く囲まれた部分から眺めていたもの、ということがよくわかります!

家具を置くための平面を設置する

a-skyで表示した部屋は、実際の部屋の形をしているわけではなく、大きな球体に部屋の画像を投影しているということが分かりました。つまり、床に見える部分も実際は遥か遠くに映し出されたものなので、実際に物を置く、ということはできません。従って、家具の3Dオブジェクトを配置するためには、実際にものを置くことのできる平面を用意する必要があります。

A-Frameにはa-planeという平面を表示するためのエレメントが用意されています。先程のコードに下記のようにa-planeと追記するだけです!

<a-scene>
  ...
  <a-plane
    id="plane"
    height="20"
    width="20"
    rotation="-90 0 0"
    position="0 -1.3 0"
    opacity="0.3"
  />
</a-scene>

f:id:kensei18:20210908183302p:plain

a-plane はそのままだと水平方向の平面にはならず、垂直の壁の状態になってしまうので、rotation="-90 0 0"としてx軸に対して-90°回転させる必要があります。裏表があるので90°ではダメです!position="0 -1.3 0"としているのは床は目線(カメラ)よりも低い位置にあるためです。本当はこの平面が見えないようにopacityは0にするのですが、開発しやすいので一旦opacity="0.3"としています。

家具を表示する

家具はglTFという3Dオブジェクトのためのファイルを使用します(バイナリの拡張子は.glb)。まずは3Dオブジェクトを表示することができるか確認してみましょう。a-entity というタグにgltf-model というプロパティを渡すと表示することができます。

<a-scene>
  ...
  <a-entity gltf-model="/sofa.glb" position="0 0 -3" />
</a-scene>

f:id:kensei18:20210908183343p:plain

ちなみに、本当は.glbファイルもa-assetsの中においてキャッシュさせることができるのですが、VueCLIプロジェクト内に.glbファイルを配置すると3Dファイルが表示できませんでした(泣)。実際のAI空間設計ではCloudFront + S3を使って3Dファイルを呼び出していて、その場合は問題なく使えました!今回のブログを書くにあたって初めて気が付きました(笑)。

家具を動かす

ここまではhtmlだけで表現できる内容でしたが、ここからVue.jsを組み合わせていきます。

実装の前に家具を動かす仕組みを簡単に解説します。AI空間設計ではマウスを動かして家具を動かしますが、それはどのような仕組みなのでしょうか?簡単にいうと、下画像のようなイメージです。

f:id:kensei18:20210908183420p:plain

マウスの先から見えない光線を出し、その先にある平面に当たると、その交点に向かって対象の家具が動いてきます。それがあたかも家具をマウスで動かしているように見えます。A-Frameではraycaster(rayは「光線」、castは「投げかける」)という機能を使って実現できます。

実装は下記のようになります。説明はインラインで記載しています。

家具を置く

動かしている家具を配置したい場所に置きます。これはシンプルで、家具を動かす時に使用した<a-entity allocate />の要素を消せば良いだけです。isMovingというbooleanのdataを用意します。

家具を再移動させる

一度配置した家具をやっぱり場所変えたい、と思うことがありますよね?その場合、動かしたい家具をクリックすると最初の時のように動き出す、というのが自然な動きかと思います。この動きもraycasterを使用することで制御することができます。

これで家具を動かす・配置する・再度動かすという「AI空間設計」の基本的な機能が実装できました!

先述の公開リポジトリでは複数の家具を配置できるようにしています!そのため解説とは少し実装が異なりますが、ここまでの内容で十分に理解できる内容になっています!

最後に

今回は部屋のVR空間で1つの家具を移動して配置するという基本的な機能のみを解説しましたが、実際の「AI空間設計」はもっとたくさんの機能が盛り込まれています!もしこのようなVRを活用したアプリケーションの開発に興味がある方は、ぜひ採用ページをご覧ください!