如何像在 Measure 应用程序中一样在 ARKit (SceneKit) 中绘制虚线?

How to draw dashed line in ARKit (SceneKit) like in the Measure app?

只是想知道是否可以(我知道可以,但如何)像在 Measure 应用程序中一样在 ARSCNView 中绘制虚线? 也许有一种方法可以开箱即用地使用场景节点,idk。

我一直在使用 SCNCylinder 绘制直线,IDK 是否可以重复使用它并进行调整,或者我们必须使用一种完全不同的方式来制作虚线。

import SceneKit

class CylinderLineNode: SCNNode {

    private(set) var cylinder: SCNCylinder
    private(set) var positionA: SCNVector3
    private(set) var positionB: SCNVector3

    init(with positionA: SCNVector3, positionB: SCNVector3, radius: CGFloat = 0.02, color: UIColor = .red) {
        self.positionA = positionA
        self.positionB = positionB
        let vector = positionB - positionA
        let height = vector.length()
        cylinder = SCNCylinder(radius: radius, height: CGFloat(height))
        cylinder.radialSegmentCount = 8
        cylinder.firstMaterial?.diffuse.contents = color
        super.init()
        geometry = cylinder
        position = (positionB + positionA) / 2
        eulerAngles = SCNVector3.lineEulerAngles(vector: vector)
    }

    ...

}

可能不是最专业的解决方案,但我从非常相似的方法入手。然后添加如下虚线样式。

首先我创建了一个半白半透明的图像来创建虚线样式

然后在SCNCylinder的material中使用:

material.diffuse.contents = UIImage(named: "line")!
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
material.isDoubleSided = true // Not sure if this is really needed here^

接下来我相应地缩放它,按照我的意愿重复它(让它尽可能好):

material.diffuse.contentsTransform = SCNMatrix4MakeScale(width * repeatCountPerMeter, height * repeatCountPerMeter, 1)

因为我使用的是白色图像,所以我可以"tint"它是我想要的任何颜色:

material.multiply.contents = UIColor.green

为了让它看起来更像“2D”,请忽略灯光,使用:

material.lighting = .constant

此外(因为我的圆柱体旋转了 90°)我还必须旋转 material:

let rotation = SCNMatrix4MakeRotation(.pi / 2, 0, 0, 1)
material.diffuse.contentsTransform = SCNMatrix4Mult(rotation, material.diffuse.contentsTransform)

并且每当调整线的大小时,相应地更新其 SCNMatrix4MakeScale(参见 width 和高度 above, where forheight` 我只是输入直径 (2*r))。