如何像在 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 for
height` 我只是输入直径 (2*r))。
只是想知道是否可以(我知道可以,但如何)像在 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 for
height` 我只是输入直径 (2*r))。