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
Realm: Predicate Returning Lazyfiltercollection - How to Convert to Results<T>
Swift Combine How Set<Anycancellable> Works
Destructuring Tuple of Tuple in Closure
How to Put View on Top of All Other Views in Swiftui
Viewwilllayoutsubviews in Swift
Scrolltoitem at Indexpath at .Top Hides Cell Under Header When Sectionheaderspintovisiblebounds
Swift Navigation Bar Item Not Calling Action
Implement Protocol with Different Associated Type
Pfobject Unable to Be Cast to Custom Subclass
"The Requested Snapshot Version Is Too Old." Error in Firestore
Swift Increment Int! Not Working
Difference Between Object(Forkey:) and Value(Forkey:) in Userdefaults
Swiftui CPU High Usage on Real-Time Foreach View Updating (Macos)
Set an Horizontal Scroll to My Barchart in Swift
Pass Type to Generic Function and Compare