Ios 获取SCNNode所面对的方向

Ios 获取SCNNode所面对的方向,ios,game-physics,scenekit,Ios,Game Physics,Scenekit,我对scenekit中如何处理节点空间坐标和旋转感到迷茫 如何获得旋转后节点面对的方向,以便在该方向上施加力 我假设沿-z轴施加到节点上的力始终会使其相对于节点向前移动,但事实并非如此。负z是节点仅在其自身坐标空间(即其子节点和几何体所在的坐标空间)中的“面向”方向。应用力时,将在包含节点的坐标空间中工作 因此,如果你想在一个节点的前进方向上施加一个力,你需要使用一种方法将一个向量,比如{0,0,-1}从节点的空间转换到其父节点的空间。我也无法让convertPosition:toNode工作。

我对scenekit中如何处理节点空间坐标和旋转感到迷茫

如何获得旋转后节点面对的方向,以便在该方向上施加力

我假设沿-z轴施加到节点上的力始终会使其相对于节点向前移动,但事实并非如此。

负z是节点仅在其自身坐标空间(即其子节点和几何体所在的坐标空间)中的“面向”方向。应用力时,将在包含节点的坐标空间中工作


因此,如果你想在一个节点的前进方向上施加一个力,你需要使用一种方法将一个向量,比如
{0,0,-1}
从节点的空间转换到其父节点的空间。

我也无法让
convertPosition:toNode
工作。
ship.convertPosition(scinvector3(0,0,-0.1),toNode:ship.parentNode)上的变化使得节点以不可预测的方向和速度飞走

对我来说,有效的方法是抓取节点的
worldTransform
矩阵的第三行,它对应于它的z轴:

func getZForward(node: SCNNode) -> SCNVector3 {
    return SCNVector3(node.worldTransform.m31, node.worldTransform.m32, node.worldTransform.m33)
}

ship.position += getZForward(ship) * speed
// if node has a physics body, you might need to use the presentationNode, eg:
// getZForward(ship.presentationNode)
// though you probably don't want to be directly modifying the position of a node with a physics body

// overrides for SCNVector arithmetic
#if os(iOS)
    typealias VecFloat = Float
#elseif os (OSX)
    typealias VecFloat = CGFloat
#endif

func + (lhs: SCNVector3, rhs: SCNVector3) -> SCNVector3 {
    return SCNVector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z)
}

func * (lhs: SCNVector3, rhs: VecFloat) -> SCNVector3 {
    return SCNVector3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs)
}

func += (lhs: inout SCNVector3, rhs: SCNVector3) {
    lhs = lhs + rhs
}
如果节点具有物理实体,则可能必须将
节点.presentationNode
传递到函数中

当iOS 11/High Sierra面世时,重写SCInvector3的需要就会减少,因为所有的
SCNNode
属性都有
simd
等价物,还有
.position
.simdPosition
等等,并且内置了许多常见的simd操作

iOS 11更新 iOS 11增加了方便快捷的功能,用于获取节点的方向。在这种情况下,
worldForward
属性就是您想要的。此外,
SCNNode
上返回
scinvector
的所有属性和矩阵类型现在都有返回simd类型的版本。由于simd已经有算术运算符的重载,因此不再需要为
SCNVector
SCNMatrix
类型添加算术重写集

因此,我们可以去掉上面的out
getZForward
方法,只需要一行:

ship.simdPosition += ship.simdWorldFront * speed
iOS 11添加的另一组方便的方法是一组
convertVector
方法,以补充现有的
convertPosition
方法
convertVector
相当于将矩阵乘以
w
位置处
0
的向量,从而忽略矩阵的平移。这些是将法线、方向等从一个节点空间转换到另一个节点空间的适当方法


因为接受的答案使用了
convertPosition
,我相信它只会为转换为0,0,0原点的节点生成正确的结果

我一直在使用该方法,但是我似乎无法获得我想要的确切结果。将类似(0,0,1)的向量转换为要移动的节点的presentationNode坐标空间,直到节点移动为止,一旦移动,转换将不再代表节点的朝向。@user3765506是否介意将您的解决方案与仍然需要解决方案的人共享?二进制操作“+”无法在SCNVector上执行:@johndoe我用SCNVector overridesworldFront更新了答案是您正在查找的属性。谢谢,ship.simdPosition+=ship.simdWorldFront*速度正是我所需要的。它给了我前向向量,不管我的旋转是什么。