为什么ARKit搭配SceneKit时设置SCNNode的simdOrientation不生效?
问题根因
你在renderer(_:nodeFor:)方法中对节点simdOrientation的修改会失效,是因为ARKit在拿到该方法返回的节点后,会自动用锚点的世界变换覆盖节点的transform属性,你提前设置的方向参数会被直接冲刷掉。
另外你当前设置的旋转轴也不符合需求:SCNCylinder默认的高度延伸方向为Y轴,要让圆柱体的端面正对墙面,需要绕X轴旋转90度,而非绕Y轴旋转。
解决方案
最稳妥的实现方式是额外增加一层子节点承载圆柱体,父节点交由ARKit自动控制变换,仅修改子节点的方向即可,修改后的renderer方法代码如下:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? { if anchor is ARPlaneAnchor { let anchorNode = SCNNode() return anchorNode } else { // 创建空的父节点,交由ARKit控制位置变换 let parentNode = SCNNode() // 子节点承载圆柱体 let cylinderNode = SCNNode(geometry: SCNCylinder(radius: dotSize, height: 0.05)) cylinderNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green cylinderNode.geometry?.firstMaterial?.isDoubleSided = true // 绕X轴旋转90度,让圆柱体端面朝向外侧 cylinderNode.simdOrientation = simd_quatf(angle: Float.pi/2.0, axis: SIMD3<Float>(1.0, 0.0, 0.0)) // 把圆柱体节点添加到父节点上 parentNode.addChildNode(cylinderNode) return parentNode } }
如果不想新增子节点,也可以实现renderer(_:didAdd:for:)代理方法,在ARKit完成节点初始变换赋值后,再修改节点方向,代码示例:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { guard !(anchor is ARPlaneAnchor) else { return } node.simdOrientation = simd_quatf(angle: Float.pi/2.0, axis: SIMD3<Float>(1.0, 0.0, 0.0)) }
内容的提问来源于stack exchange,提问作者mikeazo
相关产品推荐
相关产品推荐

