【问题标题】:Best way to obtain ARKit or RealityKit camera rotation?获得 ARKit 或 RealityKit 相机旋转的最佳方式?
【发布时间】:2021-04-30 15:10:02
【问题描述】:

我正在用 Swift 编写并尝试获取 RealityKit 相机的旋转。 我已通过以下方式成功获得该职位:

xsettings.xcam = arView.session.currentFrame?.camera.transform.columns.3.x ?? 0);
xsettings.ycam = arView.session.currentFrame?.camera.transform.columns.3.y ?? 0);
xsettings.zcam = arView.session.currentFrame?.camera.transform.columns.3.z ?? 0);

这非常有效,但我还没有找到一个似乎也有效的轮换解决方案。 目前我正在这样做:

xsettings.xcamrot =  arView.session.currentFrame?.camera.eulerAngles[0] ?? 0;
xsettings.ycamrot =  arView.session.currentFrame?.camera.eulerAngles[1] ?? 0;
xsettings.zcamrot =  arView.session.currentFrame?.camera.eulerAngles[2] ?? 0;

但它似乎无法正常工作,滚动中有很多奇怪之处 (eulerAngles[2]) 并且总体上只是有些不一致,至少与出色的定位相比。 只是好奇是否有更好的方法来访问相机的旋转?

【问题讨论】:

    标签: swift augmented-reality arkit realitykit


    【解决方案1】:

    这并不奇怪。 ARKit 或 RealityKit 相机的方向表示为滚动 (z)、俯仰 (x) 和偏航 (y)。因此,您可以使用前面提到的表达式轻松获得正确的值:

    arView.session.currentFrame?.camera.eulerAngles.x
    arView.session.currentFrame?.camera.eulerAngles.y
    arView.session.currentFrame?.camera.eulerAngles.z
    

    However, the order of rotation is ZYX。阅读它here

    还有几个关于下标和点符号的词。每两行都是一样的:

    DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
        // Pitch
        print(arView.session.currentFrame?.camera.eulerAngles[0])  // -0.6444593
        print(arView.session.currentFrame?.camera.eulerAngles.x)   // -0.6444593
        // Yaw
        print(arView.session.currentFrame?.camera.eulerAngles[1])  // -0.69380975
        print(arView.session.currentFrame?.camera.eulerAngles.y)   // -0.69380975
        // Roll
        print(arView.session.currentFrame?.camera.eulerAngles[2])  // -1.5064332
        print(arView.session.currentFrame?.camera.eulerAngles.z)   // -1.5064332
    }
    

    这是因为 ARView 相机的 eulerAngles 实例属性是支持下标和点符号的 SIMD3<Float>(又名 simd_float3)类型。

    另一方面,ARSCNView pointOfView 的eulerAngles 实例属性是SCNVector3 类型,不支持下标但支持点表示法。

    附言

    您不需要(也不能)显式分配a rotation order,因为它是隐式的内部旋转机制。

    【讨论】:

    • 谢谢,我在发布后不久偶然发现了这一点。看起来确实更好,但我很困惑,说 eulerAngles.x 和 eulerAngles[0] 之间有区别吗?还是如你所说,我的订单错了?
    • 谢谢你,但我想我需要进一步研究,因为它仍然很“奇怪”,这意味着虽然位置表现正确,但我得到了像 x 这样的东西。在一帧 -31 旋转,然后在下一帧 +31。
    • 1) 这取决于您的虚拟世界网格的方向。每次启动 AR 应用程序时,World Grid 的方向都不同,因为它建立在运行 ARSession 的第一帧之上,并且取决于您在特定时刻的设备方向(在现实世界中)。您无法保证每次启动应用程序时设备的方向都相同。例如:上一次您的 3D 虚拟网格是面向现实世界的北向,但下一次它将是面向现实世界的东向。 2) 有时(不经常)在 iPhone 的陀螺仪中发生万向节锁定 - en.wikipedia.org/wiki/Gimbal_lock
    【解决方案2】:

    您可能最好将四元数用于旋转,具体取决于您想要对输出做什么。

    您也可以使用arView.cameraTransform 来获取相机的变换。从那里,可以从arView.cameraTransform.translation.{x,y,z} 进行平移,并使用arView.cameraTransform.rotation 进行四元数旋转。四元数的好处之一是轮换顺序不会有问题。

    如果您仍想获得欧拉旋转,您可以随时使用 MDLTransform:
    MDLTransform(matrix: self.cameraTransform.matrix).rotation.{x,y,z}

    【讨论】:

    • 这对我来说是最充分的解决方案。它不需要任何数学运算,并且可以轻松直接地将旋转应用于实体。仍然没有得到 currentFrame.camera.transform 矩阵和 arView.cameraTransform 之间的区别……
    • 我在这里发布了一个专门的问题:stackoverflow.com/questions/68193399/…
    猜你喜欢
    • 2018-01-30
    • 2018-07-21
    • 2021-01-01
    • 2018-03-26
    • 2020-10-04
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多