iOS 11中的新SCNCameraController看起来非常有用,但不幸的是,除了头文件和WWDC2017视频中的简短描述之外,似乎没有任何其他文档。 frameNodes 功能看起来特别方便,但它似乎并不实际工作或至少不可靠。具体来说,frameNodes的标题注释说:
“将相机移动到所有节点的边界球体完全可见的位置。同时设置相机目标具有边界球体的中心。”
对于具有多个条目的节点数组,它通常会调整相机以使它们全部可见,但几乎从未将相机控制器目标设置为节点的边界球。至少我无法让它可靠地工作。有没有人想出如何让它工作(我使用的是iOS 11.2.1和Xcode 9.2)?
我附上了一个游乐场来演示这个问题。如果我没有手动设置cameraController.target,则摄像机围绕圆环旋转,即目标似乎设置为SCNVector(0,0,0)。如果我手动设置目标,那么相机似乎围绕正确的目标旋转,大致在圆环和立方体之间。如果这只是我可以解决的错误,那么有人可以建议(简单明了吗?)计算节点数组的边界体积吗?
import UIKit
import SceneKit
import PlaygroundSupport
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
var scene = SCNScene()
sceneView.scene = scene
PlaygroundPage.current.liveView = sceneView
sceneView.autoenablesDefaultLighting = true
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
scene.rootNode.addChildNode(cameraNode)
sceneView.allowsCameraControl = true
sceneView.defaultCameraController.interactionMode = .orbitTurntable
sceneView.defaultCameraController.pointOfView = sceneView.pointOfView
var torus = SCNTorus(ringRadius: 1, pipeRadius: 0.5)
var torusNode = SCNNode(geometry: torus)
torusNode.position = SCNVector3(0, 0, 0)
scene.rootNode.addChildNode(torusNode)
torus.firstMaterial?.diffuse.contents = UIColor.red
torus.firstMaterial?.specular.contents = UIColor.white
var cube = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
var cubeNode = SCNNode(geometry: cube)
cubeNode.position = SCNVector3(4, 0, 0)
scene.rootNode.addChildNode(cubeNode)
cube.firstMaterial?.diffuse.contents = UIColor.blue
cube.firstMaterial?.specular.contents = UIColor.white
SCNTransaction.begin()
SCNTransaction.animationDuration = 1.0
sceneView.defaultCameraController.frameNodes([torusNode, cubeNode])
//sceneView.defaultCameraController.target = SCNVector3(2, 0, 0)
SCNTransaction.commit()
答案 0 :(得分:0)
通过创建半径等于x,y,z数组中最大x,y或z值(float)的球体,可以显示节点数组的边界体积。
下面的伪代码:
maxval = 0
for i in x[] {
if i > maxval {
maxval = i
}
}
for i in y[] {
if i > maxval {
maxval = i
}
}
for i in z[] {
if i > maxval {
maxval = i
}
}
let a = SCNSPhere(radius: maxval)