ios - ARKit 节点在 sceneView.session.set World Origin 转换后消失

标签 ios swift matrix location transform

我有一些代码由用于获取标题和转换的委托(delegate)方法组成。我采用航向并将其转换为弧度并使用角度绕 y 轴旋转:

    ┌                             ┐
Y = |  cos(ry)    0   sin(ry)   0 |
    |  0          1   0         0 |
    |  -sin(ry)   0   cos(ry)   0 |
    |  0          0   0         1 |
    └                             ┘

What are the first two columns in SCNMatrix4

代码:

func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        print("received heading: \(String(describing: newHeading))")
        self.currentHeading = newHeading
        print("\(Float(currentHeading.trueHeading)) or for magneticHeading: \(currentHeading.magneticHeading)")
        let headingInRadians = degreesToRadians(deg: Float(currentHeading.trueHeading))
        print("\(headingInRadians) -------- headingInRadians")

        var m = matrix_float4x4()
        m.columns.3 = [0.0, 0.0, 0.0, 1.0]
        m.columns.2 = [sin(headingInRadians), 0.0, cos(headingInRadians), 0.0]
        m.columns.1 = [0.0, 1.0, 0.0, 0.0]
        m.columns.0 = [cos(headingInRadians), 0.0, -sin(headingInRadians), 0.0]

        sceneView.session.setWorldOrigin(relativeTransform: m)
    }

当我调用 setWorldOrigin 时,它正在删除所有节点。我试过暂停 session ,运行函数,然后再次启动 session ,但我遇到了这种奇怪的低帧率、低光情况。我知道这是对 setWorldOrigin 的函数调用,因为当我删除它时,我看到了节点并且它们持续存在。

更新

我一直在研究这个...我正在通过简单地尝试将比例更改为 2 来进行调试...我应该看到的是我放置在网格中的节点应该展开...但是我仍然得到相同的结果。在尝试 setWorldOrigin 后,节点被删除。使用此功能会重置某些东西吗?有什么特别的地方我应该使用它吗? (一些委托(delegate)功能)?

更新

print("\(sceneView.scene.rootNode) --- 渲染器中的 rootNode") 产生:

<SCNNode: 0x1c01f8100 | 111 children> --- rootNode in renderer

所以看起来 rootNode 和它的 children 仍然在某个地方......但是他们要用这么简单和小的转换去哪里?

更新

print("\(sceneView.scene.rootNode.position) --- 渲染器中的 rootNode") 产生:

SCNVector3(x: 0.0, y: 0.0, z: 0.0) --- rootNode in renderer

然而...我没有看到任何 child ...所以 rootNode 似乎在其他地方。

更新

我可以确认转换没有发生......子节点的定位(我看不到)仍然与其原始状态相同(每 2 个网格 block (米)一个节点,即:

SCNVector3(x: 6.0, y: 0.0, z: -4.0) --- rootNode child node
SCNVector3(x: 6.0, y: 0.0, z: -2.0) --- rootNode child node

更新

我现在对这个问题的最狭隘的看法是,即使是简单的旋转也会从 View 中删除节点......因为没有位置变化......这意味着我相信渲染过程正在发生某些事情。

func viewDidLoad() {    

    ...

    sceneView.scene = scene
    view.addSubview(sceneView)

    let angle = coordinateConverter.getUprightMKMapCameraHeading()
    print("\(angle) --- angle")

    mRotate = matrix_float4x4()
    mRotate.columns.3 = [0.0, 0.0, 0.0, 1.0]
    mRotate.columns.2 = [Float(sin(angle)), 0.0, Float(cos(angle)), 0.0]
    mRotate.columns.1 = [0.0, 0.0, 0.0, 0.0]
    mRotate.columns.0 = [Float(cos(angle)), 0.0, Float(-sin(angle)), 0.0]

    sceneView.session.setWorldOrigin(relativeTransform: mRotate)

控制台输出:

281.689248803283 --- angle

仍然,虚拟对象仍然不可见,但放置在原点......应该仍然相同。

我还应该注意到标准的 1,1,1,1 转换确实有效...但显然,它什么也没做...但我想仅仅使用该函数并不能使它们消失...它们只会如果你的转换确实做了一些事情就会消失......

...

var identity = matrix_float4x4()
identity.columns.3 = [0.0, 0.0, 0.0, 1.0]
identity.columns.2 = [0.0, 0.0, 1.0, 0.0]
identity.columns.1 = [0.0, 1.0, 0.0, 0.0]
identity.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: identity)

...

以上内容没有进行任何转换...并且节点仍在 View 中。

如果我将矩阵更改为此(按 10,10 翻译):

var identity = matrix_float4x4()
identity.columns.3 = [10.0, 0.0, 10.0, 1.0]
identity.columns.2 = [0.0, 0.0, 1.0, 0.0]
identity.columns.1 = [0.0, 1.0, 0.0, 0.0]
identity.columns.0 = [1.0, 0.0, 0.0, 0.0]

有效...

我只是在想...我是否必须缩小我的世界(真实世界的 MKMapKit 坐标/单位)可能是因为硬件无法处理缩放的世界。另外,从上面的测试中……我想我意识到当你使用这个函数时原点会移动,但节点不会,所以如果我想让节点在变换后保持在我的位置……我需要把它们变回来。尽管如此,结果是一样的:

print("\(transformerFromPDFToMk.tx) -- tx")
print("\(transformerFromPDFToMk.ty) -- ty")

m = matrix_float4x4()
m.columns.3 = [Float(transformerFromPDFToMk.tx), 0.0, Float(transformerFromPDFToMk.ty), 1.0]
m.columns.2 = [0.0, 0.0, 1.0, 0.0]
m.columns.1 = [0.0, 1.0, 0.0, 0.0]
m.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: m)

for node in scene.rootNode.childNodes {
    node.position = SCNVector3Make(-Float(transformerFromPDFToMk.tx) + node.position.x, node.position.y, Float(transformerFromPDFToMk.ty) + node.position.z)
}

控制台输出:

81145547.3824476 -- tx
99399579.5362287 -- ty

更新

我看到了我的对象(有点)!我以为我以前试过这个……但现在它工作得更好了 - 我使用的代码包定义了一个比例尺 (coordinateConverter.unitSizeInMeters)...我没有正确地转换成它。但是......它们正在快速闪烁......

m = matrix_float4x4()
m.columns.3 = [Float(transformerFromPDFToMk.tx) / Float(coordinateConverter.unitSizeInMeters), 0.0, Float(transformerFromPDFToMk.ty) / Float(coordinateConverter.unitSizeInMeters), 1.0]
m.columns.2 = [0.0, 0.0, 1.0, 0.0]
m.columns.1 = [0.0, 1.0, 0.0, 0.0]
m.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: m)

sceneView.session.setWorldOrigin(relativeTransform: m)

for node in scene.rootNode.childNodes {
    node.position = SCNVector3Make(-Float(transformerFromPDFToMk.tx) / 
       Float(coordinateConverter.unitSizeInMeters) + node.position.x / 
       Float(coordinateConverter.unitSizeInMeters), node.position.y / 
       Float(coordinateConverter.unitSizeInMeters), -
       Float(transformerFromPDFToMk.ty) / 
       Float(coordinateConverter.unitSizeInMeters) + node.position.z / 
       Float(coordinateConverter.unitSizeInMeters))
}

更新

闪烁的“z-fighting”是吗? https://en.wikipedia.org/wiki/Z-fighting

最佳答案

解决缩放问题后,我减小了世界的大小(缩放)并将对象彼此分开一点(以修复闪烁/“z-fighting”)——维基百科的页面非常有帮助,我我很确定我需要做的就是缩小世界大小。

关于ios - ARKit 节点在 sceneView.session.set World Origin 转换后消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48919069/

相关文章:

iphone - 在键盘顶部添加一个可点击的 "Done"UIButton

ios - PhaseScriptExecution 因构建 IOS 的 jenkins 中的非零退出代码错误而失败

matlab - 使用不匹配的向量创建矩阵

python - 在稀疏 lil_matrix (Scipy/Python) 中查找最大值及其索引

ios - swift 项目的 Objective C opencv 包装器看不到 STL header

ios - 核心数据,根据对象自身属性搜索对象

swift - 正则表达式只有在字符串有前缀时才做某事

json - 将本地字典复制到全局字典中

ios - Swift Firebase UICollectionView - 图像缩略图不一致

c - 如何在c中创建一个像1000行和列的大矩阵?