【问题标题】:Understand coordinate spaces in ARKit了解 ARKit 中的坐标空间
【发布时间】:2018-03-09 00:12:49
【问题描述】:
我已阅读所有有关 ARKit 的 Apple 指南,并观看了 WWDC video。但我不明白如何绑定到的坐标系:
- 一个真实的世界
- 一个设备
- 3D 场景
相互连接。
我可以添加一个对象,例如SCNPlane:
let stripe = SCNPlane(width: 0.005, height: 0.1)
let stripeNode = SCNNode(geometry: stripe)
scene.rootNode.addChildNode(stripeNode)
这将产生一条垂直方向的白色条纹,无论此时设备的方向如何。这意味着坐标系以某种方式与重力绑定!但是如果我尝试每帧打印upAxisattribute of the SCNScene,无论我如何旋转iPhone,它都是一样的。我也尝试打印stripeNode.worldTransform,它也没有改变。
欢迎任何有助于理解ARKit 坐标的帮助。
【问题讨论】:
标签:
ios
swift
3d
augmented-reality
arkit
【解决方案1】:
默认情况下,ARKit 中的世界坐标系基于 ARKit 对您设备周围真实世界的理解。 (是的,它是oriented to gravity,这要归功于设备的运动感应硬件。)
此外,默认情况下,当您在 ARKit 会话中使用 ARSCNView 显示 SceneKit 内容时,场景的 rootNode 坐标系与 ARKit 世界坐标系相匹配。这意味着无论您如何移动设备,场景空间中的“向上”始终与现实世界空间中的“向上”相同。
除此之外:您在其中找到upAxis 的scene attributes API 并不是您认为的那样。这些用于从文件加载的场景的固有设置 - 例如有人向您发送了一个在 3D 创作工具中设计的 DAE 文件,其中 Z 轴表示“向上”,因此该属性告诉 SceneKit 旋转该文件中的数据以适应 SceneKit 的 Y-up 坐标系统约定。
如果你想找到某个 SceneKit 节点相对于世界空间的上轴,worldUp 或 simdWorldUp 属性就是你想要的。然而,这些是相对于世界空间。没有 API 可以询问世界空间本身指向的方向,因为这意味着相对于其他事物的方向……而世界空间是其他一切都相对的“绝对”坐标系。所以你必须依赖definition。
这种坐标系匹配的好处在于,您可以非常轻松地将 SceneKit 的东西放在现实世界的空间中。您的代码在0, 0, 0 处放置了一条白色条纹,因为您没有明确地给它一个位置。在 ARKit 会话中,0, 0, 0 是您开始会话时设备的位置……因此您应该能够运行该代码,然后后退一步以查看您的 white stripe。
简而言之,ARKit 的坐标系模型是这样的:世界是固定的,你的设备/相机在其中移动。
这意味着,如果您想对设备的当前位置/方向进行任何操作,则需要转换为相机空间。
如果您正在使用 SceneKit,这很容易:view.pointOfView 为您提供 SceneKit 相机节点,因此您可以...
- 将子节点添加到该节点,当您移动它时,它们将保持“连接”到相机(例如 HUD 元素,或者如果您正在制作类似 Minecraft 的游戏,则可能是镐)
- 使用相机节点作为constraint 的目标,使场景中的其他内容在您移动时与相机交互(例如,让游戏角色看着相机)
- 使用相机节点的变换(或用于访问部分变换的各种便利属性)来定位场景中的其他内容(例如
node.position = view.pointOfView.simdWorldFront + float3(0, 0, -0.5) 将节点放置在相机当前位置前方 50 厘米处)