SessionOrigin を理解する
SessionOrigin は AR Foundation で導入された比較的新しい実装ですが、この概念はレンダリングエンジンの数十年前からカメラリグに登場しています。 MRTK Playspace ノードとしてお馴染みかもしれません。 非常にパワフルなのですが、残念ながら説明が不十分で、その結果、理解度が低いのです。
SessionOrigin とは?
SessionOrigin は、カメラが接続されている Transform オブジェクトに過ぎません。 最もわかりやすいのは、仮想シーンにカメラを配置できることです。 より微妙に、それは特別な座標空間を定義します。
Unity (およびすべての最新のレンダリング エンジン) の transform 親子関係でよくあるように、「移動している」 親が 子を 「移動」 します。 この文脈での 「移動」 という用語は、親のグローバルポーズが変わると子のグローバル座標が変わり、あるオブジェクトのグローバル座標が変わると、そのオブジェクトはグローバル座標が変わっていないオブジェクトに対して相対的に移動したように見えるということです。
その意味で、レンダリングされないカメラはむしろ特殊です。 レンダラーの視点を決定します。 具体的な例を挙げれば、明確になるかもしれません。
SessionOrigin の最も単純な例
起動時にカメラが原点にあり (AR アプリケーションでは普通)、カメラの 10メートル手前の Z 軸上に赤い球体が 1 つ置かれている(位置 = (0,0,10))という非常に簡単なシーンを想像してみてください。
何らかの理由で、ユーザーに球体から 1 メートル離れたところからスタートさせたい場合を想像してください。
2 つの興味深いオプションがあります。
- カメラを新しい位置 (0、0、9) に移動します。
- 球体を新しい位置 (0、0、1) に移動します。
この2つの選択肢は、他の文脈を抜きにしても、究極的に同等であることは一目瞭然です。 どちらの場合も、起動時には球体はカメラの前方 1m に位置しています。 唯一の違いは、2 つのオブジェクトの絶対的なグローバル座標です。 両者の相対座標、つまり両者の間のベクトルは、どちらの場合も同じです。
1 のオプションを使う場合、どのようにすればいいのでしょうか。 カメラの座標を設定すると、トラッキング システムによって上書きされます。 その代わり、カメラを親オブジェクトに接続して、親を移動させます。 トラッカーはカメラのローカル ポーズを設定し、親に対して相対的にカメラを移動させます。 これで、親が SessionOrigin になりました。
なぜ球体ではなく、カメラを動かすのでしょうか。
この簡単なケースでは、2 つのオプションは明確に交換可能です。 ただし、 「球体」 は実際 「シーン内のカメラ以外のすべてのもの」 を表すことに注意してください。 シーンが複雑になればなるほど、すべてを動かすのはより複雑になります。 SessionOrigin 経由でのカメラの移動は、常にまったく同じ操作になります。
さらに、パーティクル システムやナビゲーション メッシュなど、位置の変更が難しい、あるいは不可能な種類のオブジェクトももあります。 しかし、たとえそのようなことがなくても、シーン内の 1 つのオブジェクトである SessionOrigin の座標を変更することには、他のすべてのもののグローバル座標を変更することに比べて、明らかな利点があります。
SessionOrigin はすべてを動かす必要はない
最も簡単な例でもう一度考えてみましょう。 しかし、これは AR アプリケーションなので、レンダリングされた赤い球体とともに、ユーザーは物理的な環境も見ることになります。 わかりやすくするために、物理的な環境を図のように緑色の椅子 1 つに限定することにします。
ここで、SessionOriginを経由してカメラを移動すると、赤い球体に対して椅子は相対的に移動しますが、明らかにユーザーを選択して緑の椅子を相対的に移動していません。 球体は近くに見えるますが、椅子の位置は全く同じです。
椅子の座席にアンカーがある場合はどうでしょうか。 アンカーを赤の球と一緒に移動するか、椅子の座席を基準にして固定したままにしますか。 アンカーは物理的な世界に対して固定されていることが重要なので、明らかに椅子と一緒にとどまる必要があります。
もう一つの例は、空間メッシュです。 これは、コンテキストやレイ キャスティングなどのために、物理環境の仮想版を提供するために生成されるメッシュです。 空間メッシュは物理世界に固定されたままであることが絶対条件です。
さらに、手のメッシュや視線ベクトルなど、さまざまな例を挙げることができます。 カメラの座標を調整 (変換された) すれば、それらのオブジェクトの座標も同じように調整されるという共通した特徴があります。
つまり、概念的には、カメラと協調して動くこれらのオブジェクトも、すべて SessionOrigin に接続されていることになります。 SessionOrigin が赤い球体のようなグローバルなオブジェクトに対して相対的に移動すると、それらのオブジェクトがすべて一緒に移動してしまいます。
重要なのは、これがヘッド トラッキングによるカメラの動きと無関係であることです。 トラッカーは、SessionOrigin を基準としてカメラを移動させます。
もう少し数学的な説明
Unity のグローバル座標系は、AR アプリケーションの既定では、やや任意に配置されています。 重力ベクトル (Y軸) を「上」に揃える以外は、位置と向きはすべてトラッカーが起動時にカメラを置く位置で決まります。
多くのアプリケーションではそれでいいのかもしれませんが、グローバル座標空間が持つその任意性を取り除くことができれば、さまざまな可能性が広がります。
先ほどの例に戻って、仮想の赤い球体が物理的な椅子に対して図のように位置することがアプリケーションにとって重要であると想像してください。 SessionOrigin を調整することで、それを実現できます。
(0、0、10) にある球体を椅子から X 軸方向に 1 メートル離したい場合、椅子を (-1、0、10) に位置するようにします。 カメラが原点にあるとき、カメラが負の Z 軸に沿って椅子から直接 2 メートル後ろにあると決定すると、現在の椅子は (0、0、2) になります。 (物理オブジェクトは固有の座標を持たず、カメラと仮想オブジェクトの近接によって暗示される座標のみを持つことに注意してください)。
しかし、SessionOrigin 変換を (-1、0、8) に設定すると、今度はカメラの位置が (-1、0、8) になります。 真正面から 2 メートル先の椅子は (-1、0、10) にあります。 そして、(0、0、10) にある赤い球体は、予想通り椅子の右側 1 メートルに現れます。
つまり、SessionOrigin 変換を効果的に使って Unity のグローバル空間を再配置し、赤い球体や他のすべてのグローバル オブジェクトが、物理世界に対して正しい位置に表示されるようにしました。
Unity のグローバル座標空間を物理世界に合わせるという、簡単かつ強力なこの仕組みを活用することで、複雑なレイアウト、座標空間の永続化、デバイス間での座標空間の共有などをサポートできます。