Post

Replies

Boosts

Views

Activity

Reply to Updating mesh vertex positions per frame (from CPU)
I sorta figured out a way to do this. The key is to use SCNGeometrySource's proper initializer that takes an MTLBuffer as input: https://developer.apple.com/documentation/scenekit/scngeometrysource/1522873-init. I'm posting my pseudo code here in case anyone comes across the same issue. swift /* initialize color buffer, similarly for vertex buffer */ var color_buffer_array : [UInt8] = [] /* appending rgba values (0...1) to the color buffer */ color_buffer_array.append(contentsOf: withUnsafeBytes(of: Float(UInt8(xyzrgb[6])!) / 255.0, Array.init)) color_buffer_array.append(contentsOf: withUnsafeBytes(of: Float(UInt8(xyzrgb[7])!) / 255.0, Array.init)) color_buffer_array.append(contentsOf: withUnsafeBytes(of: Float(UInt8(xyzrgb[8])!) / 255.0, Array.init)) color_buffer_array.append(contentsOf: withUnsafeBytes(of: Float(1.0), Array.init)) curr_point_cloud.color_buffer = Data(color_buffer_array) /* NOTE: use 4 UInt8's for rgba in Data, use 4 Floats for rgba in MTLBuffer below is an example of not using MTLBuffer, so color cannot be updated in real time //    curr_point_cloud.color_source = SCNGeometrySource(data: curr_point_cloud.color_buffer!, //                             semantic: .color, //                             vectorCount: curr_point_cloud.points.count, // number of vertices //                             usesFloatComponents: true, // this has to be true in order to display correct color //                             componentsPerVector: 4, // 4 UInt8's: r, g, b, a //                             bytesPerComponent: 1, // 1 UInt8 == 1 byte //                             dataOffset: 0, //                             dataStride: 4) // 4 * 1/ /* below is an example of using MTLBuffer, so color can be updated in real time */ curr_point_cloud.color_buffer!.withUnsafeBytes { rawBufferPointer in       let rawPtr = rawBufferPointer.baseAddress!       curr_point_cloud.color_mtl_buffer = mtl_device!.makeBuffer(bytes: rawPtr, length: curr_point_cloud.color_buffer!.count, options: [])       curr_point_cloud.tmp_color_mtl_buffer = mtl_device!.makeBuffer(bytes: rawPtr, length: curr_point_cloud.color_buffer!.count, options: [])       curr_point_cloud.color_source = SCNGeometrySource(buffer: curr_point_cloud.color_mtl_buffer!, vertexFormat: .float4, semantic: .color, vertexCount: curr_point_cloud.points.count, dataOffset: 0, dataStride: 16) } /* update MTLBuffer     // NOTE: two options, change color_mtl_buffer directly, or change tmp_color_mtl_buffer and use blit command     func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {       if DataModel.shared.point_cloud_objects.count == 0 { return }       // https://stackoverflow.com/questions/40476426/scenekit-metal-depth-buffer       let commandBuffer = DataModel.shared.mtl_command_queue!.makeCommandBuffer()!       let blitCommandEncoder: MTLBlitCommandEncoder = commandBuffer.makeBlitCommandEncoder()!       blitCommandEncoder.copy(from: DataModel.shared.point_cloud_objects[0].tmp_color_mtl_buffer!, sourceOffset: 0, to: DataModel.shared.point_cloud_objects[0].color_mtl_buffer!, destinationOffset: 0, size: DataModel.shared.point_cloud_objects[0].color_buffer!.count)       blitCommandEncoder.endEncoding()       commandBuffer.commit()     }/
Apr ’21