gpt4 book ai didi

ios - 场景中的 ARKit 3D 头部跟踪

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:30:30 25 4
gpt4 key购买 nike

我正在使用 ARKit 创建增强相机应用。当 ARSession 初始化时,一个 3d 字符显示在 ARSCNView 中。我正在尝试获取角色的跟踪 ARCamera 的视角,以便在用户移动拍照时它们始终注视着相机。

我使用了 Apple 的变色龙演示,它添加了一个使用 SCNLookAtConstraint 跟踪相机视角的焦点节点,但我越来越奇怪的行为。当 ARCamera 平移时,头部会掉到一边并旋转。如果我添加一个 SCNTransformConstraint 来限制头部向上/向下/左右移动,它保持垂直但随后看向别处并且不跟踪。

我尝试将变色龙演示拆开,看看为什么我的演示不起作用,但几天后我就卡住了。

我使用的代码是:

class Daisy: SCNScene, ARCharacter, CAAnimationDelegate {

// Rig for animation
private var contentRootNode: SCNNode! = SCNNode()
private var geometryRoot: SCNNode!
private var head: SCNNode!
private var leftEye: SCNNode!
private var rightEye: SCNNode!

// Head tracking properties
private var focusOfTheHead = SCNNode()
private let focusNodeBasePosition = simd_float3(0, 0.1, 0.25)

// State properties
private var modelLoaded: Bool = false
private var headIsMoving: Bool = false
private var shouldTrackCamera: Bool = false



/*
* MARK: - Init methods
*/

override init() {

super.init()

loadModel()
setupSpecialNodes()
setupConstraints()

}


/*
* MARK: - Setup methods
*/

func loadModel() {

guard let virtualObjectScene = SCNScene(named: "daisy_3.dae", inDirectory: "art.scnassets") else {
print("virtualObjectScene not intialised")
return
}

let wrapper = SCNNode()

for child in virtualObjectScene.rootNode.childNodes {
wrapper.addChildNode(child)
}

self.rootNode.addChildNode(contentRootNode)

contentRootNode.addChildNode(wrapper)

hide()

modelLoaded = true

}


private func setupSpecialNodes() {

// Assign characters rig elements to nodes
geometryRoot = self.rootNode.childNode(withName: "D_Rig", recursively: true)
head = self.rootNode.childNode(withName: "D_RigFBXASC032Head", recursively: true)
leftEye = self.rootNode.childNode(withName: "D_Eye_L", recursively: true)
rightEye = self.rootNode.childNode(withName: "D_Eye_R", recursively: true)

// Set up looking position nodes
focusOfTheHead.simdPosition = focusNodeBasePosition

geometryRoot.addChildNode(focusOfTheHead)

}


/*
* MARK: - Head animations
*/

func updateForScene(_ scene: ARSCNView) {

guard shouldTrackCamera, let pointOfView = scene.pointOfView else {
print("Not going to updateForScene")
return
}

followUserWithHead(to: pointOfView)

}

private func followUserWithHead(to pov: SCNNode) {

guard !headIsMoving else { return }

// Update the focus node to the point of views position
let target = focusOfTheHead.simdConvertPosition(pov.simdWorldPosition, to: nil)

// Slightly delay the head movement and the animate it to the new focus position
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
let moveToTarget = SCNAction.move(to: SCNVector3(target.x, target.y, target.z), duration: 1.5)
self.headIsMoving = true
self.focusOfTheHead.runAction(moveToTarget, completionHandler: {
self.headIsMoving = false
})
})

}



private func setupConstraints() {

let headConstraint = SCNLookAtConstraint(target: focusOfTheHead)
headConstraint.isGimbalLockEnabled = true

let headRotationConstraint = SCNTransformConstraint(inWorldSpace: false) { (node, transform) -> SCNMatrix4 in

// Only track the up/down and side to side movement
var eulerX = node.presentation.eulerAngles.x
var eulerZ = node.presentation.eulerAngles.z

// Restrict the head movement so it doesn't rotate too far
if eulerX < self.rad(-90) { eulerX = self.rad(-90) }
if eulerX > self.rad(90) { eulerX = self.rad(90) }

if eulerZ < self.rad(-30) { eulerZ = self.rad(-30) }
if eulerZ > self.rad(30) { eulerZ = self.rad(30) }

let tempNode = SCNNode()
tempNode.transform = node.presentation.transform
tempNode.eulerAngles = SCNVector3(eulerX, 0, eulerZ)
return tempNode.transform

}

head?.constraints = [headConstraint, headRotationConstraint]

}

// Helper to convert degrees to radians
private func rad(_ deg: Float) -> Float {
return deg * Float.pi / 180
}

}

场景编辑器中的模型是:

enter image description here

最佳答案

我已经解决了我遇到的问题。有 2 个问题:

  1. followUserWithHead 中的目标应该已经为它的父级转换了 simdWorldPosition 并且从(而不是)转换为

    focusOfTheHead.parent!.simdConvertPosition(pov.simdWorldPosition, from: nil)

  2. 头节点的本地坐标不正确。 z 轴应该是 x 轴,所以当我获得焦点时头部运动跟踪,耳朵始终跟随相机。

enter image description here

我没有意识到 Xcode 中的Debug View Hierarchy 会显示 SCNScene 的细节。这帮助我调试场景并找到节点跟踪的位置。您可以将场景导出为 dae,然后加载到 SceneKit 编辑器中

编辑:我将 localFront 用作下面评论中建议的 mnuages,这使跟踪工作朝着正确的方向进行。不过,头部确实偶尔会动一下。我已将此归因于在模型上运行的动画,该动画试图应用一个转换,然后在下一个更新周期中更改该转换。我决定从头部移除跟踪并使用相同的方法仅跟踪眼睛。

关于ios - 场景中的 ARKit 3D 头部跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48095715/

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