【问题标题】:Unable to rotate an SCNNode in ARKit无法在 ARKit 中旋转 SCNNode
【发布时间】:2019-09-22 03:34:30
【问题描述】:

我正在尝试在 y 轴上旋转 SCNNode,以便我的节点(箭头)指向正确的方向。我想做一个使用 ARKit 的导航应用;每个箭头都需要指向我收到的路线的下一个位置。路线检索正常。

节点被添加到场景的rootNode。在某些时候,我遍历一个节点数组以将它们定位在场景中并对节点应用缩放(基于距离),这一切都正确完成。但是,当我应用旋转时,这没有效果。 旋转是通过修改节点的rotation属性来完成的:

directionNode.rotation = SCNVector4(x:0, y:1:, z:0, w:Float(bearing))

这并没有达到预期的效果。 我也试过用runAction方法,也没效果:

directionNode.runAction(SCNAction.rotateBy(x: 0, y: CGFloat(bearing), z: 0, duration: 0))

这是定位和缩放节点的代码。

for i in 0...(directionNodes.count - 1) {
    let directionNode = directionNodes[i]
    let translation = MatrixHelper.transformMatrix(for: matrix_identity_float4x4, originLocation: startingLocation, location: directionNode.location)
    let position = SCNVector3.positionFromTransform(translation)
    let distance = directionNode.location.distance(from: startingLocation)
    DispatchQueue.main.async {
        let scale = 100 / Float(distance)
        directionNode.scale = SCNVector3(x: scale, y: scale, z: scale)
        directionNode.anchor = ARAnchor(transform: translation)
        directionNode.position = position
        if (i < (self.directionNodes.count - 1)) {
            // Apply rotation to the arrow
            let successiveStepLocation = self.directionNodes[i + 1].location!
            let bearing = directionNode.location.bearingToLocationRadian(successiveStepLocation)
            // rotate
            directionNode.rotation = SCNVector4(x:0, y:1:, z:0, w:Float(bearing))
        }
    }
}

这一切都包含在一个 SCNTransaction 中。

谁能告诉我为什么节点的旋转不起作用?非常感谢任何帮助。

[编辑]:我忘了提到我试图旋转的 3D 箭头对象总是指向同一个方向。即使我“四处走动”,箭头也总是指向(在我的情况下)向左。 也许这有助于解决我的问题...

【问题讨论】:

    标签: swift transform scenekit arkit


    【解决方案1】:

    非常感谢您的回答,帮助我了解了不同的轮换方式。

    然而,事实证明节点上存在这样的约束:

    let billboardConstraint = SCNBillboardConstraint()
    billboardConstraint.freeAxes = SCNBillboardAxis.Y
    constraints = [billboardConstraint]
    

    注释此代码使旋转正常工作。好傻……

    根据文档,SCNBillboardConstraint 使对象的 z 轴始终指向 pointOfView 节点。但我不太了解这里的 freeAxes 属性。默认类型是all,因此它永远不会相对于视点旋转。那么如果我只设置Y约束类型,我只能在X和Z轴上应用旋转?还是我错了?

    【讨论】:

      【解决方案2】:

      更新:我认为问题出在您正在使用的 singleSided 着色器中。你看到了你的模型不可见的一面。只需为您的几何体启用 doubleSided 材质:

      directionNode.geometry?.firstMaterial?.isDoubleSided = true
      

      您需要使用以弧度表示的值(有效范围为-6.28+6.28)。

      对象旋转的方向很重要 >> CWCCW。在正旋转角度+.pi 时,您看不到single-sided 几何体(在某个角度)。

      它是这样工作的:

      myNode.rotation = SCNVector4(x: 0, y: -1, z: 0, w: (.pi * 3) / 2)
      

      ...当您也使用 SCNAction 时(不要忘记指定持续时间):

      let action = SCNAction.repeatForever(SCNAction.rotate(by: -.pi, 
                                                        around: SCNVector3(0,1,0), 
                                                      duration: 1.75))
      myNode.runAction(action)
      

      ...当您使用 SCNTransaction 时:

      let previousTransform = myNode.transform
      let rotate = SCNMatrix4MakeRotation(0, 1, 0, (-Float.pi/2))
      
      SCNTransaction.begin()
      SCNTransaction.animationDuration = 3.75
      myNode.transform = SCNMatrix4Mult(rotate, previousTransform)
      SCNTransaction.commit()
      

      【讨论】:

      • 对于轴承,我得到不同的值,例如 -1.70 或 3.09 我尝试像上面的示例一样应用旋转,但没有结果。我也尝试在不同的轴上旋转,仍然没有结果。我还添加了节点的悬停(上下移动)。这确实有效,但不知何故,旋转被“阻止”了。
      • 你能发布所有的代码看看那里发生了什么吗?
      • 当节点的几何返回nil时,这是什么意思?我可以看到场景中的物体。
      • 不。如果几何返回nil,则没有可查看的几何。这可能是由于锚点或缺少几何形状。
      猜你喜欢
      • 2017-12-03
      • 1970-01-01
      • 2018-08-04
      • 2016-03-18
      • 1970-01-01
      • 2019-01-30
      • 2021-12-25
      • 2018-10-26
      相关资源
      最近更新 更多