在我的新 ARKit 应用程序中,用户可以在检测到的平面上放置对象。检测到飞机很好,当用户触摸飞机时,会创建一个新节点(SCNBox)并将其丢弃在飞机上。这一步很好用。

但是,我希望新生成的框(稍后更复杂的模型)被丢弃在模型的确切中心。

这是我的代码:

fileprivate func pasteModel(hitResult: ARHitTestResult)
{
    guard let model = self.model else { return }

    // Get the tapped plane.
    if let anchor = hitResult.anchor
    {
        if let plane = self.planes[anchor.identifier]
        {
            // Get the dimensions of the model.
            let widthModel = CGFloat(0.20)
            let lengthModel = CGFloat(0.20)

            let box = SCNBox(width: widthModel, height: widthModel, length: widthModel, chamferRadius: 0.0)
            box.firstMaterial = SCNMaterial()
            box.firstMaterial?.diffuse.contents = UIColor.cyan

            let node = SCNNode(geometry: box)
            plane.addChildNode(node)

            // Get the dimensions of the tapped plane.
            let width = plane.width
            let length = plane.length

            // Calculate the scale (i.e. how much bigger the model is). Keep the ratio, so use the bigger side.
            let scaleWidth = widthModel / width
            let scaleHeight = lengthModel / length

            let scale: Float = Float(1.0 / max(scaleWidth, scaleHeight))

            node.scale = SCNVector3Make(scale, scale, scale)
            node.position = plane.position

            // Check how much the model is away from the center point.
            let centerPlane = self.getCenter(ofNode: plane)
            let centerNode = self.getCenter(ofNode: node)

            let distanceX = centerPlane.x - centerPlane.z
            let distanceZ = centerNode.x - centerNode.z

            let translation = SCNVector3Make(distanceX, self.MODEL_OFFSET, distanceZ)
            node.localTranslate(by: translation)

            // After the model has been scaled and positoned properly, the physics body is added.
            node.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.dynamic, shape: nil)
            node.physicsBody?.mass = self.MODEL_MASS
            node.physicsBody?.angularVelocityFactor = SCNVector3Zero // Prevent model rotation.
        }
    }
}

fileprivate func getCenter(ofNode node: SCNNode) -> SCNVector3
{
    let widthNode = node.boundingBox.max.x - node.boundingBox.min.x
    let lengthNode = node.boundingBox.max.z - node.boundingBox.min.z
    let centerNode = SCNVector3Make(node.position.x + Float(widthNode / 2), node.position.y, node.position.z + Float(lengthNode / 2))

    return centerNode
}

以下是我的方法的简短概述:

  • 获取 ARKit 检测到的飞机。

  • 创建一个立方体并将其缩放到平面的尺寸 - 较大的一侧用于缩放。

  • 获得飞机和立方体的中心点。

  • 平移立方体,使中心点对齐。

不幸的是,模型没有居中。我的错误在哪里?