'Apply translation to root node does not work as expected for the second time onwards
This is a continuation project from my previous question. How to move multiple nodes in ARSCNView
The previous program was a prototype. The purpose of this function is to move the AR object which is added by hand tracking using hand tracking by the Vision framework (not UI hand gesture recognizer). A large part of the app is based on ARPaint created by kkoronuei. https://github.com/kkorouei/ARPaint
The code I have posted happens inside func session(_ session: ARSession, didUpdate frame: ARFrame) {. Basically the app has 2 modes. drawMode is where the anchors are added, otherwise it is to move the drawing using hand gesture. Two modes cannot happen at the same time, so the app is either in drawMode or not in it. My current logic is to group all the existing node to a new node called motherNode and apply the translation matrix to it. indexTip2 refers to the finger VNImagePointForNormalizedPoint of the index finger tip from the vision framework. 'distance' refers the distance to the camera calculated by the Lidar sensor. These 2 variables work without issues. From these 2 variables I can create the translation Matrix and move the entire scene to the current finger position (for now I will not worry which node is being moved, as long everything is shifted in the right direction).
This works for the first time. However, when it is called again, this motherNode already exists so to avoid creating the same node over and over again, I have added an if loop to skip the creation method. The current problem is when I reuse the commented out lines, the object does not move to the finger position anymore. It either fades out of sight very quickly or it does not move at all. I might have made a mistake using swift options but I am not sure. Surely the translation to the root node can be applied multiple times right? Any thought is much appreciated.
if (!drawMode.isOn){
var parentNode: SCNNode?
var nodes: [SCNNode] = getMyNodes()
parentNode = sceneView.scene.rootNode.childNode(withName: "motherNode", recursively: true)
if parentNode != nil {
// guard let touchPositionInFrontOfCamera = getPosition(ofPoint: indexTip2, atDistanceFromCamera: self.distance, inView: self.sceneView) else { return }
// print(touchPositionInFrontOfCamera)
// let translationMatrix = SCNMatrix4Translate(parentNode!.worldTransform,
// touchPositionInFrontOfCamera.x,
// touchPositionInFrontOfCamera.y,
// touchPositionInFrontOfCamera.z)
// parentNode!.transform = translationMatrix
return
}
parentNode = SCNNode()
parentNode!.name = "motherNode"
for node in nodes {
parentNode!.addChildNode(node)
}
sceneView.scene.rootNode.addChildNode(parentNode!)
guard let touchPositionInFrontOfCamera = getPosition(ofPoint: indexTip2, atDistanceFromCamera: self.distance, inView: self.sceneView) else { return }
let translationMatrix = SCNMatrix4Translate(parentNode!.worldTransform,
touchPositionInFrontOfCamera.x,
touchPositionInFrontOfCamera.y,
touchPositionInFrontOfCamera.z)
parentNode!.transform = translationMatrix
return
}
I have added a few print lines to see what is going on. The following prints the translationMatrix when it is initialized. Then prints touchPositionInFrontOfCamera and 'translationMatrix' inside the if loop.
______
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 0.5359205, m42: 0.18874621, m43: -1.810905, m44: 1.0)
SCNVector3(x: 0.58134866, y: -0.099451624, z: -1.8089545)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 1.1172692, m42: 0.08929459, m43: -3.6198595, m44: 1.0)
SCNVector3(x: 0.5735985, y: 0.01310969, z: -1.8194867)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 1.6908677, m42: 0.10240428, m43: -5.4393463, m44: 1.0)
SCNVector3(x: 0.5767575, y: -0.01947598, z: -1.8248432)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 2.267625, m42: 0.0829283, m43: -7.2641897, m44: 1.0)
SCNVector3(x: 0.53923947, y: 0.012032239, z: -1.8421669)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 2.8068645, m42: 0.09496054, m43: -9.106357, m44: 1.0)
SCNVector3(x: 0.5817139, y: -0.086378224, z: -1.8321315)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 3.3885784, m42: 0.008582316, m43: -10.938488, m44: 1.0)
SCNVector3(x: 0.5687888, y: -0.064390875, z: -1.8420491)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 3.9573672, m42: -0.05580856, m43: -12.780537, m44: 1.0)
SCNVector3(x: 0.5444935, y: -0.063903295, z: -1.855654)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 4.5018606, m42: -0.11971185, m43: -14.63619, m44: 1.0)
SCNVector3(x: 0.5435701, y: -0.06915884, z: -1.8613077)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 5.0454307, m42: -0.1888707, m43: -16.497498, m44: 1.0)
SCNVector3(x: 0.3528172, y: -0.0486469, z: -1.9168768)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 5.3982477, m42: -0.2375176, m43: -18.414375, m44: 1.0)
SCNVector3(x: 0.34087926, y: -0.053323507, z: -1.9242713)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 5.739127, m42: -0.2908411, m43: -20.338646, m44: 1.0)
SCNVector3(x: 0.58009064, y: -0.22830658, z: -1.8522431)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 6.3192177, m42: -0.5191477, m43: -22.19089, m44: 1.0)
SCNVector3(x: 0.42730594, y: -0.17960595, z: -1.9075701)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 6.746524, m42: -0.69875365, m43: -24.09846, m44: 1.0)
SCNVector3(x: 0.47545266, y: -0.20432584, z: -1.8975433)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 7.2219763, m42: -0.9030795, m43: -25.996002, m44: 1.0)
SCNVector3(x: 0.4368087, y: -0.15196265, z: -1.9180105)
SCNMatrix4(m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0, m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0, m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, m41: 7.658785, m42: -1.0550421, m43: -27.914013, m44: 1.0)
As you can see the translationMatrix will eventually grow so huge it becomes impossible to see. Why is this happening?
Solution 1:[1]
To answer my own question, worldTransform keeps the record of transformation applied to the node up to date.
https://developer.apple.com/documentation/scenekit/scnnode/1407970-worldtransform
Therefore it will always update itself with previous values. So the solution is do not use worldTransform and use pivot instead.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | tonywang |
