gpt4 book ai didi

swift - 如何在使用 ARFaceTrackingConfiguration 时始终将 SceneNode 定位在 SceneView 的中心

转载 作者:行者123 更新时间:2023-12-04 14:20:03 24 4
gpt4 key购买 nike

我已经使用 ARFaceTrackingConfiguration session 设置了 SceneView,并在场景 Assets 中制作了一个虚拟 3D 模型。
该模型是在sceneView中导入的,但它会随着相机的移动而相应地移动,我需要的是将模型位置固定在sceneView的中心。
下图展示了我想要实现的目标。
因此 3D 模型不应根据相机移动而移动。

enter image description here

@IBOutlet var sceneView: ARSCNView!
let scene = SCNScene(named: "art.scnassets/TEST.scn")!
var contentNode: SCNNode?

override func viewDidLoad() {
super.viewDidLoad()

// Set the view's delegate
sceneView.delegate = self

// Show statistics such as fps and timing information
sceneView.showsStatistics = true

sceneView.scene = self.scene
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Create a session configuration
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true

// Run the view's session
sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

// Pause the view's session
sceneView.session.pause()
}
// MARK: - ARSCNViewDelegate
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
guard let faceAnchor = anchor as? ARFaceAnchor else { return nil }

let faceGeometry = ARSCNFaceGeometry(device: sceneView.device!)!

self.contentNode = SCNNode(geometry: faceGeometry)

return self.contentNode
}

最佳答案

所以这是我自己的问题的答案。

首先将一个对象静态放置在sceneView的中间,这意味着您不希望该对象在相机移动时移动,您需要将其位置设置为相机当前面对的位置。
要获取相机的当前位置,我们需要访问 pointOfView值(value)。pointOfView包含 cameraView 的当前位置和方向
一种用例是我们需要在相机前添加节点。
位置和方向在 pointOfView 内编码转换成变换矩阵 SCNMatrix4
.
来自苹果文档:

Image below shows the matrix configurations for some of the more common transformations you can make. Multiplying any coordinate by the identity transform returns the exact same coordinate. For other transformations, how the coordinate is modified depends entirely on which matrix components you change. For example, to translate along the x-axis only, you would supply a nonzero value for the tx component of the translation matrix and leave the ty and tz values to 0. For rotations, you would provide the appropriate sine and cosine values of the target rotation angle. Matrix configurations for



enter image description here

噗……!
现在抢 pointOfView在您的类(class)正文中,不在 ARSCNViewDelegate方法,如果您在 renderer(_nodeFor:) 中执行此操作方法然后你的对象将遵循面几何:
guard let pointOfView = self.sceneView.pointOfView else { return }

然后您可以通过以下方式将对象放置在屏幕中间:
DispatchQueue.main.async {
pointOfView.addChildNode(yourNode)
}

所以现在物体在相机前面居中,它不会随着相机移动而相应地移动。

然后为了通过向上/向下倾斜头部来移动对象,我们需要实现 ARSCNViewDelegate并调用:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode?

此方法要求委托(delegate)提供与新添加的 anchor 相对应的 SceneKit 节点,在我的场景中,我对 FaceAnchor 感兴趣。
我已经为 faceAnchor 分配了一个透明度为 0 的面部几何图形,因为我不需要它可见,它只是为了通过该节点跟踪面部位置,当面部移动时 didUpdate方法将被调用,然后我们可以更新节点或其他内容 didUpdate方法,因为只要移动目标节点,就会调用它。
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let faceAnchor = anchor as? ARFaceAnchor else { return }

let faceTransform = faceAnchor.transform
let positionY = faceLocation.columns.2.y
let positionX = faceLocation.columns.2.x
let horizentalLine = Int(positionY * 100)

self.horizentalNode.eulerAngles = SCNVector3(horizentalLine.degreeToRadians, 0, 0)

因此,正如我之前所说,在每个节点/ anchor 内部都有一个称为变换的属性,它是一个矩阵,用于编码 anchor 相对于放置 anchor 的 AR session 的世界坐标空间的位置、方向和比例。
简而言之:这与 3 维指标有关。
如果发现第 2 列中的 y 和 x 值是头部的水平和垂直移动,则那里的小数学 + degreeToRadians扩展只是转换 eulerAngles 的值旋转矩阵。

关于swift - 如何在使用 ARFaceTrackingConfiguration 时始终将 SceneNode 定位在 SceneView 的中心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55906182/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com