別視点のサブ画面を出したい in A-Frame

ハンズオンで使っている題材の迷路についてちょっと改良を加えたいなと思っていろいろとアイデアをひねってます。

1シーンを多角的視点で見るのはどうだろう?

以前、同じVR世界に複数人で集まれたらいいなと思って、複数人参加型のコンテンツをnode.jsで作ったことはありますが、逆に1つのシーンを複数視点で見れるかな?と考えました。
カメラから見る一人称視点以外にも、頭の後ろくらいから見下ろす感じの3人称視点でみれたら面白いかな~
ただA-Frameでは1シーンに配置できる(アクティブにできる)カメラは1つのみのはずだし、どうしよう。

iFrameって使えるんじゃね?

ぱっと思いついたのが、iFrameでサブウインドウを表示する方法。
様々なBlogで小窓的にA-Frameサンプルを表示しているものを、A-Frameの上に重ねられるんじゃないかと。

でも、違うシーンになるため2つのシーンの同期を考えないといけない。
WebSocketか、あるいはWebRTCか。
面倒くさいな。

で他に楽な方法はないかといろいろ調べてみると、ありました。 同一ドメイン配下であれば、iFrameもDOMとして扱えるようです。 もちろん、iFrame側から親DOM(?)もDOM操作できそう。 これは便利だ。

で作ってみたサンプルがこちら。

Hello, World! with subwindow

メイン画面はいつもの一人称ですが、サブ画面は後ろ斜め上45度から見た3人称視点となっています。 もちろん、メイン画面で動けばサブ画面も連動します。

ソース

htmlが2ファイルと、cssが1ファイルになります。
(ハテブのMarkdownのコード表記って、色とか行番号とかつかないんだな。。。)

まずはメインとなるindex.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Hello, World! with subwindow</title>
    <meta name="description" content="Hello, World! - A-Frame">
    <script src="https://aframe.io/releases/0.3.2/aframe.min.js"></script>
    <link rel="stylesheet" type="text/css" href="./css/style.css"></link>
    <script>
      // サブWindow内のユーザ情報。変数の取り回しがわからないためグローバルに持たせる。改善したい。
      var user;

      // カメラエンティティの位置情報をサブWindowのユーザと同期させるコンポーネント
      // コンポーネント名がキャメル形式だと動いてくれない不思議。
      AFRAME.registerComponent('sync-user', {
        schema: {
          userId: {default: "userPosition"},
        },

        init: function() {
          this.camera = this.el;
          var userId = this.data.userId;
          document.getElementById("iframe").onload = function(e) {
            var doc = this.contentDocument;
            // TODO:このuser変数をAFRAME.registerComponent内のスコープにできないか?
            user = doc.getElementById(userId);
          }
        },

        tick: function(e) {
            if ((typeof user !== "undefined") && (user != null)) {
              var pos = this.camera.getAttribute("position");
              var rot = this.camera.getAttribute("rotation");
              user.setAttribute("position", pos);
              user.setAttribute("rotation", {"x":0, "y":rot.y, "z": 0});
            }
        }
      });
    </script>

  </head>
  <body>
    <a-scene id="sceneId" class="aframe-scene">
      <a-entity id="camera" camera="userHeight: 1.6;" look-controls wasd-controls sync-user="userId: userPosition"></a-entity>
      <a-box id="box" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
      <a-sphere id="sphere" position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
      <a-cylinder id="cylinder" position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
      <a-plane id="plane" position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
    <div class="subwindow">
      <iframe id="iframe" src="./index2.html" />
    </div>

  </body>
</html>

次にサブ画面側のindex2.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Hello, World! - A-Frame</title>
    <meta name="description" content="Hello, World! - A-Frame">
    <script src="https://aframe.io/releases/0.3.2/aframe.min.js"></script>
  </head>
  <body>
    <a-scene id="sceneId" class="aframe-scene" vr-mode-ui="enabled: false">
      <a-sphere id="userPosition" position="0 0 0" rotation="0 0 0" radius=0.25 color="#0000FF">
        <a-entity position="0 3 3" rotation="-30 0 0">
          <a-entity camera="userHeight: 0"></a-entity>
        </a-entity>
      </a-sphere>
      <a-box id="box" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
      <a-sphere id="sphere" position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
      <a-cylinder id="cylinder" position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
      <a-plane id="plane" position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>

最後にサブウインドウの位置などを決めるcss

@charset "utf-8";

.aframe-scene{
    position: absolute;
    z-index: 1;
}
.subwindow{
    position: absolute;
    top: 10px;
    left: 10px;
    width: 300px;
    height: 200px;
    padding: 10px;
    z-index: 3;
}

改善したいところ

このままでも動きますが、何とか改善したいポイントが2点あります。
どなたかヒントだけでもいただけるとありがたいです。

  1. グローバル変数の除外
    iFrameの読み込みが遅いため、コンポーネントのinit内でiFrameのonload終了後にiFrameのDOMを持ってくるように実装しています。
    その際、変数の受け渡しがわからないため、グローバルに変数を持たせて、tick内で利用しています。
    コンポ―ネント内で閉じた変数にできれば汎用性が高まると思うのですが、変数の引き渡し方がわかりません。

  2. コンポーネントのupdateは何の契機で動く?
    tickにて毎フレーム毎にサブ画面SCENEと同期をとっていますが、初めはEntityのPositionやRotationが変更された契機で動きそうなupdateで実装していました。ですがupdateだと動かなかったです。というかsetAttributeなどを使ってEntityを更新してもupdateが動くことはありませんでした。
    何か条件が足りないのでしょうか?

RICOH THETA Sの画像ビューアーを作ってみた

Thetaで撮った画像はふつうの画像ビューアーでは見れません。
いや見れるけど、上下がノビノビのメルカトル図法です。
やっぱり360度天球画像として見たいですよね。

ということで、JPEG画像を360度全天球画像として参照できるビューアーを
作ってみました。

ビューアー

http://theta360test.azurewebsites.net/theater.html

使い方

サイトにアクセスして、左下にある「ファイルを選択」をクリック
出てきたダイアログから、画像を選択します。
しばらくすると360度天球画像を見ることができます。

残念ながらいくつかのブラウザでは動きません。
動作確認が取れているものは

以下のブラウザでは動きません。

上記以外は未確認です。Macとか触ったことないし。

せっかく撮った写真ですから、みんなに見てもらいたいですよね。
気軽に使ってもらえればありがたいです。

RICOH THETA Sでバイクの走行中動画を撮影(自撮り)する

RICOH THETA Sを買う前からやりたいことがありまして。
それはバイクの車載動画の撮影です。
バイクに設置したThetaで、360度のバイク動画を撮影したら楽しいだろうな~って。
今回、設置するための道具もそろったところで、いろいろなところにThetaを設置して
どのような動画がとれるか確かめてみました。

設置場所

設置できる場所はいろいろとあるが、今乗っているSUZUKI Bandit1200Sで設置できる場所で絞り込んでみた。

f:id:sgi-don:20160723232053j:plain

  1. ミラー
  2. ハンドルバー
  3. エンジンガード
  4. パニアケースの上
  5. 後ろタイヤ横

こんなもんかな。
ほかに、エンジン前、前輪横、ヘルメットの上、ナンバープレートのさらに後ろ など
様々な設置場所は考えているが、オーソドックスなところから攻めることにした。

設置するために必要な道具

今回の撮影に伴い、設置のためにRAM MOUNTというパーツを使ってみた。

RAMMOUNT タフ・クローS ARAP-B-400U

RAMMOUNT タフ・クローS ARAP-B-400U

すでにスマホのマウントでRAM MOUNTは使っていますが、がっちり固定されてスマホが落ちることや振動でずれることもなくとても快適。
Thetaの設置もこれがベストだろうと思っている。

設置方法

見てもらったほうが早いだろう。順にどうぞ。

1. ミラー

f:id:sgi-don:20160723232114j:plain

2. ハンドルバー

f:id:sgi-don:20160723232121j:plain

3. エンジンガード

f:id:sgi-don:20160723232130j:plain

4. パニアケースの上

RAM MOUNTパーツ+自撮り棒で、Thetaを上方向に伸ばしている。
伸ばせば伸ばすほど、ブレて見づらくなるだろうから、どの程度まで
許容できるか?

f:id:sgi-don:20160723232152j:plain

一番縮めた状態

f:id:sgi-don:20160723232158j:plain

一番伸ばした状態

f:id:sgi-don:20160723232204j:plain

伸ばした状態の見た感じ、ちょっと異様だな。
これだけ伸ばしてしまうと、どうせブレブレ見てられない動画になるんだろうな、と、この時は思っていました。

5. 後ろタイヤ横

Thetaを逆さにつけています。
Thetaは天頂補正があるため、本体が逆さでも出力結果は天井が上にくるよう補正されます(画像、動画ともに)。すごいね。

f:id:sgi-don:20160723232209j:plain

撮影結果(画像)

動画撮影の前に、360度画像がどのように見えるか確認します。

1. ミラー

前方の視界が開けて見やすいですね。
あと、バイクと乗っている人が一緒に撮影できているので、この構図が好きな人にはお勧めです。
この位置だと、やっぱり顔は映りますね。(なんか俺、変な顔)

ThetaSでバイクの撮影(自撮り)を行う。 1. ミラーに設置 - Spherical Image - RICOH THETA

2. ハンドルバー

乗っている人に近い視点で撮影できます。
計器類も一緒に映るので、気にする人は気にしますかね。
カウルがある車種だと、Thetaを雨風・小石・虫などから守ることができます。これ結構重要だと思っています。

ThetaSでバイクの撮影(自撮り)を行う。 2. ハンドルバーに設置 - Spherical Image - RICOH THETA

3. エンジンガード

下からのアングルで撮影となります。
360度画像になると、エンジン超じゃまですね。

ThetaSでバイクの撮影(自撮り)を行う。 3. エンジンガードに設置 - Spherical Image - RICOH THETA

4. パニアケースの上

パッセンジャー目線での撮影になります。
自撮り棒の長さにより、低~中~高の3種類撮ってみました。

まずは低

ThetaSでバイクの撮影(自撮り)を行う。 4. パニアケース上に設置(低い) - Spherical Image - RICOH THETA

次に中

ThetaSでバイクの撮影(自撮り)を行う。 4. パニアケース上に設置(中) - Spherical Image - RICOH THETA

最後に高

ThetaSでバイクの撮影(自撮り)を行う。 4. パニアケース上に設置(高い) - Spherical Image - RICOH THETA

高を見た後で低を見ると、すごい落差ですね。

5. 後ろタイヤ横

後ろの人を撮影するようでしょうか。だったらThetaでとる意味ないような。
とりあえず、動画撮影だけはしてみましょう。

ThetaSでバイクの撮影(自撮り)を行う。 5. 後ろタイヤ横 - Spherical Image - RICOH THETA

撮影結果(動画)

これも見てもらったほうが早いですね。どうぞー スマホで見ている人は、youtubeアプリで見ると360度天球動画としてみることができます。

1. ミラー


ThetaSでバイクの撮影(自撮り)を行う。 1. ミラーに設置

2. ハンドルバー


ThetaSでバイクの撮影(自撮り)を行う。 2. ハンドルバーに設置

3. エンジンガード


ThetaSでバイクの撮影(自撮り)を行う。 3. エンジンガードに設置

4. パニアケースの上

はじめは一番低い位置で、動画の真ん中あたりで、最高位置まで伸ばして動画撮影しています。


ThetaSでバイクの撮影(自撮り)を行う。 4. パニアケースの上に設置

5. 後ろタイヤ横


ThetaSでバイクの撮影(自撮り)を行う。 5. 後ろタイヤ横

まとめ

自撮り棒を思いっきり伸ばした状態での撮影が、思ってた以上に面白い。
伸ばしたほうが逆にブレずに見やすくなるなんて思ってもみなかったし、
自分の走行中の姿を上空2mちょい後ろのところから見るなんて
普通できないですし、しかもそれが360度全方位撮影できてしまう。

カメラ全般そうですが、レンズに傷や汚れがついてしまう場合があります。
今回の撮影でも、レンズに虫がついてしまいノイズが混じってしまいました。
(エンジンガードの撮影の途中からです)
折角撮影したけど、虫がついていて台無しにならないように、こまめに確認しながら
撮影したほうがよさそうですね。
f:id:sgi-don:20160723232215j:plain

おわり

Ricoh Theta Sの活動限界

Thetaとともにバイクに乗って動画撮影することが多いのですが、毎回電源ON/OFFするのがとても面倒。しかも最近ハードケースをGETしたのですよ。
こんなの、

THETA用ハードケース TH-1 防滴 ポリカーボネート製 6910717

THETA用ハードケース TH-1 防滴 ポリカーボネート製 6910717

これに入れてると、撮影したいときにいちいちバイク止めて、ケースから取り出して、電源ON/OFFなんてもう正気の沙汰ではない。
もういっそ電源ONのままでいいんじゃと思った。が、こいつの活動限界はどのくらいなんだろう?と事前に知っておく必要があるな。
と思いたって、電源つけっぱなしでどのくらい持つのか確認してみました。

活動限界

いきなり結論

活動時間: 約2時間(動画撮影: 合計32分30秒、写真撮影: 1枚)

これだけ持つなら、乗ってる間は電源つけっぱなしでもいいかな。 バイク降りたら、モバイルバッテリーで充電必須だな。
#あれ?Thetaってモバイルバッテリーで充電できたっけ?

数々の問題が

つけっぱなしにしてみてわかったのですが、こいつ熱い。「温かい」ではなく、「熱い」
TH-1に入れてつけっぱなししてたら、熱暴走で電源切れやがった。(走ったのは夜の10時なのに)
何のためのケースだよ。熱で内側曇ってるし、だめじゃ~ん。

防滴はあきらめて通気口を開けようかな。ついでに充電できるような穴もあけたら便利かも。構造的にむずかしそう。

Ricoh Theta Sの動画を共有するために

動画を共有する

バイクにThetaを設置して、動画を撮っています。

でせっかく撮った動画はみんなに見てもらいたいですね。
というわけで、Thetaで撮った全天球型動画を共有する方法を探してみました。

共有先いろいろ

今のところ以下の方法があるようです。

公開制限有無、アップ容量制限など、サイトにより特徴があるようです。

公開サイト 公開制限 容量制限 特徴
theta360.com 公開/限定公開 5MB コミュニティに参加した感がある
Youtube 公開/限定公開/非公開 制限なし 最近Metadata追加が不要になったみたい
Facebook Facebookの公開設定 制限なし スマホアプリからアップが可能。でも画質が落ちる。
自前サーバ 自由自在 積めるだけ a-frame使って自分好みの動画にできる?

画像メインで、たまに小さな動画をアップしたいのであれば、Theta360かな。
スマホだけで作業を完結させたいのであれば、Facebook。特にiPhoneなどのiOS使いであればTheta+ Videoアプリで編集も可能。
それ以外は自分の使っているチャンネルに合わせて、アップしていけばよいかと思います。

動画を編集する

残念ながら無料でお手軽に動画を編集(トリム、フィルタ、BGM追加など)するには、iOSのTheta+Videoアプリ以外見つけられていません。Androidではアプリ自体がないので、選択肢がこれしかないのはちょっと残念。

私はiPhoneを持っているので、公開先がFacebookだととっても楽なんですよね。

動画を公開する

共有する方法をかき集めてみました。

まとめ

私の共有の方法としては、

  • 個人的な動画などはFacebook
  • 一般公開したい情報は、FacebookもしくはYoutube
  • 3Dコンテンツとして公開する場合は、自前サーバ(予定)

こんな感じで動画を共有することがしています。
せっかくとった動画ですし、みんなで共有して楽しみましょう。

A-Frameとは?

VRコンテンツを公開するには

いろんなところでThetaの画像や動画に対応されていますね。

もともとRicohがTheta360.comで自由に公開できる場を設けています。他ではYoutubeは動画をUPできるし。Facebookもこの前画像、動画をアップできるようになったそうです。

共有するだけならそれだけでも十分なのですが、コンテンツを使ってあれこれするとなると、話はな変わってくるかと思います。

やりたいこと

未だ見えず。

ただ画像や動画を公開するだけではなく、そこに何かを加えてもう少し面白いものを作りたいなと思っています。そうなると、Theta360やYoutubeに公開するのでは自由度が低いと感じています。

これいいんじゃね?

VR Freekという雑誌があるのですが、その最後の方に自分でVRコンテンツとしてWebに公開する方法が乗っていました。しかもほとんどコードを書かなくて良い。A-FrameというJavascriptライブラリなのですが、これはいいなと思いました。

A-Frameとは?

WEBブラウザ上で3D空間を表現するためのフレームワークです。難しいことはすべて隠蔽されており、数行のhtmlを記載するだけで簡単に3Dを実現できてしまいます。

詳しくは本家サイトをご覧ください。

aframe.io

ぼちぼち勉強してみて、ブログに乗せていこうと思います。

RICOH THETA S と出会った。

Thetaに出会うまで

ここ最近のセミナーで、AR、VR関係のものが多い。というか興味のあるものを受けてくと、そうなっている。
その延長で、PlaystationVRの体験会にも行ってみた。もう、すごいね。未来だね。没入感半端ない!! って感じにあっさり感化されて、VR関係について俄然興味をもってしまった。この流れはPlayStationVRを予約か?いやいや、PS4本体持っていないし、トータルで9万弱の出費は無理っす。
ってことで、いろいろと考え抜いた挙句に、VRを体験する方ではなく コンテンツを作る方に走ってみようかと思ってしまった。でもね、VRコンテンツってなかなか簡単に作れないんですよ。Unityで3Dコンテンツ作るにも、Unityの勉強と、デザインと、綿密な作り込みと、、、無理無理。コンテンツ作れる人って尊敬する。
ということで、なんとか楽にコンテンツ作れないかなと思って巡り合ったのがThetaです。 うーん、動機が超不純。

買ってみて

こんなのです。

f:id:sgi-don:20160701190658j:plain

みなさん言われるように、超面白い。特に動画が。
バイクに乗るのですが、ハンドルに取り付けて走っているところを録画してみたら、前はもちろん、走っている自分の姿も見れる。
そうそう、自分の運転している姿って始めてみたよ。なんというかこっ恥ずかしいし、超違和感でした。

Youtubeにアップできるみたいなので、走行動画共有してみるのも面白いかなと思っています。
でもちょっと恥ずかしいし、スモークシールド買おうかな。