在 Scenekit 中移动相机
Move camera in Scenekit
我有一个关于在 SceneKit 中使用平移手势移动相机 up/down 和 left/right 而不旋转的问题。我发现有很多关于旋转相机的讨论,我正在使用它进行旋转。但我无法弄清楚如何在不旋转相机的情况下移动相机。我正在尝试模仿 allowsCameraControl,用户可以在其中用两根手指平移以更改相机的 x 和 y 位置。这是我的平移手势识别器的代码,将不胜感激,谢谢!
func handlePan(gestureRecognize: UIPanGestureRecognizer) {
let numberOfTouches = gestureRecognize.numberOfTouches
var translation = gestureRecognize.translation(in: gestureRecognize.view!)
var widthRatio = Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio
var heightRatio = Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio
if (numberOfTouches==fingersNeededToPan) {
self.cameraOrbit.eulerAngles.y = Float(-2 * M_PI) * widthRatio
self.cameraOrbit.eulerAngles.x = Float(-M_PI) * heightRatio
//for final check on fingers number
lastFingersNumber = fingersNeededToPan
}
if numberOfTouches == 2 {
self.cameraNode.position.x = -(Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio)
self.cameraNode.position.y = -(Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio)
}
lastFingersNumber = (numberOfTouches>0 ? numberOfTouches : lastFingersNumber)
if (gestureRecognize.state == .ended && lastFingersNumber==fingersNeededToPan) {
lastWidthRatio = widthRatio
lastHeightRatio = heightRatio
}
}
如果你想滑动left/right,或者up/down,那么你不需要cameraOrbit
节点(这就是Scenekit camera orbit around object使用的)。
相反,您只想滑动 left/right(X 轴)或 up/down(Y 轴)以响应触摸。看起来你正在这样做。但是,如果 cameraNode
是 cameraOrbit
的子级,您将在 cameraOrbit
的坐标系中移动,该坐标系也由您的手势处理程序旋转!使相机节点成为场景根节点的子节点。
现在,当您的相机未与根坐标系对齐时,就会发生令人困惑的事情。如果相机的X、Y、Z轴与场景的X/Y/Z轴平行,可以调整相机的X/Y位置进行移动。但是如果相机被旋转,或者偏离 Z 轴,你需要调整相机节点的 transform
,在相机平面内移动 left/right 或 up/down。我会尽快尝试扩展这个答案来证明这一点。
现在你可以很简单地做到这一点:
scnView.allowsCameraControl = true
scnView.defaultCameraController.interactionMode = .orbitTurntable
scnView.defaultCameraController.inertiaEnabled = true
scnView.defaultCameraController.maximumVerticalAngle = 89
scnView.defaultCameraController.minimumVerticalAngle = -89
使用保存的方向移动相机
func stepLeft() {
print("stepLeft")
if let pov = view.pointOfView {
pov.localTranslate(by: SCNVector3(-0.5, 0, 0))
}
}
func stepRight() {
print("stepLeft")
if let pov = view.pointOfView {
pov.localTranslate(by: SCNVector3(0.5, 0, 0))
}
}
我有一个关于在 SceneKit 中使用平移手势移动相机 up/down 和 left/right 而不旋转的问题。我发现有很多关于旋转相机的讨论,我正在使用它进行旋转。但我无法弄清楚如何在不旋转相机的情况下移动相机。我正在尝试模仿 allowsCameraControl,用户可以在其中用两根手指平移以更改相机的 x 和 y 位置。这是我的平移手势识别器的代码,将不胜感激,谢谢!
func handlePan(gestureRecognize: UIPanGestureRecognizer) {
let numberOfTouches = gestureRecognize.numberOfTouches
var translation = gestureRecognize.translation(in: gestureRecognize.view!)
var widthRatio = Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio
var heightRatio = Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio
if (numberOfTouches==fingersNeededToPan) {
self.cameraOrbit.eulerAngles.y = Float(-2 * M_PI) * widthRatio
self.cameraOrbit.eulerAngles.x = Float(-M_PI) * heightRatio
//for final check on fingers number
lastFingersNumber = fingersNeededToPan
}
if numberOfTouches == 2 {
self.cameraNode.position.x = -(Float(translation.x) / Float(gestureRecognize.view!.frame.size.width) + lastWidthRatio)
self.cameraNode.position.y = -(Float(translation.y) / Float(gestureRecognize.view!.frame.size.height) + lastHeightRatio)
}
lastFingersNumber = (numberOfTouches>0 ? numberOfTouches : lastFingersNumber)
if (gestureRecognize.state == .ended && lastFingersNumber==fingersNeededToPan) {
lastWidthRatio = widthRatio
lastHeightRatio = heightRatio
}
}
如果你想滑动left/right,或者up/down,那么你不需要cameraOrbit
节点(这就是Scenekit camera orbit around object使用的)。
相反,您只想滑动 left/right(X 轴)或 up/down(Y 轴)以响应触摸。看起来你正在这样做。但是,如果 cameraNode
是 cameraOrbit
的子级,您将在 cameraOrbit
的坐标系中移动,该坐标系也由您的手势处理程序旋转!使相机节点成为场景根节点的子节点。
现在,当您的相机未与根坐标系对齐时,就会发生令人困惑的事情。如果相机的X、Y、Z轴与场景的X/Y/Z轴平行,可以调整相机的X/Y位置进行移动。但是如果相机被旋转,或者偏离 Z 轴,你需要调整相机节点的 transform
,在相机平面内移动 left/right 或 up/down。我会尽快尝试扩展这个答案来证明这一点。
现在你可以很简单地做到这一点:
scnView.allowsCameraControl = true
scnView.defaultCameraController.interactionMode = .orbitTurntable
scnView.defaultCameraController.inertiaEnabled = true
scnView.defaultCameraController.maximumVerticalAngle = 89
scnView.defaultCameraController.minimumVerticalAngle = -89
使用保存的方向移动相机
func stepLeft() {
print("stepLeft")
if let pov = view.pointOfView {
pov.localTranslate(by: SCNVector3(-0.5, 0, 0))
}
}
func stepRight() {
print("stepLeft")
if let pov = view.pointOfView {
pov.localTranslate(by: SCNVector3(0.5, 0, 0))
}
}