获取节点的大小

Get size of dae node

假设我有一个 collada 文件,里面有一个盒子,我将 dae 文件导入到场景中。现在在场景中导入后我知道 dae 对象是一个盒子。添加到场景后,如何获取scenekit中盒子的尺寸

如果我将节点作为 SCNBox 导入,我会收到错误消息,指出 SNCBox 不是 SCNNode 的子类型。

    floorNode = scene.rootNode.childNodeWithName("floor", recursively: false) as SCNBox
    floorNode?.physicsBody = SCNPhysicsBody.staticBody()
    floorNode?.physicsBody?.categoryBitMask = 2

    let floorGeo: SCNBox  = floorNode.geometry! as SCNBox

如果 SCNNode 是导入节点的唯一方式,我如何获取维度?

SCNBox 只是 SCNGeometry 的 helper 子类,用于创建方框几何体。当您将 Collada 导入到场景中时,您会得到带有 SCNGeometries 的 SCNNode 的场景图,而不是 SCNBox'es 或 SCNCones 等,无论它们看起来如何。如果你想获得任何节点的尺寸,你应该使用 SCNBoundingVolume 协议,它由 SCNNode 和 SCNGeometry 类:

实现

func getBoundingBoxMin(_ min: UnsafeMutablePointer, 最大值最大值:UnsafeMutablePointer) -> Bool

使用此方法,您将获得边界框角。 对于盒形几何体,尺寸将匹配边界框。

示例:

var v1 = SCNVector3(x:0, y:0, z:0)
var v2 = SCNVector3(x:0, y:0, z:0)
node.getBoundingBoxMin(&v1, max:&v2)

其中 node 是您要获取边界框的节点。 结果将在 v1 和 v2 中。

Swift 3

使用 Swift 3 你可以简单地分别使用 node.boundingBox.minnode.boundingBox.max

关于如何使用 boundingBox 的示例 Swift 代码:

var min = shipNode.boundingBox.min
var max = shipNode.boundingBox.max
let w = CGFloat(max.x - min.x)
let h = CGFloat(max.y - min.y)
let l = CGFloat(max.z - min.z)
let boxShape = SCNBox (width: w , height: h , length: l, chamferRadius: 0.0)
let shape = SCNPhysicsShape(geometry: boxShape, options: nil)

shipNode.physicsBody!.physicsShape = SCNPhysicsShape(geometry: boxShape, options: nil)
shipNode.physicsBody = SCNPhysicsBody.dynamic()

Swift 5.4.

导入 ARKit

extension SCNNode {
    
    var height: CGFloat { CGFloat(self.boundingBox.max.y - self.boundingBox.min.y) }
    var width: CGFloat { CGFloat(self.boundingBox.max.x - self.boundingBox.min.x) }
    var length: CGFloat { CGFloat(self.boundingBox.max.z - self.boundingBox.min.z) }
    
    var halfCGHeight: CGFloat { height / 2.0 }
    var halfHeight: Float { Float(height / 2.0) }
    var halfScaledHeight: Float { halfHeight * self.scale.y  }
}

// Usage:
let node = SCNNode()
node.height
node.width
node.lenght