旋转整个AR会话轴以与现实世界的North-West-Up对齐

问题描述

我正在尝试对我的 entire AR会话进行轮换,以使AR会话世界的坐标与现实世界的西北向上对齐。我正在使用Xcode 12.0.1。我曾尝试在Google上找到它,但没有找到我想要的东西。任何帮助或指向正确的主题,我们将不胜感激。 (是否有其他发布位置?)

我有一个函数,它可以接收真实的纬度/经度/海拔坐标并返回X-Y-Z。这些X-Y-Z值似乎正常工作。那是当纬度/经度在我的北方(在现实世界中)时,我在AR中绘制的球面在正X轴(会话的世界轴)上,而经纬度在我的西面正Y轴。到目前为止,一切都很好。

下一步是使AR Session世界坐标轴(X-Y-Z)与现实世界的西北向上轴对齐。从会话开始时的坐标系看(水平面上的X和Z,Y向上),看来我应该做两个简单的旋转:-pi / 2绕X来使水平面上的Y和Z向上,然后绕新Z旋转以使X指向北方。

我的UIViewController内部有一个ARSCNView。我有一个配置:

 private let configuration = ARWorldTrackingConfiguration()

然后在viewDidLoad()中设置调试选项以显示会话的坐标

self.asSceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin,… ]

稍后(在viewDidLoad之后),通过单击按钮,我称一个函数为:1)获取相机变换,2)对变换进行旋转,以及3)使用所得的旋转变换设置世界原点。 / p>

guard let transform = self.arSceneView.session.currentFrame?.camera.transform else {… }
let newMat = SCNMatrix4Rotate( SCNMatrix4( transform ),minus90,1,0) // minus90 is in radians
self.arSceneView.session.setWorldOrigin( relativeTransform: sind_float4x4( newMat) )

结果是一些奇怪的旋转/平移的世界轴。并不奇怪,它不能按照我认为的方式工作,但是为了调试和理解它,我需要对过程有更好的了解。

问题1:camera.transform与setWorldOrigin? 摄影机转换和worldOrigin之间有什么联系/关系?我得到并打印了整个旋转过程中的camera.transform,并且camera.transform从未更改过,即使将worldOrigin设置为其他转换矩阵也是如此。

问题2:何时设置camera.transform,您怎么知道? 我一直通过viewWillLoad(0和viewDidLoad()检查…camera.transform,它始终为nil。我在会话开始后(不是nil时)添加一个按钮进行检查(并旋转)。 “肯定有更好的方法。何时设置?知道何时设置的正确方法是什么?

问题3:关于轮换AR会话还有其他建议吗? 我的方法完全不可行吗?我应该使用其他方法吗?我还需要其他哪些主题或关键词?

谢谢, 里克

解决方法

FYI:我还没有找到改变ARKit相机变换的方法,并且您不应该改变rootNode的变换(根据Apple),所以我通过插入一个节点解决了我的特殊问题(我称之为ARKit rootNode和场景的其余部分之间的myRootNode)。我所有绘制的元素节点都附加到myRootNode或myRootNode的子级。我将旋转应用于myRootNode,然后旋转场景中的所有内容(ARKit WorldAxes除外,因此我还要绘制自己的图像)。

要获取ARKit坐标(在运行ARSCNView会话时设置)以与X向北,Y向西和Z向上对齐,请使用以下旋转:

// point X-axis in the right direction
let yRot = appleHeadingAtRunRad + Double.pi/2.0
var mat = SCNMatrix4Rotate(SCNMatrix4Identity,Float(yRot),1,0)

// put Y-axis in plane parallel to ground,Z up
let xRot = -Double.pi/2.0
mat = SCNMatrix4Rotate(mat,Float(xRot),0)
myRootNode.transform = mat