首页 > 解决方案 > 如何像在 Measure 应用程序中一样在 ARKit (SceneKit) 中绘制虚线?

问题描述

只是想知道是否可以像在 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)
    }

    ...

}

标签: swiftscenekitarkitscnnode

解决方案


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

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

然后在材质中使用它SCNCylinder

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)

当我使用白色图像时,我可以将其“着色”为我想要的任何颜色:

material.multiply.contents = UIColor.green

为了使它看起来更像“2D”,请忽略照明,使用:

material.lighting = .constant

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

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

并且每当调整线的大小时,SCNMatrix4MakeScale相应地更新它(请参阅width和高度高度above, where for`我只是放了直径(2 * r))。


推荐阅读