SceneKit 物理在本地添加速度 space

SceneKit physics add velocity in local space

我正在尝试使用 physicsBody.velocity 通过为不同方向的轴增加或减少速度来操纵玩家节点。问题是我无法找到将其应用于本地 space 的方法,或者至少应用与对象所面对的方向相关的速度。换句话说,如果我没有旋转对象的节点,它就可以正常工作。如果我这样做,它仍会将速度添加到未旋转的 space。 我知道有一种方法可以为当前的 SCNVector3 添加速度,但我无法弄清楚。

if isZThrustPositive {
        if let velocity = self.physicsBody?.velocity {
            if velocity.z * 100 <= 8000 {
                thrustDirection = SCNVector3(
                    x: velocity.x,
                    y: velocity.y,
                    z: velocity.z + kPlayerShipMainThrust)
                self.physicsBody?.velocity = thrustDirection
            }
        }
    }

我也在尝试以类似的方式使用 angularVelocity 旋转节点。只要节点没有移动或旋转,它就可以正常工作。如果有,它似乎也在使用世界 space。

if isYRotatingPositive {
        if let angularVel = self.physicsBody?.angularVelocity {
            self.physicsBody?.angularVelocity = SCNVector4(
                x: angularVel.x,
                y: angularVel.y + kPlayerShipRotationSpeed,
                z: angularVel.z,
                w: angularVel.w + kPlayerShipRotationMagnitude)
        }
    }

物理模拟完成后,我正在更新节点的位置和旋转。 我也尝试过 convertPosition,但无法找到一种方法来完成这项工作。 (我得到了一些非常疯狂的结果)。 任何帮助深表感谢。

UPDATE 我让 playerShip 对象在旋转时在正确的方向上增加速度,但如果它没有朝正确的方向转动,我仍然无法执行多次旋转. 对于船速,我这样做了:

if isXThrustPositive {
        thrustDirection = self.convertPosition(SCNVector3(x: kPlayerShipMainThrust, y: 0.0, z: 0.0), toNode: self.parentNode!)
        thrustDirection.x = thrustDirection.x - self.position.x
        thrustDirection.y = thrustDirection.y - self.position.y
        thrustDirection.z = thrustDirection.z - self.position.z
        self.physicsBody?.applyForce(thrustDirection, impulse: true)
    }

当尝试使用类似的方法进行旋转时(我知道这注定会失败),结果SCNVector3只是一个位置,而不是节点当前面对的方向。是否有任何关于 convertTransform 的信息以及我如何使用它?

事实证明,我必须从场景的 rootNode 中获取正确的位置才能根据 SCNNode 的当前方向执行正确的旋转。

xAxis = self.convertPosition(SCNVector3Make(1.0, 0.0, 0.0), toNode: self.parentNode!)
yAxis = self.convertPosition(SCNVector3Make(0.0, 1.0, 0.0), toNode: self.parentNode!)
zAxis = self.convertPosition(SCNVector3Make(0.0, 0.0, 1.0), toNode: self.parentNode!)
if isXRotatingPositive {
    self.physicsBody?.applyTorque(
        SCNVector4(
            x: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.x - self.position.x),
            y: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.y - self.position.y),
            z: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.z - self.position.z),
            w: cos(kPlayerShipRotationSpeed/2.0) * kPlayerShipRotationMagnitude),
        impulse: true)
    }

然后我只是使用标准四元数旋转公式从当前位置获取基于新轴的旋转。 我希望这对其他人有帮助(并且即将发布有关 SceneKit 的更多信息) 如果任何 SceneKit 专家想对此发表评论或提供建议,他们将不胜感激。 :)