2017-05-25 207 views
0

我正在使用一个SceneKit项目,我想在三个坐标轴(世界轴)上旋转一个物体,但是一旦我旋转了物体,下一个旋转就相对于新的旋转轴完成了。沿着世界坐标轴旋转

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

据我知道有用于SCNAction以下选项:

  • SCNAction.rotateTo(X:1.0,Y:0.0,Z:0.0,持续时间:0.5, usesShortestUnitArc:真)
  • 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。旋转(by:0.0,around:SCNVector3,duration:0.5)
  • SCNAction.rotate(toAxisAngle:SCNVector4,持续时间:0.5)

可惜这些都不是绝对的,它们都依赖于前面的旋转。

你知道任何方式来实现真正的绝对世界轴旋转吗?

感谢您的帮助!

回答

3

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

如果节点有不同的变换父这是不行的,但我们可以通过转换所得的变换父母坐标空间解决这个问题。

您可以在this Swift Playground试试这个。

我希望这是你在找什么。

+0

谢谢Orangenkopf,好主意! – Velykovits

+0

保存我的一天,谢谢你! –

+0

如果父母的职位不是(0,0,0),是否也适用?当我尝试这种方法时,节点正在绕父轴旋转,而不是沿着它自己的(已转换)轴旋转 - 我错过了什么? –