获得SCNNode面临的方向
我迷失了如何在scenekit中处理节点空间坐标和旋转。
如何在旋转后获得节点所面向的方向,以便我可以在该方向上施加力。
我假设沿着-z轴施加到节点的力总是相对于节点向前移动,但事实并非如此。
负z是节点的“面向”方向,仅在其自己的坐标空间中(即其子节点和几何体所在的坐标空间中)。 应用力时,您正在包含节点的坐标空间中工作。
因此,如果要在节点的前向方向上应用力,则需要使用convertPosition:toNode:
等方法将节点空间中的{0,0,-1}
等向量转换为父节点。
我也无法获得convertPosition:toNode
工作。 ship.convertPosition(SCNVector3(0,0,-0.1), toNode: ship.parentNode)
使节点以不可预测的方向和速度飞行。
对我worldTransform
是抓住节点的worldTransform
矩阵的第三行,它对应于它的z-forward轴:
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 }
如果节点具有物理主体,则可能必须将node.presentationNode
传递给函数。
当iOS 11 / High Sierra出现时,对覆盖SCNVector3的需求就会减少,因为所有SCNNode
属性都有simd
等价物,以及.position
还有.simdPosition
等等,并且有很多常见的simd操作内置的。
iOS 11更新
iOS 11增加了便捷的便利function,可以获取节点的方向。 在这种情况下, worldForward
属性就是您想要的属性。 此外, SCNNode
上返回SCNVector
和矩阵类型的所有属性现在都具有返回simd类型的版本。 因为simd已经有算术运算符的重载,所以不再需要为SCNVector
和SCNMatrix
类型添加算术覆盖的SCNVector
。
所以我们可以摆脱上面的getZForward
方法,只需要行:
ship.simdPosition += ship.simdWorldFront * speed
iOS 11添加的另一组方法是一组convertVector
方法,以补充现有的convertPosition
方法。 convertVector
相当于在w
位置将矩阵乘以向量乘以0
,从而忽略矩阵的平移。 这些是用于将法线,方向等事物从一个节点的空间转换为另一个节点的适当方法。
因为接受的答案使用convertPosition
,我相信它只会为翻译为0,0,0原点的节点产生正确的结果