Ios 是否匹配用于自定义Scenekit渲染的ARSCNView变换? TL:DR
我试图在Ios 是否匹配用于自定义Scenekit渲染的ARSCNView变换? TL:DR,ios,swift,scenekit,augmented-reality,arkit,Ios,Swift,Scenekit,Augmented Reality,Arkit,我试图在MTKView中渲染SCNRenderer,因此我在颜色/深度缓冲区上有句柄-我试图匹配ARSCNView通过ARKit进行的变换,因此我的SCNRenderer的行为类似于ARSCNView 是否有人通过ARFrame/ARCamera和ARKit提供的信息匹配ARSCNViews world和face tracking配置的示例,并适当修改SCNSCamera 比较长的 出于各种原因(无法访问ARSCNView/SCNView的MTLPassDescriptor和SCNTechniq
MTKView
中渲染SCNRenderer
,因此我在颜色/深度缓冲区上有句柄-我试图匹配ARSCNView
通过ARKit
进行的变换,因此我的SCNRenderer
的行为类似于ARSCNView
是否有人通过ARFrame
/ARCamera
和ARKit
提供的信息匹配ARSCNViews world和face tracking配置的示例,并适当修改SCNSCamera
比较长的
出于各种原因(无法访问ARSCNView
/SCNView
的MTLPassDescriptor
和SCNTechnique
有其自身奇怪的限制),我试图通过MTKView
+ARKit
++SCNRenderer
自己重新实现一些ARSCNView
,这使我能够更好地控制渲染管道。我的代码基于苹果ARKit+金属示例
我想匹配ARKit
正在做的事情-但当我尝试使用ARFrame
/ARCamera
信息修改我的SCNScene
和SCNCamera
时,我的场景会移动,但使用相机的方式与使用ARSCNView或ARKit with Metal演示的方式不同
我不知道什么东西被错误地从ARKit传递到了我的场景中
我的场景:
self.sceneKitRenderer = SCNRenderer(device: self.device, options: nil)
self.sceneKitRenderer?.delegate = self as SCNSceneRendererDelegate
let scene = SCNScene()
scene.background.contents = nil
let sphere = SCNSphere(radius: 1.0)
sphere.firstMaterial?.diffuse.contents = UIColor.red
sphere.firstMaterial?.isDoubleSided = true
let sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3(0, 0.0, -5)
scene.rootNode.addChildNode(sphereNode)
let camera = SCNCamera()
let cameraNode = SCNNode()
cameraNode.camera = camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
cameraNode.look(at: scene.rootNode.worldPosition)
scene.rootNode.addChildNode(cameraNode)
self.sceneKitRenderer?.scene = scene
self.sceneKitRenderer?.pointOfView = cameraNode
当我收到更新的ARFrame时,我正在更新场景的视点及其投影矩阵,如下所示:
// Match clipping
self.sceneKitRenderer?.pointOfView?.camera?.zNear = 0.001
self.sceneKitRenderer?.pointOfView?.camera?.zFar = 1000
// Match projection
let projection = SCNMatrix4( frame.camera.projectionMatrix(for: .landscapeRight, viewportSize: viewportSize, zNear: 0.001, zFar: 1000))
self.sceneKitRenderer?.pointOfView?.camera?.projectionTransform = projection
// Match transform
self.sceneKitRenderer?.pointOfView?.simdTransform = frame.camera.transform
虽然这看起来有些作用,但它与输出不匹配
问题:
从摄像机的翻译中指定simdTransform
或SCNRenderer
的视角是否正确
我是否需要对场景做些什么来设置适当的坐标系(即根节点比例?)
感谢您的指导 我做了两件事让它工作起来。
首先,您需要从ARKit的场景中获取摄影机节点,并使用它在其他场景中设置摄影机节点的变换
和摄影机的投影变换
:
// get the first node that has a camera attached
if let arkitCameraNode = arkitScene.rootNode.childNodes(passingTest: { (node, stop) -> Bool in
return node.camera != nil
}).first {
// SCNNode
otherSceneCameraNode.transform = arkitCameraNode.transform
// SCNCamera
otherSceneCamera.projectionTransform = arkitCameraNode.camera!.projectionTransform
}
在此之后,您需要通过获取相应的ARAnchor
transform来同步其他场景中的克隆节点:
if let anchor = arkitSceneView.anchor(for: nodeFromARKitScene) {
clonedNodeInOtherScene.simdTransform = anchor.transform
}
希望这有帮助 问题中引用的用于将ARCamera
与SCNScene相机匹配的代码在不同方向上不起作用,因为变换会因方向不同而不同。ARCamera
上有一个函数,用于获取特定方向的视图矩阵(视图矩阵是摄影机变换的逆矩阵)。因此,可以使用以下内容来正确考虑方向:
// Match clipping
self.sceneKitRenderer?.pointOfView?.camera?.zNear = 0.001
self.sceneKitRenderer?.pointOfView?.camera?.zFar = 1000
// Match projection
let projection = SCNMatrix4( frame.camera.projectionMatrix(for: .portrait, viewportSize: viewportSize, zNear: 0.001, zFar: 1000))
self.sceneKitRenderer?.pointOfView?.camera?.projectionTransform = projection
// Match transform
self.sceneKitRenderer?.pointOfView?.simdTransform = currentFrame.camera.viewMatrix(for: .portrait).inverse
谢谢你。我实际上根本没有使用ARSCNView,所以我没有一个要复制的带有变换的参考场景。然而,我上面的代码确实有效,只是坐标系不是我所期望的——一旦我开始在场景中使用米,它就自行解决了:)