Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change SCNNode position without changing orientation

I am using SceneKit and have an app with multiple SCNNodes and when the user taps one, it will follow their finger (using a UILongPressGestureRecognizer). In the state began and changed, I am using the following line of code to change the node's position:

_currentlyMoving?.position = SCNVector3Make(worldPoint.x, worldPoint.y, worldPoint.z)

In this line, _currentlyMoving is the SCNNode, and worldPoint the position of my finger.

This is moving the node to the correct position; however, it also appears to be changing the rotation of the node to (0,0,0) (The node is always at its starting rotation.)

Is there any way to change the position of an SCNNode without affecting the rotation?

Also, I have tried the following but it did not work either (the same thing happened):

_currentlyMoving?.transform.m41 = worldPoint.x
_currentlyMoving?.transform.m42 = worldPoint.y
_currentlyMoving?.transform.m43 = worldPoint.z

The only other thing that I am doing with the node is the following three lines to stop it from moving while picked up:

_currentlyMoving?.physicsBody?.velocity = SCNVector3Make(0.0, 0.0, 0.0)
_currentlyMoving?.physicsBody?.velocityFactor = SCNVector3Make(0.0, 0.0, 0.0)
_currentlyMoving?.physicsBody?.angularVelocity = SCNVector4Make(0.0, 0.0, 0.0, 1.0)
like image 940
Jsdodgers Avatar asked Oct 02 '14 20:10

Jsdodgers


1 Answers

So after testing many things for a few days, I found out that the rotation is never actually getting set on the node; it is only getting set on the presentation node. Because of this, whenever I was setting the position, the transform of the node was automatically being recalculated based on my new position and the current rotation (which it thought was [0,0,0]), effectively resetting the node's rotation.

So, in order to solve this issue, you have to change the rotation of the node to the presentationNode's rotation.

This is what I am currently doing in my panGestureRecognizer's .Began state (after setting the touched node to currentlyMoving:

if let currentlyMoving = _currentlyMoving {
    if let presentationNode = currentlyMoving.presentationNode() {
        currentlyMoving.rotation = presentationNode.rotation
    }
    currentlyMoving.position = newLocation
}

This just sets the node's rotation to its presentation rotation before moving it so that the transform is set correctly based on what the user can see.

A problem that I was having with this was that some of the models that I downloaded were still being rotated strangely by tiny amounts, although all of the models I created myself were working fine. I had to create my own versions of the other models, after which everything has been working fine. So, I still don't quite know what was wrong with the first models that caused them to shift slightly when I set their rotations to their presentation rotations (I don't have any experienced with 3D modeling).

like image 54
Jsdodgers Avatar answered Sep 19 '22 03:09

Jsdodgers