将翻译应用到根节点后第二次无法按预期工作

Posted

技术标签:

【中文标题】将翻译应用到根节点后第二次无法按预期工作【英文标题】:Apply translation to root node does not work as expected for the second time onwards 【发布时间】:2021-06-14 09:47:12 【问题描述】:

这是我上一个问题的延续项目。 How to move multiple nodes in ARSCNView

之前的程序是一个原型。此函数的目的是移动通过 Vision 框架(不是 UI 手势识别器)的手部跟踪通过手部跟踪添加的 AR 对象。该应用程序的很大一部分基于 kkoronuei 创建的 ARPaint。 https://github.com/kkorouei/ARPaint

我发布的代码发生在func session(_ session: ARSession, didUpdate frame: ARFrame) 中。基本上,该应用程序有 2 种模式。 drawMode 是添加锚点的地方,否则就是使用手势移动绘图。两种模式不能同时发生,所以应用程序要么在drawMode 中,要么不在其中。我目前的逻辑是将所有现有节点分组到一个名为motherNode 的新节点,并将转换矩阵应用于它。 indexTip2 指的是视觉框架中食指尖的手指VNImagePointForNormalizedPoint。 “距离”是指激光雷达传感器计算的到相机的距离。这两个变量可以正常工作。从这两个变量中,我可以创建平移矩阵并将整个场景移动到当前手指位置(现在我不用担心移动的是哪个节点,只要一切都朝着正确的方向移动)。

这是第一次。但是,当再次调用它时,这个motherNode 已经存在,所以为了避免一遍又一遍地创建同一个节点,我添加了一个 if 循环来跳过创建方法。当前的问题是当我重用注释掉的行时,对象不再移动到手指位置。它要么很快消失在视线之外,要么根本不动。我可能使用 swift 选项犯了一个错误,但我不确定。当然可以多次应用到根节点的翻译,对吗?任何想法都非常感谢。

            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
            

我添加了一些打印行来看看发生了什么。以下在初始化时打印translationMatrix。然后在 if 循环中打印 touchPositionInFrontOfCamera 和 'translationMatrix'。

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

如您所见,translationMatrix 最终会变得如此之大,以至于无法看到。为什么会这样?

【问题讨论】:

【参考方案1】:

为了回答我自己的问题,worldTransform 将应用于节点的转换记录保持最新。 https://developer.apple.com/documentation/scenekit/scnnode/1407970-worldtransform 因此,它总是会用以前的值更新自己。所以解决方案是不要使用worldTransform,而是使用pivot

【讨论】:

以上是关于将翻译应用到根节点后第二次无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

未显示根线时,TreeView 将 +- 号添加到根节点[重复]

将命名空间前缀添加到根节点

疫情控制(NOIP2012)庆祝2012满贯!?(???-?)????

Babel 模块解析器无法按预期工作(节点 + 打字稿)

不能在“根”类型的节点中构造“属性”类型的项目

从单个ECHO命令输出的连接文本文件在预期输出后第二次将字符插入到字符串中