Pet*_*ann 5 lidar scenekit swift arkit realitykit
LiDAR 的对象遮挡可在 RealityKit 中通过场景理解选项发挥作用。基本上,扫描的几何形状用于遮挡。
arView.environment.sceneUnderstanding.options.insert(.occlusion)
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这没有包含在 SceneKit 中。虽然仍然可以通过 ARMeshAnchor 从 LiDAR 获取扫描的几何图形,但必须从该几何图形手动完成对象遮挡。这是对此的讨论:苹果论坛
这种方法已经有解决方案了吗?
我通过执行以下操作在 SceneKit 中实现了对象遮挡:
//Before starting session, put this option in configuration
if ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) {
configuration.sceneReconstruction = .mesh
} else {
// Handle device that doesn't support scene reconstruction
}
// Run the view's session
sceneView.session.run(configuration)
Run Code Online (Sandbox Code Playgroud)
在这个方法中你会得到场景重建网格,所以像这样实现
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
guard let meshAnchor = anchor as? ARMeshAnchor else {
return nil
}
let geometry = createGeometryFromAnchor(meshAnchor: meshAnchor)
//apply occlusion material
geometry.firstMaterial?.colorBufferWriteMask = []
geometry.firstMaterial?.writesToDepthBuffer = true
geometry.firstMaterial?.readsFromDepthBuffer = true
let node = SCNNode(geometry: geometry)
//change rendering order so it renders before our virtual object
node.renderingOrder = -1
return node
}
Run Code Online (Sandbox Code Playgroud)
网格更新时更新您的节点
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let meshAnchor = anchor as? ARMeshAnchor else {
return
}
let geometry = createGeometryFromAnchor(meshAnchor: meshAnchor)
// Optionally hide the node from rendering as well
geometry.firstMaterial?.colorBufferWriteMask = []
geometry.firstMaterial?.writesToDepthBuffer = true
geometry.firstMaterial?.readsFromDepthBuffer = true
node.geometry = geometry
}
Run Code Online (Sandbox Code Playgroud)
其余方法
// Taken from https://developer.apple.com/forums/thread/130599
func createGeometryFromAnchor(meshAnchor: ARMeshAnchor) -> SCNGeometry {
let meshGeometry = meshAnchor.geometry
let vertices = meshGeometry.vertices
let normals = meshGeometry.normals
let faces = meshGeometry.faces
// use the MTL buffer that ARKit gives us
let vertexSource = SCNGeometrySource(buffer: vertices.buffer, vertexFormat: vertices.format, semantic: .vertex, vertexCount: vertices.count, dataOffset: vertices.offset, dataStride: vertices.stride)
let normalsSource = SCNGeometrySource(buffer: normals.buffer, vertexFormat: normals.format, semantic: .normal, vertexCount: normals.count, dataOffset: normals.offset, dataStride: normals.stride)
// Copy bytes as we may use them later
let faceData = Data(bytes: faces.buffer.contents(), count: faces.buffer.length)
// create the geometry element
let geometryElement = SCNGeometryElement(data: faceData, primitiveType: primitiveType(type: faces.primitiveType), primitiveCount: faces.count, bytesPerIndex: faces.bytesPerIndex)
return SCNGeometry(sources: [vertexSource, normalsSource], elements: [geometryElement])
}
func primitiveType(type: ARGeometryPrimitiveType) -> SCNGeometryPrimitiveType {
switch type {
case .line: return .line
case .triangle: return .triangles
default : return .triangles
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1130 次 |
| 最近记录: |