6

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)
Jsdodgers
  • 5,253
  • 2
  • 20
  • 36
  • Does your node have a physicBody set? If you are moving it programmatically, did you use a "kinematic" body? – Toyos Oct 03 '14 at 20:44
  • @Toyos It does have a physicsBody, but it is dynamic, not kinematic. – Jsdodgers Oct 05 '14 at 18:10
  • The transform of the node should not be affected by its position, unless you have some constraints in place. Can you share the minimal code to reproduce this problem? – Gusutafu Oct 06 '14 at 02:11

1 Answers1

5

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).

Jsdodgers
  • 5,253
  • 2
  • 20
  • 36