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,所以我没有一个要复制的带有变换的参考场景。然而,我上面的代码确实有效,只是坐标系不是我所期望的——一旦我开始在场景中使用米,它就自行解决了:)