无法在ARKit中旋转SCNNode

4

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

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

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 箭头对象始终指向相同的方向。即使我“走过去”,箭头始终指向(在我的情况下)左侧。 也许这有助于解决我的问题...

2个回答

1

更新:我认为你使用的是 singleSided 着色器,导致你看到了模型的不可见侧面。只需为你的几何体启用doubleSided 材质即可:

directionNode.geometry?.firstMaterial?.isDoubleSided = true

你需要使用弧度值(有效范围为-6.28+6.28)。

你的物体旋转的方向很重要 >> CW 或者 CCW。当旋转角度为正的+.pi时,你无法看到在某个角度下的单面几何形状。

它的工作原理如下:

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

enter image description here


获取的方位角值不同,例如-1.70或3.09。 我尝试像上面的示例一样应用旋转,但没有结果。我还尝试在不同轴上旋转,仍然没有结果。 我还添加了节点的悬停(上下移动),它确实起作用,但旋转却“被阻止”了。 - Raoul
请发布所有代码以查看其中的问题? - Andy Jazz
当节点的几何体返回nil时,这意味着什么?但我可以在场景中看到该对象。 - Raoul
不行。如果几何体返回 nil,那么就没有几何体可以观察了。这可能是由于锚点或缺少几何体引起的。 - Andy Jazz

0
非常感谢您的回答,对我理解旋转的不同方式有很大帮助。
然而,事实证明节点上有一个限制条件,如下所示:
let billboardConstraint = SCNBillboardConstraint()
billboardConstraint.freeAxes = SCNBillboardAxis.Y
constraints = [billboardConstraint]

注释这段代码后,旋转才正常工作。真是太蠢了...

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接