web-dev-qa-db-ja.com

ARKitの座標空間を理解する

私はすべてのAppleガイド ARKit を読み、 WWDCビデオ を見ました。しかし、どのように座標系を調整するのか理解できません。バインドされています:

  1. 現実の世界
  2. デバイス
  3. 3Dシーン

互いに接続します。

SCNPlaneなどのオブジェクトを追加できます:

let stripe = SCNPlane(width: 0.005, height: 0.1)
let stripeNode = SCNNode(geometry: stripe)
scene.rootNode.addChildNode(stripeNode)

これにより、その時点でデバイスの向きに関係なく、垂直方向に向けられる白いストライプが生成されます。つまり、座標系はどういうわけか重力に拘束されています!しかし、フレームごとにupAxisSCNSceneの属性 を印刷しようとすると、iPhoneをどのように回転させても同じになります。また、stripeNode.worldTransformを印刷しようとしましたが、変更されません。

ARKit座標を理解する上での助けは大歓迎です。

7
kelin

デフォルトでは、ARKitの世界座標系は、デバイス周辺の現実世界に対するARKitの理解に基づいています。 (そして、はい、それは 重力に向けられた 、デバイスのモーションセンシングハードウェアのおかげです。)

また、デフォルトでは、ARSCNViewを使用してARKitセッションでSceneKitコンテンツを表示すると、シーンのrootNodeの座標系がARKitワールド座標系に一致します。つまり、デバイスをどのように動かしても、シーン空間の「上」は実世界の空間の「上」と常に同じです。

余談ですが、 シーン属性APIupAxisを見つけた場所は、あなたが思っているものではありません。これらは、ファイルからロードされたシーンの固有の設定用です。誰かが3Dオーサリングツールで設計されたDAEファイルを送信します。Z軸は「上」を意味します。そのため、属性は、SceneKitのY-up座標系の規則に合うようにそのファイル内のデータを回転するようにSceneKitに指示します。

ワールド空間を基準にしたSceneKitノードの上方軸を見つけたい場合は、 worldUp またはsimdWorldUpプロパティが必要です。ただし、それらは世界空間に対して相対的です。ワールドスペース自体がどの方向を指しているかを尋ねるAPIはありません。これは、他の何かに対する方向を意味するためです...そしてワールドスペースは、他のすべてが相対する「絶対」座標系です。したがって、 定義 に依存する必要があります。

この座標系のマッチングの優れている点は、SceneKitのものを実世界の空間に非常に簡単に配置できることです。明示的に位置を指定しなかったため、コードは_0, 0, 0_に白いストライプを配置します。 ARKitセッションでは、_0, 0, 0_は、セッションを開始したときのデバイスの位置です...したがって、そのコードを実行してから、一歩後退して 白いストライプ を確認できるはずです。 =。


要するに、ARKitの座標系モデルは次のとおりです:世界は固定されており、デバイス/カメラはその中で移動します。

これは、デバイスの現在の位置/向きに関連して何かをしたい場合は、カメラ空間への変換が必要であることを意味します。

SceneKitを使用している場合、それは簡単です。_view.pointOfView_はSceneKitカメラノードを提供するので、次のことができます...

  • そのノードに子ノードを追加すると、移動してもカメラに「接続」されたままになります(たとえば、HUD要素、またはMinecraftのようなものを作成している場合はつるはし)
  • カメラノードを 制約 のターゲットとして使用して、シーン内の他のコンテンツを移動時にカメラと相互作用させます(たとえば、ゲームキャラクターにカメラを見てもらいます)
  • カメラノードの変換(または変換の一部にアクセスするためのさまざまな便利なプロパティ)を使用して、シーン内の他のコンテンツを配置します(たとえば、node.position = view.pointOfView.simdWorldFront + float3(0, 0, -0.5)を使用して、カメラが現在ある場所の50 cm前にノードをドロップします)
23
rickster