我正在尝试模拟 ARKit,但使用设备的前置摄像头而不是后置摄像头(并且不限于 iPhone X)。到目前为止,我已经设法设置了一个简单的场景,其中仅在 SCNCamera 前面加载了一个 3D 模型,并且感谢 Travis 在此答案中提供的片段,设法根据设备的姿态定位 SCNCamera。
但是,我仍然需要根据设备的运动来平移相机,以便我可以从不同的角度可视化对象并“缩放”到它;而且我不知道应该使用哪些数据。是userAcceleration
从CMDeviceMotion
对象吗?我通过记录注意到,即使我让设备保持相对安静,我也会得到一些加速度分量的非零值。任何关于如何解决这个问题的提示或线索都非常感谢。
这是我到目前为止的基本代码:
class ViewController: UIViewController {
@IBOutlet weak var sceneView: SCNView!
private let cameraNode = SCNNode()
private var ringNode: SCNNode!
private let motionManager = CMMotionManager()
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
setupMotionManager()
}
private func setupScene() {
let objScene = SCNScene(named: "art.scnassets/ring.obj")!
ringNode = objScene.rootNode.childNode(withName: "ring", recursively: true)
ringNode.applyUniformScale(0.003)
ringNode.position = SCNVector3(x: 0, y: 0, z: -5)
let scene = SCNScene()
scene.rootNode.addChildNode(ringNode)
// create and add a camera to the scene
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 0)
// create and add a light to the scene
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = .omni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)
// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.color = UIColor.darkGray
scene.rootNode.addChildNode(ambientLightNode)
sceneView.scene = scene
}
private func setupMotionManager() {
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
motionManager.startDeviceMotionUpdates(to: OperationQueue(), withHandler: { (motion, error) in
if let motion = motion {
self.cameraNode.orientation = motion.gaze(atOrientation: .portrait)
let acc = motion.userAcceleration
print("Acc: \(accDescription(acc))")
}
})
}
}