沿世界轴旋转
Rotation along world axis
我正在做一个 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(by: 0.0, around: SCNVector3, duration: 0.5)
- SCNAction.rotate(toAxisAngle:SCNVector4,持续时间:0.5)
不幸的是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 游乐场中尝试。
希望这就是您要找的。
我正在做一个 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(by: 0.0, around: SCNVector3, duration: 0.5)
- SCNAction.rotate(toAxisAngle:SCNVector4,持续时间:0.5)
不幸的是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 游乐场中尝试。
希望这就是您要找的。