我正在研究一个SceneKit项目,我想在三个轴(世界轴)上旋转一个物体但是一旦我旋转了物体,下一个旋转就会相对于新的旋转轴完成。
想象一个立方体,你应该能够使用相对于世界的三个按钮在绝对x和y和z轴上旋转。
据我所知,SCNAction有以下选项:
不幸的是,这些都不是绝对的,所有这些都依赖于之前的轮换。
你知道如何实现真正的绝对世界轴旋转吗?
提前感谢您的帮助!
答案 0 :(得分: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()
}
如果节点的父节点具有不同的变换,则此方法无效,但我们可以通过将生成的变换转换为父节点坐标空间来解决此问题。
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 Playground尝试此操作。
我希望这就是你要找的东西。