我有一个3d矢量我作为物理力量应用:
let force = SCNVector3(x: 0, y: 0, z: -5)
node.physicsBody?.applyForce(force, asImpulse: true)
我需要根据mobile device's position将力旋转为4x4矩阵变换或欧拉角。
var transform:matrix_float4x4 - 摄像机在世界坐标空间中的位置和方向。
var eulerAngles:vector_float3 - 摄像机的方向,表示为滚动,俯仰和偏航值。
我认为这更像是一个基本的3D图形问题,但这个应用程序是使用SceneKit和ARKit的基于Swift的iOS应用程序。
我可以在SceneKit和simd库中使用一些实用工具。不幸的是,我天真地试图做simd_mul(force, currentFrame.camera.transform)
这样的事情让我失望。
答案 0 :(得分:6)
@orangenkopf提供了great answer,帮助我提出了这个问题:
let force = simd_make_float4(0, 0, -5, 0)
let rotatedForce = simd_mul(currentFrame.camera.transform, force)
let vectorForce = SCNVector3(x:rotatedForce.x, y:rotatedForce.y, z:rotatedForce.z)
node.physicsBody?.applyForce(vectorForce, asImpulse: true)
答案 1 :(得分:3)
你的想法是对的。您需要将变换和方向相乘。
我在simd_mul
找不到任何文档。但我怀疑你至少有以下一个问题:
simd_mul
同时应用转换的旋转和转换SceneKit没有提供太多的线性代数函数,所以我们必须自己构建:
extension SCNMatrix4 {
static public func *(left: SCNMatrix4, right: SCNVector4) -> SCNVector4 {
let x = left.m11*right.x + left.m21*right.y + left.m31*right.z + left.m41*right.w
let y = left.m12*right.x + left.m22*right.y + left.m32*right.z + left.m42*right.w
let z = left.m13*right.x + left.m23*right.y + left.m33*right.z + left.m43*right.w
let w = left.m14*right.x + left.m24*right.y + left.m43*right.z + left.m44*right.w
return SCNVector4(x: x, y: y, z: z, w: w)
}
}
extension SCNVector4 {
public func to3() -> SCNVector3 {
return SCNVector3(self.x , self.y, self.z)
}
}
现在执行以下操作:
// Convert the tranform to a SCNMatrix4
let transform = SCNMatrix4FromMat4(currentFrame.camera.transform)
// Convert the matrix to the nodes coordinate space
let localTransform = node.convertTransform(transform, from: nil)
let force = SCNVector4(0, 0, -5, 0)
let rotatedForce = (localTransform * force).to3()
node.physicsBody?.applyForce(rotatedForce, asImpulse: true)