The same question was also asked here Is it normal for an SCNNode pivot to change the nodes position? ... but after searching online for hours I couldn't find any coded solution to this problem. Which is how does one center the pivot of a node without moving the node.
So in the end I spend most of today working on this coded answer below.
What I found was that the orientation of the local axis determines whether you subtract or do an addition for the correction factor.
Take this bike below. The right-hand pedal crank pivot z-axis (blue) is pointing upwards, whilst in the other photo, left-hand pedal crank pivot z-axis (blue) is pointing downwards. That reason these axis is different is when the person was drawing the bike model in SketchUp, they just copied and flipped the first pedal crank to the opposite side. So unfortunately, its very common to get imported DAE models with ad-hoc pivot orientation and positions!


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've only tested the code above on the two different z-axis orientations shown above, the complete code would also have to deal with 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?