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

标签 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,但无法找到实现此功能的方法。 (我得到了一些非常疯狂的结果)。 任何帮助深表感谢。

更新 我让 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 专家想对此发表评论或提供建议,他们将不胜感激。 :)

关于swift - SceneKit 物理在局部空间中添加速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32038480/

相关文章:

iOS黑暗模式。用户界面样式在进入后台时来回更改

ios - 在调整时区时将特定日期字符串转换为 Swift 3 日期

arrays - 如何在 Swift 中使用索引和元素迭代循环

algorithm - 相似矩阵 -> 特征向量算法?

java - Java TreeMap put() 方法的奇怪行为

c++ - 泰勒级数在 sin(90) 和 cos(120) 之后得到 nan

swift - 替换 Storyboard 中的 ViewController,同时保留 Segues

c++ - 在结构中初始化结构 vector

javascript - 如何在 ECMAScript 中将点转换为极坐标?

javascript - 将 sin() 近似为 {1, 0, -1} 会给出错误的结果