Как нарисовать пунктирную линию в ARKit (SceneKit), как в приложении Measure?
Просто хотел узнать, возможно ли (я знаю, что это так, но как) нарисовать пунктирную линию в ARSCNView, как в приложении Measure? Может быть, есть способ использовать узлы сцены из коробки, 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)
}
...
}
1 ответ
Возможно, не самое профессиональное решение, но я начал с очень похожего подхода. И затем добавил пунктирный стиль, как следует.
Сначала я создал изображение наполовину белое, наполовину прозрачное, чтобы создать штриховой стиль
Затем использовал его в материале 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* р)).