理解ARKit中的坐标空间

我已经阅读了有关ARKit的所有Apple指南,并观看了WWDCvideo 。 但我无法理解如何绑定系统:

  1. 一个现实世界
  2. 一个装置
  3. 一个3D场景

互相连接。

我可以添加一个对象,例如SCNPlane

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

这将产生一个白色条纹,它将垂直定向,无论该设备将如何定向。 这意味着坐标系以某种方式受到引力的束缚! 但是,如果我尝试每帧打印upAxis 属性 ,它将是相同的,无论我如何旋转iPhone。 我也尝试打印stripeNode.worldTransform ,它也没有改变。

欢迎任何理解ARKit坐标的帮助。

默认情况下,ARKit中的世界坐标系基于ARKit对您设备周围真实世界的理解。 (是的,由于设备的运动感应硬件,它面向重力 。)

此外,默认情况下,当您使用ARSCNView在ARKit会话中显示SceneKit内容时,场景的rootNode的坐标系将与ARKit世界坐标系匹配。 这意味着无论您如何移动设备,场景空间中的“向上”始终与真实世界中的“向上”相同。

upAxis :您找到upAxis的场景属性API并不是您认为的那样。 这些是针对从文件加载的场景的固有设置 – 例如某人向您发送在3D创作工具中设计的DAE文件,其中Z轴表示“向上”,因此该属性告诉SceneKit旋转该文件中的数据以适合SceneKit的Y特征坐标系统约定。

如果要查找某个SceneKit节点相对于世界空间的向上轴,则可以使用worldUpsimdWorldUp属性。 但是,那些与世界空间有关 没有用于询问世界空间本身指向哪个方向的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厘米处)