ARKit节点在sceneView.session.setWorldOrigin转换后消失

5

我有一些代码,包括获取标题的委托方法和一个转换方法。我将标题转化为弧度,并使用该角度绕y轴旋转:

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

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时,它会移除所有节点。我已经尝试暂停会话、运行函数,然后再次启动会话,但是获得了奇怪的低帧率、低光照情况。我知道这是对setWorldOrigin的函数调用,因为当我将其删除时,我可以看到节点并且它们仍然存在。
更新:
我一直在尝试解决这个问题,通过简单地尝试将比例增加2来进行调试...所有我放置在网格中的节点应该会分散开来...然而我仍然得到相同的结果。在尝试使用setWorldOrigin之后,节点被移除了。使用这个函数会重置什么吗?我应该在特定的位置使用它吗?(某些委托函数)?
更新: print("\(sceneView.scene.rootNode) --- rootNode in renderer")产生以下结果:
<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

然而...我没有看到任何孩子节点...所以根节点似乎在其他地方。

更新

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

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

更新

目前我对这个问题的最狭义看法是,即使是简单的旋转也会使节点消失在视野中...由于没有位置变化...我认为这意味着渲染过程中发生了一些事情。

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)

...

上述内容没有任何转换...节点仍然可见。
如果我将矩阵更改为以下内容(向右和向下平移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://zh.wikipedia.org/wiki/Z测试

2个回答

3

在解决缩放问题之后,我缩小了世界的大小(比例),并将物体彼此分开一点(以修复闪烁/“z-fighting”)- 维基百科的页面非常有帮助,我相信我所需要做的就是缩小世界大小。


0

嘿,在查看您的代码后,我注意到您在绕y轴旋转时设置了错误的4x4矩阵。

您当前的设置如下。

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]

根据交换,正确的格式如下: https://math.stackexchange.com/questions/72014/given-an-angle-in-radians-how-could-i-calculate-a-4x4-rotation-matrix-about-the

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]

这应该能让它为您工作。

根据您想要在场景中做什么,我建议取当前方向和上一个方向之间的差值,并将其用作您的角度。理论上,这应该使场景始终面向您相同的方向。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接