了解ARKit中的3D对象变换属性

时间:2018-08-05 23:37:43

标签: ios swift 3d scenekit arkit

比方说,我在ViewDidLoad中场景的根节点中添加了3D模型(例如狗)作为子节点。我打印出了狗节点的transformworldTransform属性,它们都是4x4的身份矩阵。

旋转,缩放和定位后,我重新打印了transformworldTransform属性。我不明白如何阅读它们。哪一列涉及位置,大小或方向?

在任何变换下,我如何找出1)狗的前脸朝向哪个方向,假设在viewDidLoad中狗的前脸朝向(0,0,-1),并且2)高度和宽度狗的?

1 个答案:

答案 0 :(得分:2)

关于变换矩阵的完整介绍是:a)超出了简单的SO答案的范围,并且b)3D图形编程中的一个基本主题,您可以找到大量或两本关于该主题的书籍,教程和资源。这是两个不错的文章:

但是,由于您在SceneKit中使用ARKit,因此有许多方便的实用程序可用于转换,因此您通常不需要深入研究数学。

  

狗的正面朝哪个方向?

节点在其局部坐标空间中始终“面向” (0,0,-1)。 (请注意,这是SceneKit的“面对”的内在概念,它可能会映射也可能不会映射到任何自定义资产的设计方式。如果您导入了OBJ,DAE或3D创作工具中内置的任何文件,并且在该工具中狗的鼻子指向(0,0,-1),您的狗正对着“正确”的方向。)

您可以从SCNNode.simdLocalFront获得此方向-请注意,这是一个静态/类属性,因为在局部空间中,对于所有节点而言,前部始终是相同的方向。

您可能更感兴趣的是节点自己的“前端”概念如何转换为世界空间-也就是说,相对于场景的其余部分,这只狗是面对的。这有两种方法可以实现:

  1. Convert simdLocalFront进入世界空间,您可以使用任何其他矢量:node.convert(node.simdLocalFront, to: nil)。 (请注意,如果您将to参数保留为零,则会转换为世界空间。)

  2. 使用simdWorldFront属性,该属性将为您完成转换。

  

狗的身高和宽度?

高度和宽度与变换无关。转换会(主要)告诉您某物在何处以及其面对的方式。

但是,假设您尚未缩放节点,则其在本地空间中的边界框将描述其在世界空间中的尺寸:

let (min, max) = node.boundingBox
let height = abs(max.y - min.y)
let width = abs(max.x - min.x)
let depthiness = abs(max.z - min.z)

(不过请注意,这是固有高度:例如,如果您有一个直立的人体模型,然后旋转它使其躺下,则该高度仍然是从头到脚的。)