【问题标题】:SceneKit: rotate node around itselfSceneKit:围绕自身旋转节点
【发布时间】:2018-07-05 20:16:21
【问题描述】:

我想围绕它的 x 轴旋转一个节点(更具体地说,我想转动一个轮子)。

车轮是汽车的子节点。我在stackoverflow上发现了几个关于这个问题的线程,例如this 但没有一个解决方案对我有用:

我尝试了以下代码:

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

【问题讨论】:

  • 检查这个stackoverflow.com/questions/47927620/…也许可以帮助你
  • 恐怕这并没有真正的帮助,因为旋转本身是有效的,真正的问题是我相信的支点......
  • 尝试使用SCNAction.rotate(by: value around: SCNVector3Make(1,0 , 0), duration: 0.2) 尝试我发布的答案并告诉我,但请试一试

标签: ios swift 3d scenekit arkit


【解决方案1】:

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

    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)
    }

【讨论】:

    【解决方案2】:

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

    您有两个选项可以使轴重新居中。您可以在代码中添加一个函数。

     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)
    

    您像这样应用于节点。这会将枢轴放置在节点边界框​​的中心。但我发现您有时需要根据需要从哪里调整该函数……这可能是一个反复试验的过程,直到它的位置完美。

    另一种方法是在 3D 创作工具(例如 SketchUp)中打开 collada(dae 文件),并在这种情况下将(每个车轮几何形状)制作成一个组件(如果还没有的话)。从那里您可以重置组件轴,并将轴重新定位到每个车轮的几何形状中心。

    在许多情况下,汽车、直升机和其他您想要制作动画的模型的免费 dae 模型并非由作者创建并打算制作动画,因此动画几何的几何分组和轴不在正确的枢轴位置。您可能还希望轴位于摆动门等的铰链上,这样它就会偏离中心,并且可以很容易地得到正确的结果。所以我认为最好知道如何在 3D 模型本身中进行轴调整(针对枢轴点)。

    【讨论】:

      【解决方案3】:

      我知道现在回答已经很晚了。但我找到了一种绕自身轴旋转节点的方法。重点是:创建父节点,添加目的节点为子节点。 您可以使用下面的代码围绕其 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放到你喜欢的任何地方。

      【讨论】:

        猜你喜欢
        • 2014-10-05
        • 2019-01-14
        • 2020-08-25
        • 1970-01-01
        • 2016-11-23
        • 2016-09-10
        • 1970-01-01
        • 2018-12-17
        • 2019-08-05
        相关资源
        最近更新 更多