5

I have a question about moving the camera up/down and left/right without rotating in SceneKit with a pan gesture. I have found plenty of discussions about rotating the camera, which I am using for my rotation. But I can't figure out how to move the camera without rotating it. I am trying to mimic, allowsCameraControl where the user can pan with two fingers to change the cameras x and y position. Here is the code for my pan gesture recognizer, any help would be greatly appreciated, thanks!

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
    }
}
Zach Fuller
  • 1,219
  • 2
  • 14
  • 18
  • To clarify: do you want to move sideways, without changing camera angle? E.g. I'm facing northeast, and I step sideways (northwest to the left, southeast to the right) while continuing to face northeast? – Hal Mueller Nov 15 '16 at 09:12
  • Yes I am just trying to move the camera left / right or up / down without rotating, like is possible with allowsCameraControl, sorry for the confusion @HalMueller – Zach Fuller Nov 15 '16 at 16:24

3 Answers3

5

If you want to slide left/right, or up/down, then you don't need the cameraOrbit node (that's what Scenekit camera orbit around object uses).

Instead, you just want to slide left/right (X axis) or up/down (Y axis) in response to touch. It looks like you're doing that. But if cameraNode is a child of cameraOrbit, you'll be moving in the coordinate system of cameraOrbit, which is also being rotated by your gesture handler! Make the camera node a child of your scene's root node.

Now the confounding thing happens when your camera isn't lined up with the root coordinate system. If the camera's X, Y, and Z axes are parallel to the scene's X/Y/Z axes, you can adjust the camera's X/Y positions to move. But if the camera's been rotated, or pointed off Z axis, you need to adjust the camera node's transform, to move left/right or up/down in the plane of the camera. I'll try to expand this answer sometime soon to demonstrate that.

Community
  • 1
  • 1
Hal Mueller
  • 7,019
  • 2
  • 24
  • 42
5

Now you can do it quite simple:

scnView.allowsCameraControl = true
scnView.defaultCameraController.interactionMode = .orbitTurntable
scnView.defaultCameraController.inertiaEnabled = true
scnView.defaultCameraController.maximumVerticalAngle = 89
scnView.defaultCameraController.minimumVerticalAngle = -89
RS2307
  • 96
  • 1
  • 6
2

to move camera with saved orientation use

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))
        }
    }
g01dt00th
  • 71
  • 2
  • 2