沿世界轴旋转

Rotation along world axis

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

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

据我所知,SCNAction 有以下选项:

不幸的是none这些都是绝对的,它们都依赖于之前的旋转。

你知道实现真实绝对世界轴旋转的方法吗?

提前感谢您的帮助!

要绕世界轴旋转节点,请将节点 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()
}

如果节点的父节点具有不同的变换,这将不起作用,但我们可以通过将生成的变换转换为父坐标 space.

来解决此问题
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()
}

您可以在 this Swift 游乐场中尝试。

希望这就是您要找的。