SceneKit 物理在局部空间中添加速度 [英] SceneKit physics add velocity in local space

查看:59
本文介绍了SceneKit 物理在局部空间中添加速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to manipulate the player node using physicsBody.velocity by adding or subtracting velocity to the axis for different directions. The problem is that I'm having trouble finding the method for applying that to local space or at least applying the velocity in relation to the direction the object is facing. In other words, it works fine if I have not rotated the object's node. If I do it will still add the velocity to the unrotated space. I know there is a way to add velocity to the current SCNVector3, but I cannot figure it out.

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 旋转节点.只要节点没有移动或旋转,就可以正常工作.如果有,它似乎也在使用世界空间.

I am also trying to rotate the node using angularVelocity in a similar fashion. That works fine as long as the node has not moved or rotated. If it has, it seems to be using world space as well.

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,但无法找到一种方法来完成这项工作.(我得到了一些非常疯狂的结果).任何帮助深表感谢.

After the physics are simulated, I am updating the node's position and rotation. I have also tried convertPosition, but could not figure out a way to make this work. (I got some really crazy results with this). Any help is much appreciated.

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

UPDATE I got the playerShip object to add velocity in the proper directions when it is rotated, but I am still unable to perform multiple rotations without it not turning in the correct direction. For the ship velocity I did this:

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

When trying to use a similar method for rotation (I know it would be doomed), the resulting SCNVector3 is just a position, not the direction the node is currently facing. Is there any information on convertTransform and how I might use that?

推荐答案

事实证明,我必须从场景的 rootNode 获得正确的位置,才能根据SCNNode 的当前方向.

As it turns out, I had to get the proper position from the rootNode of the scene to perform a proper rotation based on the current orientation of the 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 专家想对此发表评论或提供建议,他们将不胜感激.:)

Then I just used the standard quaternion rotation formula to get the rotation based on the new axes from the current position. I hope this helps someone else (and that more information on SceneKit is forthcoming) If any SceneKit experts want to comment on this or offer suggestions, they are much appreciated. :)

这篇关于SceneKit 物理在局部空间中添加速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆