1

I have a simple scene with a centered object and the camera positioned on a virtual sphere around the center (inspired from Rotate SCNCamera node looking at an object around an imaginary sphere).

Now I want to be able to move the object with a two finger pan gesture. My code works well as long as I don't rotate the camera first. If I first rotate the camera by 180° (so that the camera looks at the object from behind), then the movement is in the wrong direction (which makes sense to me). It gets worse with other camera positions. However, I cannot find how I must convert or project the x/y translations from the recognizer to the plane parallel to the camera. The object should move under the fingers..

This is the setup of my scene:

    let scene = SCNScene()

    //add camera
    let camera = SCNCamera()
    camera.usesOrthographicProjection = true
    camera.orthographicScale = 30
    camera.zNear = 1.0
    camera.zFar = 1000

    cameraNode = SCNNode()
    cameraNode.camera = camera
    cameraNode.position = SCNVector3(x: 0.0, y: 0.0, z: 50.0)

    cameraOrbit = SCNNode()
    cameraOrbit.addChildNode(cameraNode)

    scene.rootNode.addChildNode(cameraOrbit)

    boxNode.geometry = SCNBox(width: 10, height: 40, length: 10, chamferRadius: 0.2) 
    scene.rootNode.addChildNode(boxNode)

    let panMoveGestureRecognizer = UIPanGestureRecognizer(target: self, action:#selector(panMoveGesture))
    panMoveGestureRecognizer.minimumNumberOfTouches = 2
    sceneView.addGestureRecognizer(panMoveGestureRecognizer)

And the gesture recognizers code:

func panMoveGesture(recognizer: UIPanGestureRecognizer) {

    //move
    let translation = recognizer.translation(in: self.view.superview)
    var newXMovement = -Float(translation.x) * 0.1
    var newYMovement = Float(translation.y) * 0.1

    switch recognizer.state {
        case .began:
            currentXMovement = cameraOrbit.position.x
            currentYMovement = cameraOrbit.position.y
        case .changed:
            newXMovement += currentXMovement
            newYMovement += currentYMovement

            cameraOrbit.position.x = newXMovement
            cameraOrbit.position.y = newYMovement
        case .ended:
            currentXMovement = newXMovement
            currentYMovement = newYMovement
        default: break
    }

}

Please help ;-)

Community
  • 1
  • 1
pawi
  • 183
  • 1
  • 12
  • So, you would like your object to respond to gestures as if its axes maintained the same orientation with respect to the camera as the camera moves. E.g., say the object's x-axis points right. Rotate the camera 180° and the x-axis still points right although you are now looking at the object from behind. Is this correct? – bpedit Sep 27 '16 at 16:54
  • That's what I understood him to be asking. I can't think of a way to do it without attaching the object to the camera and constraining it during camera movements. – Confused Sep 28 '16 at 00:23
  • Yes, that's what I want to achieve.. – pawi Sep 28 '16 at 06:38
  • Did you think of a way to compare the camera's current position with the orientation of the object to rotate, so you can convert the transform to that relationship? I think this is another way to do it, but don't know how. – Confused Oct 02 '16 at 10:06

0 Answers0