现在我执行面部地标检测,然后在结果点上使用SCNSceneRenderer.hitTest(cgPt, options: [.rootNode: faceNode])
来查找各种地标的3D位置。我的面部节点是ARFaceAnchor
的孩子,并且ARSCNFaceGeometry
。基本算法似乎工作得很好。但是,出于性能原因,我将特征检测和单个命中测试发送到后台队列,与同步执行所有操作相比,这似乎会导致准确性显着降低。
据推测,这是因为我使用给定的ARFrame
来查找2D地标,但是当我异步执行命中测试时,我无法保证我的面部节点SCNNode
处于相同的位置就像捕获帧时一样,它可能会移动一点点。 (使用ARFaceTrackingConfiguration
跟踪/更新面部锚点。
有没有办法创建我可以传递的面部节点的“冻结”副本,以便异步执行命中测试而不会同时更改节点的位置?
根据我的理解,clone()
和copy()
没有提供我正在寻找的内容。我尝试通过将新的SCNNode设置为原始的几何和位置来编写自己的frozenCopy()
函数。但是,当我在创建时打印此节点的worldPosition
与命中测试的时间时,它似乎已经改变,即使我实际上没有将它添加到场景层次结构......所以我不喜欢我认为它的行为与我的期望相符。我有这个想法吗?
任何想法都将非常感激。非常感谢!
extension SCNNode {
func frozenCopy() -> SCNNode {
// let scnCopy: SCNNode = self.copy() as! SCNNode
// let scnCopy: SCNNode = self.clone()
let scnCopy: SCNNode = SCNNode()
scnCopy.geometry = self.geometry?.copy() as! SCNGeometry?
scnCopy.transform = self.worldTransform
// Setting more properties just in case...
scnCopy.worldOrientation = self.worldOrientation
scnCopy.worldPosition = self.worldPosition
scnCopy.camera = self.camera?.copy() as! SCNCamera?
scnCopy.light = self.light?.copy() as! SCNLight?
scnCopy.pivot = self.pivot
return scnCopy
}
}
我考虑过的一个解决方案是尝试存储面部节点和相机变换以传递给自定义命中测试功能。如果可能的话,我想使用SceneKit API命中测试,因为我认为这比我自己编写的任何函数都要好。