【问题标题】:ARKit vs SceneKit coordinatesARKit 与 SceneKit 坐标
【发布时间】:2017-11-27 16:27:15
【问题描述】:

我试图了解 ArKit 中引入的不同元素与 SceneKit 中的可能等效元素之间的区别:

  • SCNNode.simdTransformSCNNode.transform。在 ARKit 中,人们似乎使用SCNNode.simdTransform 而不是SCNNode.transform。它们有何不同? simdTransform 似乎使用列主要顺序,而变换(SCNMatrix4)是行主要顺序。如何将一种转换为另一种?只是转置?我的印象是,如果我使用transform 而不是simdTransform,则跟踪效果不佳。这是预期的还是只是印象?如果我设置了一个属性,如果我再设置另一个属性会怎样?

  • ARFrame.camera vs Scene.pointOfView:看看他们的转换,他们似乎有点不同:

.

// ARFrame.camera.transform (matrix_float4x4)
-0.01 0.99  -0.11 0.02
-0.99 0.00  0.11  0.06
0.10  0.11  0.98  0.0
0.0   0.0   0.0   1.0

// sceneView.pointOfView.transform (SCNMatrix4)
// or sceneView.pointOfView.simdTransform^T (matrix_float4x4)
0.99  0     0.11   0
0.01  0.99  -0.12  0
-0.11 0.11  0.98   0
0.03  0.6   0.0    0.99

它们是否相同减去一圈?

【问题讨论】:

  • “我的印象是,如果我使用 transform 而不是 simdTransform,跟踪效果也不好。这是预期的还是只是印象?” ;-)只有您可以判断这只是您的印象还是您有确凿的证据,例如通过查看 Xcode 日志说明 [Technique] 世界跟踪性能受到资源限制的影响 告诉我们是否是后者,那将非常有趣。

标签: scenekit ios11 arkit


【解决方案1】:

SceneKit 和 ARKit 都包含定义为 SIMD 类型的符号。由于 ARKit 导入 SceneKit,因此在 SceneKit 中定义的 SIMD 符号可供两者访问。 SIMD 类型支持并行计算,因此使用它们可以提高应用更新逻辑的性能。正如您所发现的,在 SIMD 类型与其较旧的 SceneKit 或 Core Graphics 等价物之间进行转换并不总是一种方便的方法,因此您通常可以通过在可能的情况下始终使用 SIMD 来获得更简洁的代码。

更新任何影响节点变换的属性也会更新其其他变换属性。这也适用于本地和世界坐标。

ARFramecamera 属性描述了设备的硬件摄像头,而不是用于渲染场景的虚拟摄像头。虽然我希望有密切的对应关系,但我的猜测是您在渲染循环期间更新 SCNCamera 实例之前轮询 ARCamera 实例。如果可以的话,我建议从适当的委托方法驱动这些更新,因为您会知道相关数据是最新的。

【讨论】:

  • 很好的总结。有关ARAnchorSCNNode 定位的更多信息,另请参阅this answer
【解决方案2】:

我不认为SCNMatrix4 像您所说的那样遵循行主要约定。考虑以下几点:

func makeTranslationMatrix(tx: Float, ty: Float, tz: Float) -> simd_float4x4 {
    var matrix = matrix_identity_float4x4

    matrix[3, 0] = tx
    matrix[3, 1] = ty
    matrix[3, 2] = tz

    return matrix
}

var T1 = makeTranslationMatrix(tx: 1, ty: 2, tz: 3)
print(T1.columns.0)
print(T1.columns.1) 
print(T1.columns.2) 
print(T1.columns.3) 
/*
T1
float4(1.0, 0.0, 0.0, 0.0)
float4(0.0, 1.0, 0.0, 0.0)
float4(0.0, 0.0, 1.0, 0.0)
float4(1.0, 2.0, 3.0, 1.0)
*/

var sceneT1 = SCNMatrix4MakeTranslation(1, 2, 3)
print("\(sceneT1.m11), \(sceneT1.m12), \(sceneT1.m13), \(sceneT1.m14)")
print("\(sceneT1.m21), \(sceneT1.m22), \(sceneT1.m23), \(sceneT1.m24)")
print("\(sceneT1.m31), \(sceneT1.m32), \(sceneT1.m33), \(sceneT1.m34)")
print("\(sceneT1.m41), \(sceneT1.m42), \(sceneT1.m43), \(sceneT1.m44)")
/*
sceneT1
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
1.0, 2.0, 3.0, 1.0
*/

如您所见,SCNMatrix4 的翻译值存储在m41, m42, m43 - 第 4 列中。由于矩阵被转置,这些值可能存储在m41, m42, m43 中,然后它们实际上将平移值存储在第 4 行中。这个question 涵盖了这种困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2018-12-25
    • 2017-12-29
    • 2020-02-09
    • 2018-03-09
    相关资源
    最近更新 更多