沿世界轴旋转

Vel*_*its 1 ios scenekit swift

我正在开发一个 SceneKit 项目,我想在三个轴(世界轴)上旋转一个对象,但是一旦我旋转该对象,下一次旋转就会相对于新的旋转轴完成。

想象一个立方体,您应该能够使用相对于世界的三个按钮在绝对 x 轴、y 轴和 z 轴上旋转。

据我所知 SCNAction 有以下选项:

  • SCNAction.rotateTo(x:1.0,y:0.0,z:0.0,持续时间:0.5,usesShortestUnitArc:true)
  • SCNAction.rotateTo(x: 1.0, y: 0.0, z: 0.0, 持续时间: 0.5)
  • SCNAction.rotateBy(x: 1.0, y: 0.0, z: 0.0, 持续时间: 0.5)
  • SCNAction.rotate(通过:0.0,周围:SCNVector3,持续时间:0.5)
  • SCNAction.rotate(toAxisAngle:SCNVector4,持续时间:0.5)

不幸的是,这些都不是绝对的,它们都依赖于之前的轮换。

你知道有什么方法可以实现真正的绝对世界轴旋转吗?

我在这里先向您的帮助表示感谢!

jls*_*ert 5

要绕世界轴旋转节点,请将节点乘以worldTransform旋转矩阵。

我还没有找到 的解决方案SCNAction,但使用SCNTransaction非常简单。

func rotate(_ node: SCNNode, around axis: SCNVector3, by angle: CGFloat, duration: TimeInterval, completionBlock: (()->())?) {
    let rotation = SCNMatrix4MakeRotation(angle, axis.x, axis.y, axis.z)
    let newTransform = node.worldTransform * rotation

    // Animate the transaction
    SCNTransaction.begin()
    // Set the duration and the completion block
    SCNTransaction.animationDuration = duration
    SCNTransaction.completionBlock = completionBlock

    // Set the new transform
    node.transform = newTransform

    SCNTransaction.commit()
}
Run Code Online (Sandbox Code Playgroud)

如果节点的父节点具有不同的变换,则此方法不起作用,但我们可以通过将结果变换转换为父节点坐标空间来解决此问题。

func rotate(_ node: SCNNode, around axis: SCNVector3, by angle: CGFloat, duration: TimeInterval, completionBlock: (()->())?) {
    let rotation = SCNMatrix4MakeRotation(angle, axis.x, axis.y, axis.z)
    let newTransform = node.worldTransform * rotation

    // Animate the transaction
    SCNTransaction.begin()
    // Set the duration and the completion block
    SCNTransaction.animationDuration = duration
    SCNTransaction.completionBlock = completionBlock

    // Set the new transform
    if let parent = node.parent {
        node.transform = parent.convertTransform(newTransform, from: nil)
    } else {
        node.transform = newTransform
    }

    SCNTransaction.commit()
}
Run Code Online (Sandbox Code Playgroud)

您可以在这个Swift Playground中尝试一下。

我希望这就是您正在寻找的。

  • let newTransform = node.worldTransform * 旋转在 Swift 4 中生成错误。替换为 let newTransform = SCNMatrix4Mult(node.worldTransform,rotation) (2认同)