SceneKit物理在局部空间中添加速度

时间:2015-08-16 18:27:22

标签: swift vector trigonometry scenekit

我试图通过向不同方向的轴添加或减去速度来使用physicsBody.velocity来操纵玩家节点。问题在于,我无法找到将其应用于局部空间的方法,或者至少应用与物体所面向方向相关的速度。换句话说,如果我没有旋转对象的节点,它工作正常。如果我这样做,仍然会将速度添加到未旋转的空间。 我知道有一种方法可以将速度添加到当前的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旋转节点。只要节点没有移动或旋转,这样就可以正常工作。如果有,它似乎也在使用世界空间。

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的任何信息以及我如何使用它?

1 个答案:

答案 0 :(得分:1)

事实证明,我必须从场景的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专家想对此发表评论或提供建议,我们非常感谢。 :)