Set the SCNNode axis to the bounding volume center without changing the position of the node

I’m looking for a way to set the SCNNodes anchor point (obtained when importing Collada files) at their center of gravity (or at the center of their bounding box. I get the center using

SCNVector3 center; CGFloat radius; [node getBoundingSphereCenter:&center radius:&radius]; 

However, when I try to set the axis of the node (which is a 4D vector as opposed to the 3D center vector) to the center, the position of the node also changes.

 node.pivot = SCNMatrix4MakeTranslation(center.x,center.y,center.z); 

How can I compensate for this movement - accordingly. How can I change only the axis of a node without affecting its position in space? Or is there even a way (without using additional empty nodes) to do this in Interface Builder?

+2
source share
2 answers

A rod is not only the center of rotation, but also the reference point node for the position. When you reset the hinge, the rotation position relative to the parent object remains fixed. In fact, you are moving the geometry relative to the current position of the object.

A simple fix is ​​to move the node using the negative values ​​of those used to reset the rod. If for some reason you need a specific value that does not allow this, put your node in the node container and use the node container for position and your re-pivoted node for rotation.

+3
source

The same question was asked here. Is changing the position of nodes normal for the SCNNode axis? ... but after searching the Internet for several hours, I could not find any encoded solution to this problem. Which means how to center the w630 axis without moving the node .

So in the end, I spend most of today on this encoded answer below. I found that the orientation of the local axis determines whether you subtract or make an addition for the correction factor.

Take this bike below. The right axis of rotation of the pedal grip (blue) is directed upward, and in another photograph the left rotation axis of the rotation axis (blue) is directed downward. For this reason, this axis is different from when a person drew a bike model in SketchUp, they just copied and turned the first pedal handle to the opposite side. Unfortunately, it is very common to import DAE models with special orientations and positions!

enter image description here

enter image description here

  func centerPivotWithOutMoving(for node: SCNNode) -> SCNNode { let initialPos = activeNode.presentation.position var min = SCNVector3Zero var max = SCNVector3Zero node.__getBoundingBoxMin(&min, max: &max) node.pivot = SCNMatrix4MakeTranslation( min.x + (max.x - min.x)/2, min.y + (max.y - min.y)/2, min.z + (max.z - min.z)/2 ) let correctX = Float(min.x + (max.x - min.x)/2) let correctY = Float(min.y + (max.y - min.y)/2) let correctZ = Float(min.z + (max.z - min.z)/2) if node.convertVector(SCNVector3(0,0,1), from: parentNode).z < 0 { // if blue local z-axis is pointing downwards node.position = SCNVector3(initialPos.x - correctX, initialPos.y - correctY, initialPos.z - correctZ) } else { // if blue local z-axis is pointing upwards node.position = SCNVector3(initialPos.x + correctX, initialPos.y + correctY, initialPos.z + correctZ) } return node } 

I just checked the code above on the two different z-axis orientations shown above, the full code would also have to deal with the x, y axis using these two conditions.

  node.convertVector(SCNVector3(0,1,0), from: parentNode).z < 0 node.convertVector(SCNVector3(1,0,0), from: parentNode).z < 0 

If there is a better way to do this ... please share?

+1
source

Source: https://habr.com/ru/post/1275734/


All Articles