Scenkit Eulerangles Strange Values During Rotation

ARKit cannot rotate a SCNNode correctly on a vertical plane

I tried SCNNode eulerAngles and SCNNode rotation and I have no luck...

I guess that is because I invoked SCNNode.transform() when I add the painting. When later I modify SCNNode.eulerAngles and invoke SCNNode.rotation(), they may have influence on the first transform.

I finally get it working using SCNMatrix4Rotate, not using eulerAngles and rotation.

  func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
...
let newPaintingNode = SCNNode(geometry: planeGeometry)
newPaintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
newPaintingNode.transform = SCNMatrix4Rotate(newPaintingNode.transform, -Float.pi / 2.0, 1.0, 0.0, 0.0)
newPaintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
self.paintingNode = newPaintingNode
...
}
...
@objc func rotateNode(_ gesture: UIRotationGestureRecognizer){

if let _ = self.paintingNode {

// Get The Current Rotation From The Gesture
let rotation = Float(gesture.rotation)

if gesture.state == .began {
self.rotationZ = rotation
}

if gesture.state == .changed {
let diff = rotation - self.rotationZ
self.paintingNode?.transform = SCNMatrix4Rotate(self.paintingNode!.transform, diff, 0.0, 0.0, 1.0)
self.rotationZ = rotation
}

}

}

And the above code works on both vertical and horizontal plane.

Rotate a node using pan gesture in SceneKit iOS

I think you might be overcomplicating what you need to do here.

In my example, I have created an SCNNode with an SCNBox Geometry and set it's Euler Angles as per your example: (x: -90, y: 0, z: 0).

The 1st thing you need to do, is create a variable to store the rotationAngle around the YAxis:

var currentAngleY: Float = 0.0

Then try this function in order to rotate your node around the YAxis (which works fine by the way):

 /// Rotates An Object On It's YAxis
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func rotateObject(_ gesture: UIPanGestureRecognizer) {

guard let nodeToRotate = currentNode else { return }

let translation = gesture.translation(in: gesture.view!)
var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
newAngleY += currentAngleY

nodeToRotate.eulerAngles.y = newAngleY

if(gesture.state == .ended) { currentAngleY = newAngleY }

print(nodeToRotate.eulerAngles)
}

Hope it helps...

SceneKit. How to rotate SCNNode around its axis

Seems you was really close, you had to swap parameters in GLKQuaternionMultiply call. I used solution in https://stackoverflow.com/a/39813058/4124265 to achieve rotation only by Z axis:

    let orientation = modelNode.orientation
var glQuaternion = GLKQuaternionMake(orientation.x, orientation.y, orientation.z, orientation.w)

// Rotate around Z axis
let multiplier = GLKQuaternionMakeWithAngleAndAxis(0.5, 0, 0, 1)
glQuaternion = GLKQuaternionMultiply(glQuaternion, multiplier)

modelNode.orientation = SCNQuaternion(x: glQuaternion.x, y: glQuaternion.y, z: glQuaternion.z, w: glQuaternion.w)

To rotate arround Y:

    // Rotate around Y axis
let multiplier = GLKQuaternionMakeWithAngleAndAxis(0.5, 0, 1, 0)
glQuaternion = GLKQuaternionMultiply(glQuaternion, multiplier)


Related Topics



Leave a reply



Submit