SceneKit:围绕自身旋转节点
SceneKit: rotate node around itself
我想围绕它的 x 轴旋转一个节点(更具体地说,我想转动一个轮子)。
车轮是汽车的子节点。我在 Whosebug 上发现了几个关于这个问题的线程,例如 但没有一个解决方案对我有用:
我尝试了以下代码:
if let wheel = sceneView.scene.rootNode.childNode(withName: "WheelRearL", recursively: true) {
// also tried:
// wheel.pivot = SCNMatrix4MakeTranslation(0.5, 0.5, 0.5)
let (minVec, maxVec) = (wheel.boundingBox)
wheel.pivot = SCNMatrix4MakeTranslation(-25, (maxVec.y - minVec.y) / 2 + minVec.y, (maxVec.z - minVec.z) / 2 + minVec.z)
}
但是车轮还是绕着整车的中心转
以下代码用于旋转本身,但与我认为的解决方案无关:
let spin = CABasicAnimation.init(keyPath: "rotation")
spin.fromValue = NSValue(scnVector4: SCNVector4(x: 25, y: 0, z: 0, w: 0))
spin.toValue = NSValue(scnVector4: SCNVector4(x:25, y: 0, z: 0, w: Float(CGFloat(2 * M_PI))))
spin.duration = 3
spin.repeatCount = .infinity
let wheel = sceneView.scene.rootNode.childNode(withName: "WheelRearL", recursively: true)
wheel?.addAnimation(spin, forKey: "spin around")
(顺便说一句:我需要更改代码中的枢轴,而无需在 SceneKit 界面构建器中设置额外的容器节点并将其移动到节点中心)
好吧,不知何故我找到了一个可行的解决方案:(不知道这是否是最好的方法 - 但它绝对适合我。)
if let w = sceneView.scene.rootNode.childNode(withName: name, recursively: true) {
let (minVec, maxVec) = w.boundingBox
w.position.x = -25 / 100
w.position.y = ((maxVec.y - minVec.y) / 2 + minVec.y) / 100
w.position.z = ((maxVec.z - minVec.z) / 2 + minVec.z) / 100
w.pivot = SCNMatrix4MakeTranslation(-25, (maxVec.y - minVec.y) / 2 + minVec.y, (maxVec.z - minVec.z) / 2 + minVec.z)
}
节点的局部轴通常不像这颗心那样位于几何体的中心。
您有两个选项可以使轴重新居中。您可以在代码中添加一个函数。
func centerPivot(for node: SCNNode) {
var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)
node.pivot = SCNMatrix4MakeTranslation(
min.x + (max.x - min.x)/2,
min.y + (max.y - min.y)/2,
min.z + (max.z - min.z)/2
)
}
调用函数
centrePivot(for: wheelNode)
你像这样应用到节点。这会将枢轴放置在节点边界框的中心。但我发现你有时需要根据你需要从哪里开始修改那个函数......这可能是一个反复试验的过程,直到它的位置完美。
另一种方法是在 SketchUp 等 3D 创作工具中打开 collada(dae 文件),并在这种情况下(每个车轮几何形状)制作成一个组件(如果还没有的话) .从那里您可以重置组件轴,并将轴重新定位到每个车轮的几何中心。
在许多情况下,您想要制作动画的汽车、直升机和其他模型等的免费 dae 模型并不是作者为制作动画而创建的,因此动画几何的几何分组和轴不是在正确的枢轴位置。您可能还希望轴位于摆动门等的铰链上,这样它就会偏离中心,并且可以 fiddle 得到正确的结果。所以我认为最好知道如何在 3D 模型本身中进行轴调整(对于枢轴点)。
我知道现在回答已经很晚了。但我找到了一种绕自身轴旋转节点的方法。关键点是:创建父节点并将目标节点添加为子节点。
您可以使用下面的代码围绕其 X 轴旋转“hudNode”:
let containerNode = SCNNode()
containerNode.addChildNode(hudNode)
let roteAction = SCNAction.rotate(by: 3.14, around: SCNVector3(1,0,0), duration: 0)
hudNode.runAction(roteAction)
然后你可以把containerNode放到你喜欢的任何地方。
我想围绕它的 x 轴旋转一个节点(更具体地说,我想转动一个轮子)。
车轮是汽车的子节点。我在 Whosebug 上发现了几个关于这个问题的线程,例如
我尝试了以下代码:
if let wheel = sceneView.scene.rootNode.childNode(withName: "WheelRearL", recursively: true) {
// also tried:
// wheel.pivot = SCNMatrix4MakeTranslation(0.5, 0.5, 0.5)
let (minVec, maxVec) = (wheel.boundingBox)
wheel.pivot = SCNMatrix4MakeTranslation(-25, (maxVec.y - minVec.y) / 2 + minVec.y, (maxVec.z - minVec.z) / 2 + minVec.z)
}
但是车轮还是绕着整车的中心转
以下代码用于旋转本身,但与我认为的解决方案无关:
let spin = CABasicAnimation.init(keyPath: "rotation")
spin.fromValue = NSValue(scnVector4: SCNVector4(x: 25, y: 0, z: 0, w: 0))
spin.toValue = NSValue(scnVector4: SCNVector4(x:25, y: 0, z: 0, w: Float(CGFloat(2 * M_PI))))
spin.duration = 3
spin.repeatCount = .infinity
let wheel = sceneView.scene.rootNode.childNode(withName: "WheelRearL", recursively: true)
wheel?.addAnimation(spin, forKey: "spin around")
(顺便说一句:我需要更改代码中的枢轴,而无需在 SceneKit 界面构建器中设置额外的容器节点并将其移动到节点中心)
好吧,不知何故我找到了一个可行的解决方案:(不知道这是否是最好的方法 - 但它绝对适合我。)
if let w = sceneView.scene.rootNode.childNode(withName: name, recursively: true) {
let (minVec, maxVec) = w.boundingBox
w.position.x = -25 / 100
w.position.y = ((maxVec.y - minVec.y) / 2 + minVec.y) / 100
w.position.z = ((maxVec.z - minVec.z) / 2 + minVec.z) / 100
w.pivot = SCNMatrix4MakeTranslation(-25, (maxVec.y - minVec.y) / 2 + minVec.y, (maxVec.z - minVec.z) / 2 + minVec.z)
}
节点的局部轴通常不像这颗心那样位于几何体的中心。
您有两个选项可以使轴重新居中。您可以在代码中添加一个函数。
func centerPivot(for node: SCNNode) {
var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)
node.pivot = SCNMatrix4MakeTranslation(
min.x + (max.x - min.x)/2,
min.y + (max.y - min.y)/2,
min.z + (max.z - min.z)/2
)
}
调用函数
centrePivot(for: wheelNode)
你像这样应用到节点。这会将枢轴放置在节点边界框的中心。但我发现你有时需要根据你需要从哪里开始修改那个函数......这可能是一个反复试验的过程,直到它的位置完美。
另一种方法是在 SketchUp 等 3D 创作工具中打开 collada(dae 文件),并在这种情况下(每个车轮几何形状)制作成一个组件(如果还没有的话) .从那里您可以重置组件轴,并将轴重新定位到每个车轮的几何中心。
在许多情况下,您想要制作动画的汽车、直升机和其他模型等的免费 dae 模型并不是作者为制作动画而创建的,因此动画几何的几何分组和轴不是在正确的枢轴位置。您可能还希望轴位于摆动门等的铰链上,这样它就会偏离中心,并且可以 fiddle 得到正确的结果。所以我认为最好知道如何在 3D 模型本身中进行轴调整(对于枢轴点)。
我知道现在回答已经很晚了。但我找到了一种绕自身轴旋转节点的方法。关键点是:创建父节点并将目标节点添加为子节点。 您可以使用下面的代码围绕其 X 轴旋转“hudNode”:
let containerNode = SCNNode()
containerNode.addChildNode(hudNode)
let roteAction = SCNAction.rotate(by: 3.14, around: SCNVector3(1,0,0), duration: 0)
hudNode.runAction(roteAction)
然后你可以把containerNode放到你喜欢的任何地方。