仅使用一个旋转轴将SCNNode定位在摄像机前

时间:2018-01-26 16:11:31

标签: ios swift rotation scenekit arkit

我试图创建一个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的不同组合,但是没有果。

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

任何帮助都会非常感谢!

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

1 个答案:

答案 0 :(得分: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