首页 文章

只需一个旋转轴即可将SCNNode放置在摄像机前方

提问于
浏览
0

我正在尝试制作一个ARKit应用程序,其中SCNNode(在这种情况下是一个盒子)放在摄像机前面,面向摄像机 . 当用户移动相机时,在移动一定距离时放置物体 . 这会让你有一系列节点面向摄像机,线间距相等 .

我在一定程度上有这个工作,但我的问题是旋转 . 我正在使用所有旋转轴,因此当用户重新定位他们的手机时,节点的旋转匹配 . 我想将其限制为围绕y轴的旋转 . 理想的结果是类似于多米诺骨牌的外观,所有物体具有相同的x和z旋转,但可能有不同的y旋转 .

我希望我已经足够清楚地解释了这一点!

这是我目前使用的代码:

func createNode(fromCameraTransform cameraTransform: matrix_float4x4) -> SCNNode {
    let geometry = SCNBox(width: 0.02, height: 0.04, length: 0.01, chamferRadius: 0)

    let physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: geometry))
    physicsBody.mass = 1000

    let node = SCNNode(geometry: geometry)
    node.physicsBody = physicsBody

    var translationMatrix = matrix_identity_float4x4
    translationMatrix.columns.3.x = 0.05  // Moves the node down in world space
    translationMatrix.columns.3.z = -0.1  // Moves the object away from the camera

    node.simdTransform = simd_mul(cameraTransform, translationMatrix)

    return node
}

我尝试了从 cameraTransform 的第二列中提取值的不同组合,并将它们设置为 eulerAnglesrotationsimdRotation ,但无济于事 .

我还尝试从当前 sceneViewpointOfView 中提取值并将它们分配给上面列出的相同值,但同样没有运气 .

任何帮助将非常感谢!

我对此有所了解,但我真的只是开始使用SceneKit和3D转换/矩阵,所以请对我温柔!

1 回答

  • 2

    我想我知道你要做什么,基本上会自动丢弃每个新的多米诺骨牌,使其在camera.pointOfView跟踪后均匀分布 .

    您可以将新节点的euler角度y轴更新为与摄像机pointofView eularAngles.y相同 . 因此,当您将相机移动到下一个放置的节点时,始终面向相机(仅绕y轴旋转) .

    enter image description here

    每次相机移动时,都会调用下面的渲染器函数updateAtTime

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    
    
    // You set the camera’s pointOfView’s eularAngle for y-xis to the node you are 
       about to place.
    
    node.eulerAngles.y = (sceneView.pointOfView?.eulerAngles.y)!
    
    • 我在操场上工作,所以它确实有效 .

    编辑:这个角度以上的解决方案有一个万向节锁定问题(当你绕过一个圆圈时会将其角度重置回轴 .

    所以我发现这种方法使用SCNBillboardConstraint工作时没有经历万向锁定问题,因为你绕圈子 .

    let yFreeConstraint = SCNBillboardConstraint()
                    yFreeConstraint.freeAxes = .Y 
                    node.constraints = [yFreeConstraint]
                    node.eulerAngles = node.presentation.eulerAngles
                    node.position = position
    

    enter image description here

相关问题