【问题标题】:Position SCNNode in front of camera with just one axis of rotation仅使用一个旋转轴将 SCNNode 定位在相机前面
【发布时间】:2018-07-06 00:27:26
【问题描述】:

我正在尝试制作一个 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 转换/矩阵开始,所以请对我温柔一点!

【问题讨论】:

    标签: ios swift rotation scenekit arkit


    【解决方案1】:

    我想我知道你想做什么,基本上是自动放下每个新的多米诺骨牌,使其均匀分布在 camera.pointOfView 轨迹之后。

    您可以将新节点欧拉角 y 轴更新为与查看 eularAngles.y 的相机点相同。因此,当您围绕下一个节点移动相机时,您放置的节点始终面向相机(仅围绕 y 轴旋转)。

    下面的渲染器函数 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
    

    【讨论】:

    • 感谢您的回复!会试试这个,让你知道我是怎么做到的
    • 它可以工作,但orientation 保持零值,所以,如果你需要那个角度,这是没用的
    • 您的评论含糊不清,无法解读。有效但没用? developer.apple.com/documentation/scenekit/scnnode/…
    猜你喜欢
    • 2018-07-09
    • 1970-01-01
    • 2016-09-26
    • 2020-04-07
    • 2019-10-29
    • 2021-07-07
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多