我有这个代码:
let box = SCNBox(width: 1, height: 2, length: 4, chamferRadius: 0.2)
box.firstMaterial?.diffuse.contents = UIColor.yellow
box.firstMaterial?.emission.contents = UIColor.green
let boxNode = SCNNode(geometry: box)
print(boxNode.boundingBox)
boxNode.eulerAngles = SCNVector3(0.785, 0.5, 0.5)
print(boxNode.boundingBox)
boxNode.scale = SCNVector3(1.3, 2.3, 3.3)
print(boxNode.boundingBox)
scene.rootNode.addChildNode(boxNode)
我得到了这个:
(min: __C.SCNVector3(x: -0.5, y: -1.0, z: -2.0), max: __C.SCNVector3(x: 0.5, y: 1.0, z: 2.0))
(min: __C.SCNVector3(x: -0.5, y: -1.0, z: -2.0), max: __C.SCNVector3(x: 0.5, y: 1.0, z: 2.0))
(min: __C.SCNVector3(x: -0.5, y: -1.0, z: -2.0), max: __C.SCNVector3(x: 0.5, y: 1.0, z: 2.0))
事实证明,即使在应用旋转或缩放之后,边界框也没有更新。这与 SpriteKit 的行为不同。我想知道如何获得更新的边界框?
发生这种情况是因为
boxNode.boundingBox
返回的边界框值代表 SCNNode
的 局部边界框(当您最初创建几何图形时),它不会自动考虑诸如
rotation
、 等变换scaling
或 translation
应用于节点。
要获取世界空间中的实际边界框尺寸,您需要应用转换来获取世界坐标中的边界框,如果我正确理解您的问题,这就是您所期望的:
添加这个新功能:
func getWorldSpaceBoundingBox(of node: SCNNode) -> (min: SCNVector3, max: SCNVector3) {
let (min, max) = node.boundingBox
let corners = [
SCNVector3(min.x, min.y, min.z),
SCNVector3(max.x, min.y, min.z),
SCNVector3(min.x, max.y, min.z),
SCNVector3(max.x, max.y, min.z),
SCNVector3(min.x, min.y, max.z),
SCNVector3(max.x, min.y, max.z),
SCNVector3(min.x, max.y, max.z),
SCNVector3(max.x, max.y, max.z)
]
// Transform each corner to world space
let transformedCorners = corners.map { node.convertPosition($0, to: nil) }
// Initialize min and max points
var worldMin = transformedCorners[0]
var worldMax = transformedCorners[0]
// Find min and max points among transformed corners
for corner in transformedCorners {
worldMin = SCNVector3(
x: Swift.min(worldMin.x, corner.x),
y: Swift.min(worldMin.y, corner.y),
z: Swift.min(worldMin.z, corner.z)
)
worldMax = SCNVector3(
x: Swift.max(worldMax.x, corner.x),
y: Swift.max(worldMax.y, corner.y),
z: Swift.max(worldMax.z, corner.z)
)
}
return (min: worldMin, max: worldMax)
}
然后您可以像这样使用示例框设置:
func testBox() {
let box = SCNBox(width: 1.0, height: 2.0, length: 4.0, chamferRadius: 0.2)
box.firstMaterial?.diffuse.contents = UIColor.yellow
box.firstMaterial?.emission.contents = UIColor.green
let boxNode = SCNNode(geometry: box)
sceneView.scene?.rootNode.addChildNode(boxNode)
print("Original bounding box (local):", boxNode.boundingBox)
// Apply transformations
boxNode.eulerAngles = SCNVector3(0.785, 0.5, 0.5)
boxNode.scale = SCNVector3(1.3, 2.3, 3.3)
// Get transformed bounding box in world space
let worldBoundingBox = getWorldSpaceBoundingBox(of: boxNode)
print("Transformed bounding box (world):", worldBoundingBox)
}
这是调试器的打印输出:
原始边界框(局部):(最小值:__C.SCNVector3(x:-0.5,y:-1.0,z:-2.0),最大值:__C.SCNVector3(x:0.5,y:1.0,z:2.0) )
变换后的边界框(世界):(最小值:__C.SCNVector3(x:-4.7974877,y:-5.0958166,z:-5.835535),最大值:__C.SCNVector3(x:4.7974877,y:5.0958166,z:5.835535) )