如何将相机放置在 SceneKit 中 SK3DNode 内的 3D 模型中心

问题描述 投票:0回答:1

我希望能够将 3D 模型居中放置在 SK3DNode 内。我有以下代码:

public extension SK3DNode {
  static func forModel(_ model: SCNNode, size: CGSize) -> SK3DNode {
    let scene = SCNScene()
    let node3D = SK3DNode()
    node3D.scnScene = scene
    node3D.viewportSize = size
    
    scene.rootNode.addChildNode(model)

    let camera = SCNCamera()
    let cameraNode = SCNNode()
    cameraNode.camera = camera
    node3D.pointOfView = cameraNode
    
    cameraNode.constraints = [SCNLookAtConstraint(target: model)]
    // TODO: adjust position to center fit the model
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 4)
    
    return node3D
  }
}

我已完成以下操作:

    let planeX = model.boundingSize.x
    let planeY = model.boundingSize.y
    let planeLength = max(planeX, planeY)
    let angleInRadian = NumberUtil.degreeToRadian(degree: camera.fieldOfView)
    let distance = planeLength / 2 / tan(angleInRadian/2)

我根据这个答案中的图片得到了上述计算:基于模型尺寸的相机位置?

这似乎很接近我想要的,但它在计算时没有考虑视口的大小和长宽比,所以我认为它不正确。有没有更好的方法来计算这个?

ios swift scenekit
1个回答
0
投票

计算相机到模型的距离时需要考虑 3D 模型的深度,或者从模型中心(或原点)到相机计算距离。 这个调整会解决一切问题

附注您不需要也达到 90% 的大小。您将完美地将模型显示在相机视口中。

    // get the boundingBox aka maximun size of X Y Z of the model (no need for /0.9)
    let planeX = model.boundingBox.max.x
    let planeY = model.boundingBox.max.y
    
    // you need planZ to get the depth of the 3d model for accurate
    // distance calculation
    let planeZ = model.boundingBox.max.z
    
    let planeLength = max(planeX, planeY)
    
    // to convert to radian you can multiply the angle to (.pi/180)
    let angleInRadian = cameraNode.camera!.fieldOfView * (.pi/180)
    
    // this is the distance from the center of the 3d model to the camera
    let distance = planeLength / 2 / tan(angleInRadian/2)
    
    // you have to add half the depth of the 3d model to it
    let actualDistance = distance + (planeZ/2)
    
    cameraNode.position = SCNVector3(x: 0, y: 0, z: actualDistance)
© www.soinside.com 2019 - 2024. All rights reserved.