无法在ARKit中旋转SCNNode

时间:2019-05-03 14:53:43

标签: swift transform scenekit arkit

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

将节点添加到场景的rootNode。在某个点上,我遍历了一系列节点以将它们放置在场景中,并将缩放应用于节点(基于距离),所有步骤均正确完成。但是,当我应用旋转时,这没有效果。 通过修改节点的旋转属性来完成旋转:

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 个答案:

答案 0 :(得分:0)

  

更新:我认为问题出在您使用的singleSided着色器中。您会看到模型的不可见面。只需为您的几何图形启用 doubleSided 材料:

directionNode.geometry?.firstMaterial?.isDoubleSided = true

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

  

重要的是您的对象朝哪个方向旋转>> CWCCW。您看不到single-sided的几何形状(以一定角度旋转 )。{p> 1。

它是这样工作的:

+.pi

...以及当您使用SCNAction时(也不要忘记分配持续时间):

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

...以及当您使用SCNTransaction时:

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

enter image description here

希望这会有所帮助。

答案 1 :(得分:0)

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

但是,事实证明,这样的节点存在约束:

SELECT m.manufacturer_id
    , m.name
    , COUNT(p.product_id) AS products_total 
FROM oc20_product p 
LEFT JOIN oc20_product_description pd ON pd.product_id = p.product_id 
LEFT JOIN oc20_manufacturer m ON m.manufacturer_id = p.manufacturer_id 
WHERE pd.name LIKE concat('%',mycard,'%') AND p.status = 1 
GROUP BY m.manufacturer_id, m.name
ORDER BY m.name ASC 

注释此代码可使旋转正常工作。挺蠢的...

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