1

I am trying to rotate SCNNode with UIRotationGestureRecognizer and changing of eulerAngles. I switch between rotation around y and around z axis. When I rotate only one of them everything is fine. But problem appears when I rotate both. It no longer rotate around axis itself but it rotates randomly.

I have read many answers especially from ARGeo like this one: SCNNode Z-rotation axis stays constant, while X and Y axes change when node is rotated , and I understand problem of eulerAngles and gimbal lock.

But I don't understand how to correctly use orientation ant that w component. Is here someone who successfully used UIRotationGestureRecognizer and orientation instead of eulerAngles?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
matuslittva
  • 154
  • 1
  • 9

1 Answers1

1

Here's one of an examples how to implement UIRotationGestureRecognizer.

I copied it from How can I rotate an SCNNode.... SO post.

private var startingOrientation = GLKQuaternion.identity
private var rotationAxis = GLKVector3Make(0, 0, 0)

@objc private func handleRotation(_ rotation: UIRotationGestureRecognizer) {
    guard let node = sceneView.hitTest(rotation.location(in: sceneView), options: nil).first?.node else {
        return
    }
    if rotation.state == .began {
        startingOrientation = GLKQuaternion(boxNode.orientation)
        let cameraLookingDirection = sceneView.pointOfView!.parentFront
        let cameraLookingDirectionInTargetNodesReference = boxNode.convertVector(cameraLookingDirection,                                                                        
                                                                                 from: sceneView.pointOfView!.parent!)
        rotationAxis = GLKVector3(cameraLookingDirectionInTargetNodesReference)
    } else if rotation.state == .ended {
        startingOrientation = GLKQuaternionIdentity
        rotationAxis = GLKVector3Make(0, 0, 0)
    } else if rotation.state == .changed {
        let quaternion = GLKQuaternion(angle: Float(rotation.rotation), axis: rotationAxis)
        node.orientation = SCNQuaternion((startingOrientation * quaternion).normalized())
    }
}

Hope this helps.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 1
    thanks for quick answer, since I switch rotating axis with button crucial for me was question from your link, I never realised from documentation that it could be as easy as SCNQuaternion(0, 0, 1, newRotation) to rotate it in z axis and SCNQuaternion(0, 1, 0, newOrientation) to rotate it on y axis ... Thank you! – matuslittva Apr 23 '19 at 09:33