SceneKit:围绕自身旋转节点

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 界面生成器中设置额外的容器节点并将其移动到节点中心)

Cla*_*lay 5

节点的局部轴通常不像这个心脏那样位于几何形状的中心。

\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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

调用该函数

\n\n
centrePivot(for: wheelNode)\n
Run 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


Pas*_*cal 0

好吧,不知怎的,我找到了一个可行的解决方案:(不知道这是否是最好的方法 - 但它绝对适合我。)

    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)