0
votes

I am using a pan gesture to rotate a node in my SceneKit Scene. The code I currently have rotates the node perfectly. Here is my code I am using to rotate the node:

var previousRotation:Float = 0

@objc func panGestureRecognized(gesture: UIPanGestureRecognizer) {
    if gesture.numberOfTouches == 2 {
        let view = self.view as! SCNView
        let node = view.scene!.rootNode.childNode(withName: "Node", recursively: false)
        let translation = gesture.translation(in: view)

        var newAngle = Float(translation.x) * Float(Double.pi) / 180.0
        newAngle += previousRotation

        switch gesture.state {
        case .began:
            newAngle += previousRotation
            break
        case .changed:
            node!.rotation = SCNVector4(x: 0, y: Float(translation.y), z: 0, w: newAngle)
            break
        case .ended:
            newAngle += previousRotation
            break
        default: break
        }
    }
}

The problem is, the rotation "resets" when you lift your fingers and start the rotation again. I need it to "keep" its rotation so when you start panning again it just continues from where the last rotation stopped at.

1
this code never sets the previousRotation variable. Shouldn't it be previousRotation = newAngle in the .ended case?mnuages
I figured it out, but now it has another issue. When you are rotating, and then you stop and rotate the other direction, when you reach a certain point (rotating that direction) the rotation will stop then reverse and start going the other direction even though you are still rotating the same direction.E. Huckabee

1 Answers

0
votes

Here we go, I figured it out after some major changes, info from other SO questions, and a different approach. Using this code you can perfectly rotate a node on any axis (y, in my case) and then "store" its rotation to continue rotating with another pan afterwards.

var previousRotation = SCNVector4(x: 0, y: 0, z: 0, w: 0)

@objc func pan(gesture: UIPanGestureRecognizer) {
    if gesture.numberOfTouches == 2 {
        let view = self.view as! SCNView
        let node = view.scene!.rootNode.childNode(withName: "Node", recursively: false)
        let translate = gesture.translation(in: view)

        var newAngle = Float(translate.x) * Float(Double.pi) / 180.0

        var rotationVector = SCNVector4()
        rotationVector = SCNVector4(x: 0, y: previousRotation.y + Float(translate.y), z: 0, w: previousRotation.w - newAngle)

        switch gesture.state {
        case .began:
            previousRotation = node!.rotation
            break
        case .changed:
            node!.rotation = rotationVector
            break
        default: break
        }
    }
} 

Hopefully this helps someone else in the future.