diff --git a/ios/Classes/SwiftPolyvoxFilamentPlugin.swift b/ios/Classes/SwiftPolyvoxFilamentPlugin.swift index 8ec0b4f0..8137385a 100644 --- a/ios/Classes/SwiftPolyvoxFilamentPlugin.swift +++ b/ios/Classes/SwiftPolyvoxFilamentPlugin.swift @@ -7,17 +7,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture var registrar : FlutterPluginRegistrar var textureId: Int64? var registry: FlutterTextureRegistry - - var width: Double = 0 - var height: Double = 0 - - var createdAt = Date() - - var targetPixelBuffer: CVPixelBuffer?; - // var context: EAGLContext?; - // var textureCache: CVOpenGLESTextureCache?; - // var texture: CVOpenGLESTexture? = nil; - // var frameBuffer: GLuint = 0; + + var pixelBuffer: CVPixelBuffer?; var pixelBufferAttrs = [ kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_32BGRA), @@ -27,7 +18,6 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture ] as CFDictionary var resources:NSMutableDictionary = [:] - var viewer:UnsafeMutableRawPointer? = nil var displayLink:CADisplayLink? = nil @@ -35,9 +25,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture var loadResourcePtr: UnsafeMutableRawPointer? = nil var freeResourcePtr: UnsafeMutableRawPointer? = nil - var resourcesPtr : UnsafeMutableRawPointer? = nil - - var _rendering = true + var loadResource : @convention(c) (UnsafeRawPointer, UnsafeMutableRawPointer) -> ResourceBuffer = { uri, resourcesPtr in @@ -138,29 +126,13 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture selector: #selector(doRender)) displayLink!.add(to: .current, forMode: RunLoop.Mode.default) } - - @objc func doRender() { - guard _rendering == true, let textureId = self.textureId, let viewer = viewer else { - return - } - render(viewer, 0) - self.registry.textureFrameAvailable(textureId) - } - - func forceRender() { - guard let textureId = self.textureId, let viewer = viewer else { - return - } - render(viewer, 0) - self.registry.textureFrameAvailable(textureId) - } - + public func copyPixelBuffer() -> Unmanaged? { - if(targetPixelBuffer == nil) { + if(pixelBuffer == nil) { print("empty") return nil; } - return Unmanaged.passRetained(targetPixelBuffer!); + return Unmanaged.passRetained(pixelBuffer!); } public func onTextureUnregistered(texture:FlutterTexture) { @@ -181,379 +153,42 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture } private func createPixelBuffer(width:Int, height:Int) { - - if(targetPixelBuffer != nil) { - destroy_swap_chain(self.viewer) - } if(CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height), - kCVPixelFormatType_32BGRA, pixelBufferAttrs, &targetPixelBuffer) != kCVReturnSuccess) { + kCVPixelFormatType_32BGRA, pixelBufferAttrs, &pixelBuffer) != kCVReturnSuccess) { print("Error allocating pixel buffer") } - print("Pixel buffer created") - } - - private func initialize(width:Int32, height:Int32) { - - if(self.viewer != nil) { - clear_assets(self.viewer) - clear_lights(self.viewer) - destroy_swap_chain(self.viewer) - delete_filament_viewer(self.viewer) - } - - print("Initializing with size \(width)x\(height)") - - createPixelBuffer(width:Int(width), height:Int(height)) self.textureId = self.registry.register(self) - - loadResourcePtr = unsafeBitCast(loadResource, to: UnsafeMutableRawPointer.self) - freeResourcePtr = unsafeBitCast(freeResource, to: UnsafeMutableRawPointer.self) - - viewer = create_filament_viewer_ios( - nil, - loadResourcePtr!, - freeResourcePtr!, - Unmanaged.passUnretained(self).toOpaque() - ) - - create_swap_chain( - self.viewer, - unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self), - UInt32(width), UInt32(height)) - - update_viewport_and_camera_projection(self.viewer!, width, height, 1.0); - - createDisplayLink() - } - private func resize(width:Int32, height:Int32) { - print("Resizing to size \(width)x\(height)") - if(self.textureId != nil) { - self.registry.unregisterTexture(self.textureId!) + private func resize(width:Int32, height:Int32) { + if(self.textureId != nil) { + self.registry.unregisterTexture(self.textureId!) + } + createPixelBuffer(width: Int(width), height:Int(height)) } - createPixelBuffer(width: Int(width), height:Int(height)) - - create_swap_chain( - self.viewer, - unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self), - UInt32(width), UInt32(height)) - - update_viewport_and_camera_projection(self.viewer!, width, height, 1.0); - - self.textureId = self.registry.register(self) - } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let methodName = call.method; switch methodName { - - case "addLight": - let args = call.arguments as! Array - let entity = add_light( - self.viewer, - args[0] as! UInt8, - Float(args[1] as! Double), - Float(args[2] as! Double), - Float(args[3] as! Double), - Float(args[4] as! Double), - Float(args[5] as! Double), - Float(args[6] as! Double), - Float(args[7] as! Double), - Float(args[8] as! Double), - args[9] as! Bool) - result(entity); - case "setAnimation": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let entityName = args[1] as! String - let morphData = (args[2] as! FlutterStandardTypedData) - - let numMorphWeights = args[3] as! Int - - let boneAnimations = args[4] as! Array> - let numBoneAnimations = boneAnimations.count - - var boneAnimStructs = UnsafeMutableBufferPointer.allocate(capacity: numBoneAnimations) - if numBoneAnimations > 0 { - for i in 0...numBoneAnimations - 1 { - let boneNames = boneAnimations[i][0] as! Array - let meshNames = boneAnimations[i][1] as! Array - let frameData = (boneAnimations[i][2] as! FlutterStandardTypedData) - let frameDataNative = UnsafeMutableBufferPointer.allocate(capacity: Int(frameData.elementCount)) - - frameData.data.withUnsafeBytes{ (floatPtr: UnsafePointer) in - for i in 0...Int(frameData.elementCount - 1) { - frameDataNative[i] = floatPtr.advanced(by: i).pointee - } - } - - var boneNameArray = UnsafeMutableBufferPointer?>.allocate(capacity: boneNames.count) - - for i in 0...boneNames.count - 1 { - boneNameArray[i] = UnsafePointer(strdup(boneNames[i])) - } - - var meshNameArray = UnsafeMutableBufferPointer?>.allocate(capacity: meshNames.count) - - for i in 0...meshNames.count - 1 { - meshNameArray[i] = UnsafePointer(strdup(meshNames[i])) - } - boneAnimStructs[i] = BoneAnimation( - boneNames: boneNameArray.baseAddress, - meshNames:meshNameArray.baseAddress, - data:frameDataNative.baseAddress, - numBones: boneNames.count, - numMeshTargets: meshNames.count - ) - } - } - - - let numFrames = args[5] as! Int - let frameLenInMs = args[6] as! Double - morphData.data.withUnsafeBytes { (morphDataNative: UnsafePointer) in - set_animation( - assetPtr, - entityName, - morphDataNative, - Int32(numMorphWeights), - boneAnimStructs.baseAddress, - Int32(boneAnimations.count), - Int32(numFrames), - Float(frameLenInMs) - ) - } - - boneAnimStructs.forEach { (boneAnimStruct:BoneAnimation) in - - for i in 0...boneAnimStruct.numBones - 1 { - boneAnimStruct.boneNames[i]?.deallocate() - } - boneAnimStruct.boneNames.deallocate() - - for i in 0...boneAnimStruct.numMeshTargets - 1 { - boneAnimStruct.meshNames[i]?.deallocate() - } - boneAnimStruct.meshNames.deallocate() - - boneAnimStruct.data.deallocate(); - - } - boneAnimStructs.deallocate() - result("OK") - case "initialize": - let args = call.arguments as! Array - initialize(width:args[0], height:args[1]) - result(self.textureId); - case "clearLights": - clear_lights(self.viewer); - result(true); - case "loadSkybox": - load_skybox(self.viewer!, call.arguments as! String) - result("OK"); - case "removeSkybox": - remove_skybox(self.viewer!) - result("OK"); - case "loadGlb": - let args = call.arguments as! Array - let assetPtr = load_glb(self.viewer, args[0] as! String, args[1] as! Bool) - result(unsafeBitCast(assetPtr, to:Int64.self)); - case "loadGltf": - let args = call.arguments as! Array - result(load_gltf(self.viewer, args[0] as! String, args[1] as! String)); - case "removeAsset": - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: call.arguments as! Int) - remove_asset(viewer!, assetPtr) - result("OK") - case "clearAssets": - clear_assets(viewer!) - result("OK") - case "loadIbl": - let args = call.arguments as! Array - load_ibl(self.viewer, args[0] as! String, Float(args[1] as! Double)) - result("OK"); - case "removeIbl": - remove_ibl(self.viewer) - result("OK"); - case "setCamera": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - set_camera(self.viewer, assetPtr, args[1] as! String) - result("OK"); - case "playAnimation": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let animationIndex = args[1] as! Int32; - let loop = args[2] as! Bool; - let reverse = args[3] as! Bool; - play_animation(assetPtr, animationIndex, loop, reverse) - result("OK"); - case "setAnimationFrame": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let animationIndex = args[1] as! Int32; - let animationFrame = args[2] as! Int32; - set_animation_frame(assetPtr, animationIndex, animationFrame) - result("OK"); - case "stopAnimation": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let animationIndex = args[1] as! Int32 - stop_animation(assetPtr, animationIndex) // TODO - result("OK"); - case "getMorphTargetNames": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let meshName = args[1] as! String - let numNames = get_morph_target_name_count(assetPtr, meshName) - var names = [String]() - if(numNames > 0) { - for i in 0...numNames - 1 { - let outPtr = UnsafeMutablePointer.allocate(capacity:256) - get_morph_target_name(assetPtr, meshName, outPtr, i) - names.append(String(cString:outPtr)) - } - } - result(names); - case "getAnimationNames": - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: call.arguments as! Int) - let numNames = get_animation_count(assetPtr) - var names = [String]() - for i in 0...allocate(capacity:256) - get_animation_name(assetPtr, outPtr, i) - names.append(String(cString:outPtr)) - } - result(names); - case "setMorphTargetWeights": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let entityName = args[1] as! String - let weights = args[2] as! Array - let count = args[3] as! Int - weights.map { Float($0) }.withUnsafeBufferPointer { - apply_weights(assetPtr, entityName, UnsafeMutablePointer.init(mutating:$0.baseAddress), Int32(count)) - - } - result("OK") - case "panStart": - let args = call.arguments as! Array - grab_begin(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), true) - result("OK") - case "panUpdate": - let args = call.arguments as! Array - grab_update(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double)) - result("OK") - case "panEnd": - grab_end(self.viewer) - result("OK") - case "removeLight": - remove_light(self.viewer,call.arguments as! Int32) - result(true); - case "render": - forceRender() - result("OK") + case "createTexture": + let args = call.arguments as! Array + createPixelBuffer(width:args[0], height:args[1]) + createDisplayLink() + result(unsafeBitCast(pixelBuffer!, to: UnsafeMutableRawPointer.self)) + case "getLoadResourceFn": + result(unsafeBitCast(loadResource, to: UnsafeMutableRawPointer.self)) + case "getFreeResourceFn": + result(unsafeBitCast(freeResource, to: UnsafeMutableRawPointer.self)) + case "getGlTextureId": + result(Unmanaged.passUnretained(self).toOpaque()) + case "getContext": + result(nil) case "resize": - let args = call.arguments as! Array - let width = Int32(args[0]) - let height = Int32(args[1]) - resize(width:width, height:height) - result(self.textureId) - case "rotateStart": - let args = call.arguments as! Array - grab_begin(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), false) - result("OK") - case "rotateUpdate": - let args = call.arguments as! Array - grab_update(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double)) - result("OK") - case "rotateEnd": - grab_end(self.viewer) - result("OK") - case "clearBackgroundImage": - clear_background_image(self.viewer!) - result("OK") - case "setBackgroundColor": - let args = call.arguments as! Array - set_background_color(self.viewer!, Float(args[0] as! Double),Float(args[1] as! Double),Float(args[2] as! Double), Float(args[3] as! Double)) - result("OK") - case "setBackgroundImage": - let uri = call.arguments as? String - set_background_image(self.viewer!, uri) - result("OK") - case "setBackgroundImagePosition": - let args = call.arguments as! Array - set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool) - result("OK"); - case "setPosition": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - let x = Float(args[1] as! Double) - set_position(assetPtr, x, Float(args[2] as! Double), Float(args[3] as! Double)) - result("OK") - case "setRotation": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - set_rotation(assetPtr, Float(args[1] as! Double), Float(args[2] as! Double), Float(args[3] as! Double), Float(args[4] as! Double)) - result("OK") - case "setScale": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - set_scale(assetPtr, Float(args[1] as! Double)) - result("OK"); - case "setCameraPosition": - let args = call.arguments as! Array - set_camera_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), Float(args[2] as! Double)) - result("OK"); - case "setCameraRotation": - let args = call.arguments as! Array - set_camera_rotation(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), Float(args[2] as! Double),Float(args[3] as! Double)) - result("OK") - case "setCameraModelMatrix": - let matrix = call.arguments as! FlutterStandardTypedData - matrix.data.withUnsafeBytes{ (floatPtr: UnsafePointer) in - set_camera_model_matrix(self.viewer, floatPtr) - } - result("OK") - case "setCameraExposure": - let args = call.arguments as! Array - set_camera_exposure(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double),Float(args[2] as! Double)) - result("OK"); - case "setCameraFocalLength": - set_camera_focal_length(self.viewer, Float(call.arguments as! Double)) - result("OK"); - case "setCameraFocusDistance": - // TODO - // set_camera_focus_distance(self.viewer, Float(call.arguments as! Double)) - // result("OK"); - break - case "setFrameInterval": - set_frame_interval(self.viewer, Float(call.arguments as! Double)); - result("OK") - case "setRendering": - _rendering = call.arguments as! Bool - result("OK") - case "setTexture": - let args = call.arguments as! Array - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int) - load_texture(assetPtr, args[1] as! String, args[2] as! Int32) - result("OK"); - case "transformToUnitCube": - let assetPtr = UnsafeMutableRawPointer.init(bitPattern: call.arguments as! Int) - transform_to_unit_cube(assetPtr) - result("OK"); - case "zoomBegin": - scroll_begin(self.viewer) - result("OK") - case "zoomUpdate": - let args = call.arguments as! Array - scroll_update(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double),Float(args[2] as! Double)) - result("OK") - case "zoomEnd": - scroll_end(self.viewer) - result("OK") + result(self.textureId); + case "tick": + self.registry.textureFrameAvailable(textureId) + result(true) default: result(FlutterMethodNotImplemented) }