Scenekit 中的变换和旋转
Transform and Rotate in Scenekit
我有一个 SCN 节点,我已将其转换为所需的旋转和角度。
我现在想在新的 x 轴上无限旋转它,但我似乎无法让它旋转 360 度,它只是稍微移动了一点。
let spin = CABasicAnimation(keyPath: "rotation")
spin.fromValue = NSValue(SCNVector4: SCNVector4(x: item.rotation.x, y: item.rotation.y, z: item.rotation.z, w: item.rotation.w))
spin.toValue = NSValue(SCNVector4: SCNVector4(x: Float(2*M_PI), y: item.rotation.y, z: item.rotation.z, w: item.rotation.w))
spin.duration = 3
spin.repeatCount = .infinity
item.addAnimation(spin, forKey: "spin around")
注意我从之前的问题中找到了旋转代码,它按预期工作,但如果我想在转换后的节点上旋转则不行。
编辑:转换代码:
self.item.transform = SCNMatrix4Mult(SCNMatrix4Mult(SCNMatrix4MakeScale(1.1, 1.1, 1.1), SCNMatrix4MakeRotation(2.2, 228.0, 120.0, 55.2)), SCNMatrix4MakeTranslation(-2.5, 12, 6))
self.item.pivot = SCNMatrix4MakeTranslation(0, 0, 4)
self.item.transform = SCNMatrix4Mult(SCNMatrix4MakeTranslation(0, 0, 4), item.transform)
回答您的评论和可能的问题。安装 .dae 文件后,您可以访问以下示例中的节点:
// "rhodopsin" is the namne of a .dae file
guard let rho = SCNScene(named: "rhodopsin") else {
print("Couldn't find molecule in dictionary (rhodopsin)")
return }
let chain = rho.rootNode.childNodeWithName("chain", recursively: true)!
let hetero = rho.rootNode.childNodeWithName("hetero", recursively: true)!
如果您需要查找这些节点的名称,请在编辑器中打开 .dae 文件 window 并单击左下方的小边栏图标。在那个侧栏中是场景图(下图)。您不仅可以看到层次结构,还可以重命名,如有必要,还可以移动节点并重新设置父级(小心)。
您可能需要添加其他保护措施以防止找不到文件。我正在使用它来构建档案,而不是客户端。
继续这个例子:
baseNode.addChildNode(chain)
baseNode.addChildNode(hetero)
// (baseNode is a child of the current scene's root node)
这些现在的行为就像您在 SceneKit
中创建的节点一样。在我的例子中,如果 chain
有一些调整的方向阻止了简单的动画,比如世界的 y 轴,可以旋转 baseNode
。或者,如果它需要与 hetero
分开的旋转,我会将它放在一个新的、否则为空的节点中并旋转它。
let panNode = SCNNode()
panNode.addChildNode(chain)
baseNode.addChildNode(panNode)
// perform rotations on panNode or baseNode
我有一个 SCN 节点,我已将其转换为所需的旋转和角度。
我现在想在新的 x 轴上无限旋转它,但我似乎无法让它旋转 360 度,它只是稍微移动了一点。
let spin = CABasicAnimation(keyPath: "rotation")
spin.fromValue = NSValue(SCNVector4: SCNVector4(x: item.rotation.x, y: item.rotation.y, z: item.rotation.z, w: item.rotation.w))
spin.toValue = NSValue(SCNVector4: SCNVector4(x: Float(2*M_PI), y: item.rotation.y, z: item.rotation.z, w: item.rotation.w))
spin.duration = 3
spin.repeatCount = .infinity
item.addAnimation(spin, forKey: "spin around")
注意我从之前的问题中找到了旋转代码,它按预期工作,但如果我想在转换后的节点上旋转则不行。
编辑:转换代码:
self.item.transform = SCNMatrix4Mult(SCNMatrix4Mult(SCNMatrix4MakeScale(1.1, 1.1, 1.1), SCNMatrix4MakeRotation(2.2, 228.0, 120.0, 55.2)), SCNMatrix4MakeTranslation(-2.5, 12, 6))
self.item.pivot = SCNMatrix4MakeTranslation(0, 0, 4)
self.item.transform = SCNMatrix4Mult(SCNMatrix4MakeTranslation(0, 0, 4), item.transform)
回答您的评论和可能的问题。安装 .dae 文件后,您可以访问以下示例中的节点:
// "rhodopsin" is the namne of a .dae file
guard let rho = SCNScene(named: "rhodopsin") else {
print("Couldn't find molecule in dictionary (rhodopsin)")
return }
let chain = rho.rootNode.childNodeWithName("chain", recursively: true)!
let hetero = rho.rootNode.childNodeWithName("hetero", recursively: true)!
如果您需要查找这些节点的名称,请在编辑器中打开 .dae 文件 window 并单击左下方的小边栏图标。在那个侧栏中是场景图(下图)。您不仅可以看到层次结构,还可以重命名,如有必要,还可以移动节点并重新设置父级(小心)。 您可能需要添加其他保护措施以防止找不到文件。我正在使用它来构建档案,而不是客户端。
继续这个例子:
baseNode.addChildNode(chain)
baseNode.addChildNode(hetero)
// (baseNode is a child of the current scene's root node)
这些现在的行为就像您在 SceneKit
中创建的节点一样。在我的例子中,如果 chain
有一些调整的方向阻止了简单的动画,比如世界的 y 轴,可以旋转 baseNode
。或者,如果它需要与 hetero
分开的旋转,我会将它放在一个新的、否则为空的节点中并旋转它。
let panNode = SCNNode()
panNode.addChildNode(chain)
baseNode.addChildNode(panNode)
// perform rotations on panNode or baseNode