ARKit将SCNNode放置在面向相机的位置

Mar*_* Dm 11 ios swift scnnode arkit arscnview

我正在使用ARKit显示3D对象.我设法将节点放在用户面前的真实世界(也就是相机).但是当我放下相机时,我无法让它们面对镜头.

let tap_point=CGPoint(x: x, y: y)
let results=arscn_view.hitTest(tap_point, types: .estimatedHorizontalPlane)
guard results.count>0 else{
    return
}
guard let r=results.first else{
    return
}

let hit_tf=SCNMatrix4(r.worldTransform)
let new_pos=SCNVector3Make(hit_tf.m41, hit_tf.m42+Float(0.2), hit_tf.m43)

guard let scene=SCNScene(named: file_name) else{
    return
}
guard let node=scene.rootNode.childNode(withName: "Mesh", recursively: true) else{
    return
}
node.position=new_pos
arscn_view.scene.rootNode.addChildNode(node)
Run Code Online (Sandbox Code Playgroud)

节点位于相机前面的平面上.但他们都朝着同一个方向前进.我想我应该轮换,SCNNode但我没有设法做到这一点.

小智 7

首先,获取相机的旋转矩阵:

let rotate = simd_float4x4(SCNMatrix4MakeRotation(sceneView.session.currentFrame!.camera.eulerAngles.y, 0, 1, 0))
Run Code Online (Sandbox Code Playgroud)

然后,组合矩阵:

let rotateTransform = simd_mul(r.worldTransform, rotate)
Run Code Online (Sandbox Code Playgroud)

最后,将转换应用于您的节点,转换为SCNMatrix4:

node.transform = SCNMatrix4(rotateTransform)
Run Code Online (Sandbox Code Playgroud)

希望有所帮助

编辑

在这里你如何从simd_float4x4创建SCNMatrix4

   let rotateTransform = simd_mul(r.worldTransform, rotate)

  node.transform =  SCNMatrix4(m11: rotateTransform.columns.0.x, m12: rotateTransform.columns.0.y, m13: rotateTransform.columns.0.z, m14: rotateTransform.columns.0.w, m21: rotateTransform.columns.1.x, m22: rotateTransform.columns.1.y, m23: rotateTransform.columns.1.z, m24: rotateTransform.columns.1.w, m31: rotateTransform.columns.2.x, m32: rotateTransform.columns.2.y, m33: rotateTransform.columns.2.z, m34: rotateTransform.columns.2.w, m41: rotateTransform.columns.3.x, m42: rotateTransform.columns.3.y, m43: rotateTransform.columns.3.z, m44: rotateTransform.columns.3.w)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!!!我发誓你是堆栈溢出的唯一答案,对我有用!添加一个节点作为摄像机的子节点会使节点跟随它,而你的方式只是最初朝向摄像机,但保持原位.在我的例子中,我将在`touchesBegan`中提取一个`SCNVector3`以用作我的`textNode`的位置,然后应用你所显示的`rotateTransform`.再次感谢,这应该标记为答案@op (2认同)

小智 5

guard let frame = self.sceneView.session.currentFrame else {
    return
}
node.eulerAngles.y = frame.camera.eulerAngles.y
Run Code Online (Sandbox Code Playgroud)


ric*_*ter 2

您是否希望节点始终面向相机,即使相机移动?这就是 SceneKit约束的用途。或SCNLookAtConstraint可以SCNBillboardConstraint使节点始终指向相机。

您是否希望节点在放置时面向相机,但然后保持静止(以便您可以移动相机并看到它的背面)?有几种方法可以做到这一点。有些涉及有趣的数学,但更简单的处理方法可能只是设计 3D 资源,使“前”始终位于 Z 轴正方向。根据相机变换设置放置对象的变换,其初始方向将与相机的方向相匹配。