我试图创建一个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
的第二列提取值并将其设置为eulerAngles
,rotation
和simdRotation
的不同组合,但是没有果。
我还尝试从当前pointOfView
的{{1}}中提取值,并将它们分配给上面列出的相同值,但同样没有运气。
任何帮助都会非常感谢!
我对此有所了解,但我真的只是开始使用SceneKit和3D转换/矩阵,所以要对我温和!
答案 0 :(得分:2)
我想我知道你要做什么,基本上会自动删除每个新的多米诺骨牌,使其在camera.pointOfView跟踪后均匀分布。
您可以将新节点的euler角度y轴更新为与摄像机pointofView 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