使用旋转获取一个SCNNode的边界体积

3

我使用XCode级别编辑器设置了一个非常简单的场景。

enter image description here

正如您所看到的,其中一个1x5的矩形立方体已经旋转了90度。这是通过在节点检查器中将欧拉角属性的y属性设置为90来实现的。

enter image description here

但请注意,边界框不考虑长方体的旋转。当我在场景中遍历SCNNodes时也是如此。两个长方体都有相同的边界体积。
for wall:SCNNode in walls.childNodes {
    var v1 = SCNVector3Zero
    var v2 = SCNVector3Zero
    wall.getBoundingBoxMin(&v1, max:&v2)
    print(v1, v2)
}

// Prints
// SCNVector3(x: -0.5, y: 0.0, z: -2.5) SCNVector3(x: 0.5, y: 0.5, z: 2.5)
// SCNVector3(x: -0.5, y: 0.0, z: -2.5) SCNVector3(x: 0.5, y: 0.5, z: 2.5)

因此,似乎使用子节点自己的坐标系计算Bounding Volume,而不是节点父级(或场景)的坐标系。这让我想知道; 我如何计算场景中SCNNode的Bounding Volume?
查看SCNNode文档,似乎所有信息都在那里。我可以读取eulerAngles,它给出了正确的绕y轴旋转。我可以读取transform属性。
我想我可以通过节点的变换矩阵来乘以向量,但变换矩阵(4x4)和边界框向量(1x3)似乎不兼容。SceneKit似乎也没有提供任何将变换矩阵应用于向量的方法。然而,我对几何学不太擅长,可能会错过一些明显的东西。
1个回答

5
一些想法:
  1. 在界面生成器中(如您的屏幕截图所示),有一个名为“Editing space”的属性,您可以将其设置为“World”(而不是“Local”)。

  2. 在代码中,您可以使用临时节点来计算边界框。确保它只有一个子节点(您要计算边界框的节点),对该子节点应用任何变换,然后询问 父节点 其边界框。从文档中得知:

包含子节点的节点的边界体积是最小的体积,它包围了节点的子节点的边界体积。

  1. 获取节点的边界框,然后使用诸如 -convertPosition:toNode: 的实用工具来计算另一个坐标系中的边界框。

谢谢。第1点 - 当处于“World”模式时,我没有调整旋转的选项。我认为第3点无效。它没有考虑旋转。我采用了第2点的变体-我的所有Wall Nodes都是Walls(复数)节点的子级。所以我遍历所有子节点,将它们的隐藏属性设置为true。然后我再次遍历子节点,但这次是将hidden设置为false,获取WallsNode的boundingBox,然后再次将隐藏属性设置为true。完成所有需要做的事情后,我再次在所有墙节点上将hidden设置为false。 - gargantuan
2
这真的是最聪明的做法吗?似乎知道节点的边界体积应该是一个非常普遍的情况。而这种方法感觉非常笨拙、不直观,达成目标的方式并不好。 - gargantuan
1
第3点也应该可以工作。您必须将8个位置(边界框的每个角落)转换为新的坐标空间中的最小和最大值沿每个轴找到。 - mnuages
基本上,您可以使用-convertVector:toNode:方法来获取节点包围框的最小/最大值。 - Alex

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