Pas*_*cal 5 3d ios scenekit swift arkit
我想绕其 x 轴旋转节点(更具体地说,我想转动轮子)。
车轮是汽车的子节点。我在 stackoverflow 上发现了一些关于这个问题的线程,例如这个,但没有一个解决方案适合我:
我尝试了以下代码:
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)
}
Run Code Online (Sandbox Code Playgroud)
但车轮仍然绕着全车的中心转动。
以下代码用于旋转本身,但不应与我认为的解决方案相关:
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")
Run Code Online (Sandbox Code Playgroud)
(顺便说一句:我需要更改代码中的枢轴,而不需要在 SceneKit 界面生成器中设置额外的容器节点并将其移动到节点中心)
节点的局部轴通常不像这个心脏那样位于几何形状的中心。
\n\n\n\n您有两个选项可以使轴重新居中。您可以将函数添加到代码中。
\n\n func centerPivot(for node: SCNNode) {\n var min = SCNVector3Zero\n var max = SCNVector3Zero\n node.__getBoundingBoxMin(&min, max: &max)\n node.pivot = SCNMatrix4MakeTranslation(\n min.x + (max.x - min.x)/2,\n min.y + (max.y - min.y)/2,\n min.z + (max.z - min.z)/2\n )\n}\nRun Code Online (Sandbox Code Playgroud)\n\n调用该函数
\n\ncentrePivot(for: wheelNode)\nRun Code Online (Sandbox Code Playgroud)\n\n您可以像这样将其应用于节点。这会将枢轴放置在节点边界框的中心。但我\xe2\x80\x99ve发现你有时需要根据你需要从哪里开始修改该函数......这可能是一个反复试验的过程,直到它的位置完美为止。
\n\n另一种方法是在SketchUp等 3D 创作工具中打开 collada(dae 文件),并在本例中将(每个车轮几何形状)制作为组件(如果它已经不是 \xe2\x80\x99t)。从那里您可以重置组件轴,并将轴重新定位到每个车轮的几何中心。
\n\n在许多情况下,汽车、直升机和您想要动画化的其他模型等的免费 dae 模型并不是由作者为了动画化而创建的,因此动画几何体的几何分组和轴不在\xe2\x80\x99t中正确的枢轴位置。您可能还希望轴位于旋转门等的铰链上,因此它会偏离中心,并且可能很难正确设置。所以我认为最好知道如何在 3D 模型本身中进行轴调整(对于枢轴点)。
\n好吧,不知怎的,我找到了一个可行的解决方案:(不知道这是否是最好的方法 - 但它绝对适合我。)
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)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2862 次 |
| 最近记录: |