如何解决如何使用Arkit Scenekit创建类似qlone 3d扫描仪应用程序的AR圆顶
我正在寻找在Scenekit中创建AR穹顶形状几何体的方法,就像它是在qlone 3D扫描仪应用程序中创建的一样。 请参考以下链接以获取视觉效果。
https://www.youtube.com/watch?v=0JQZmTT3KO0
https://3dscanexpert.com/qlone-3d-scanning-ios-app/
解决方法
模型 IO api MDLMesh.newEllipsoid 创建圆顶,现在我们需要在圆顶的每个部分上放置瓷砖。
- 创建圆顶并获取顶点,并使用顶点创建图块并将它们作为单独的 SCNNode 放置。
导入 UIKit 导入场景套件 导入 ARKit 导入模型IO
ARDome 类:SCNNode {
private var sceneView: ARSCNView!
private var radius: Float = 0.0
private var radialSegments: Int = 0
private var verticalSegments: Int = 0
private var maxDistanceToFocusPoint: Float = 0.05
private var minSize = SIMD3<Float>(0.01,0.01,0.01)
var tilesContinuousHitCount = [SCNNode:Int]()
private var extent = SIMD3<Float>(0.01,0.01) {
didSet {
extent = max(extent,minSize)
}
}
init(sceneView: ARSCNView,radius: Float,radialSegments: Int,verticalSegments: Int) {
super.init()
self.sceneView = sceneView
self.radius = radius
self.radialSegments = radialSegments
self.verticalSegments = verticalSegments
//self.categoryBitMask = 0x0
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func domeSkeleton() {
let mesh = MDLMesh.newEllipsoid(withRadii: vector_float3(radius,radius,radius),radialSegments: radialSegments,verticalSegments: verticalSegments,geometryType: MDLGeometryType.lines,inwardNormals: true,hemisphere: true,allocator: nil)
self.geometry = SCNGeometry(mdlMesh: mesh)
self.geometry?.firstMaterial?.diffuse.contents = UIColor.appYellow
self.geometry?.firstMaterial?.isDoubleSided = true
}
func placeTiles() {
guard let geometry = self.geometry else { return }
let vertices = helper.testim(geo: geometry)
let rings = vertices.chunked(into: radialSegments + 1)
for base in 0..<(verticalSegments/2) {
let bottom = base + 1
let top = base
for i in 0..<(radialSegments) {
let rectNode = helper.getNode(lb: rings[bottom][i],lt: rings[top][i],rt: rings[top][i+1],rb: rings[bottom][i+1])
self.addChildNode(rectNode)
}
}
}
}
助手类
导入 UIKit 导入场景套件 导入 ARKit 导入模型IO
类助手{ public static func getNode(lb: SCNVector3,lt: SCNVector3,rt: SCNVector3,rb: SCNVector3) -> DomeTile{ 让顶点:[SCNVector3] = [lb,lt,rt,rb,] 让源 = SCNGeometrySource(顶点:顶点) 让索引:[UInt16] = [0,1,2,3,] 让元素 = SCNGeometryElement(索引:索引,primitiveType:.triangles) 让几何 = SCNGeometry(来源:[来源],元素:[元素]) geometry.firstMaterial?.isDoubleSided = true geometry.firstMaterial?.diffuse.contents = UIColor.spectrumBlue.withAlphaComponent(0.7) 让节点 = DomeTile(几何:几何) 返回节点 }
public static func testim(geo: SCNGeometry) -> [SCNVector3] {
//let rect = SCNBox(width: 40.0,height: 40.0,length: 5.0,chamferRadius: 0.0)
let srcs = geo.sources(for: .vertex)
guard let src = srcs.first else { exit(1)}
let bperC = src.bytesPerComponent
let stride = src.dataStride / bperC
let offset = src.dataOffset / bperC
let vectorCount = src.vectorCount
let vertices = src.data.withUnsafeBytes { (buffer : UnsafePointer<Float>) -> [SCNVector3] in
var result = Array<SCNVector3>()
for i in 0...vectorCount - 1 {
let start = i * stride + offset
let x = buffer[start]
let y = buffer[start + 1]
let z = buffer[start + 2]
result.append(SCNVector3(x,y,z))
}
return result
}
return vertices
}
}
扩展数组{ func chunked(into size: Int) -> [[Element]] { return stride(from: 0,to: count,by: size).map 数组(self[$0 ..
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。