rearrange source/header files for compatibility with CocoaPods Framework structure
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 572 KiB |
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
#import "PolyvoxFilamentApi.h"
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
import Flutter
|
|
||||||
import UIKit
|
|
||||||
import OpenGLES.ES3
|
|
||||||
import GLKit
|
|
||||||
|
|
||||||
|
|
||||||
public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture {
|
|
||||||
|
|
||||||
var registrar : FlutterPluginRegistrar
|
|
||||||
var textureId: Int64?
|
|
||||||
var registry: FlutterTextureRegistry
|
|
||||||
|
|
||||||
var width: Double = 0
|
|
||||||
var height: Double = 0
|
|
||||||
|
|
||||||
var context: EAGLContext?;
|
|
||||||
var targetPixelBuffer: CVPixelBuffer?;
|
|
||||||
var textureCache: CVOpenGLESTextureCache?;
|
|
||||||
var texture: CVOpenGLESTexture? = nil;
|
|
||||||
var frameBuffer: GLuint = 0;
|
|
||||||
|
|
||||||
|
|
||||||
var pixelBufferAttrs = [
|
|
||||||
kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_32BGRA),
|
|
||||||
kCVPixelBufferOpenGLCompatibilityKey: kCFBooleanTrue,
|
|
||||||
kCVPixelBufferOpenGLESCompatibilityKey: kCFBooleanTrue,
|
|
||||||
kCVPixelBufferIOSurfacePropertiesKey: [:]
|
|
||||||
] as CFDictionary
|
|
||||||
|
|
||||||
var resources:NSMutableDictionary = [:]
|
|
||||||
var viewer:UnsafeMutableRawPointer? = nil
|
|
||||||
|
|
||||||
var displayLink:CADisplayLink? = nil
|
|
||||||
|
|
||||||
static var messenger : FlutterBinaryMessenger? = nil;
|
|
||||||
|
|
||||||
var loadResourcePtr: UnsafeMutableRawPointer? = nil
|
|
||||||
var freeResourcePtr: UnsafeMutableRawPointer? = nil
|
|
||||||
var resourcesPtr : UnsafeMutableRawPointer? = nil
|
|
||||||
|
|
||||||
var loadResource : @convention(c) (UnsafeRawPointer, UnsafeMutableRawPointer) -> ResourceBuffer = { uri, resourcesPtr in
|
|
||||||
print("Loading resource buffer")
|
|
||||||
|
|
||||||
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
|
||||||
|
|
||||||
let uriString = String(cString:uri.assumingMemoryBound(to: UInt8.self))
|
|
||||||
|
|
||||||
let key = instance.registrar.lookupKey(forAsset:uriString)
|
|
||||||
|
|
||||||
let path = Bundle.main.path(forResource: key, ofType:nil)
|
|
||||||
do {
|
|
||||||
let foo: String = path!
|
|
||||||
let data = try Data(contentsOf: URL(fileURLWithPath:foo))
|
|
||||||
let resId = instance.resources.count
|
|
||||||
let nsData = data as NSData
|
|
||||||
instance.resources[resId] = nsData
|
|
||||||
let rawPtr = nsData.bytes
|
|
||||||
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
|
|
||||||
} catch {
|
|
||||||
print("Error opening file: \(error)")
|
|
||||||
return ResourceBuffer()
|
|
||||||
}
|
|
||||||
return ResourceBuffer()
|
|
||||||
}
|
|
||||||
|
|
||||||
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
|
||||||
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
|
||||||
instance.resources.removeObject(forKey:rid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createDisplayLink() {
|
|
||||||
displayLink = CADisplayLink(target: self,
|
|
||||||
selector: #selector(doRender))
|
|
||||||
|
|
||||||
displayLink!.add(to: .current, forMode: RunLoop.Mode.default)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func doRender() {
|
|
||||||
if(viewer != nil) {
|
|
||||||
render(viewer)
|
|
||||||
self.registry.textureFrameAvailable(self.textureId!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func copyPixelBuffer() -> Unmanaged<CVPixelBuffer>? {
|
|
||||||
if(targetPixelBuffer == nil) {
|
|
||||||
print("empty")
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
return Unmanaged.passRetained(targetPixelBuffer!);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
||||||
let _messenger = registrar.messenger();
|
|
||||||
messenger = _messenger;
|
|
||||||
let channel = FlutterMethodChannel(name: "app.polyvox.filament/event", binaryMessenger: _messenger)
|
|
||||||
let instance = SwiftPolyvoxFilamentPlugin(textureRegistry: registrar.textures(), registrar:registrar)
|
|
||||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
init(textureRegistry: FlutterTextureRegistry, registrar:FlutterPluginRegistrar) {
|
|
||||||
self.registry = textureRegistry;
|
|
||||||
self.registrar = registrar
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
print("Error allocating pixel buffer")
|
|
||||||
}
|
|
||||||
if(self.viewer != nil) {
|
|
||||||
create_swap_chain(self.viewer, unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self))
|
|
||||||
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Pixel buffer created")
|
|
||||||
}
|
|
||||||
|
|
||||||
private func initialize(width:Int32, height:Int32) {
|
|
||||||
|
|
||||||
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 = filament_viewer_new_ios(
|
|
||||||
unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self),
|
|
||||||
loadResourcePtr!,
|
|
||||||
freeResourcePtr!,
|
|
||||||
Unmanaged.passUnretained(self).toOpaque()
|
|
||||||
)
|
|
||||||
|
|
||||||
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
|
||||||
|
|
||||||
createDisplayLink()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
||||||
let methodName = call.method;
|
|
||||||
|
|
||||||
switch methodName {
|
|
||||||
case "initialize":
|
|
||||||
let args = call.arguments as! Array<Int32>
|
|
||||||
initialize(width:args[0], height:args[1])
|
|
||||||
result(self.textureId);
|
|
||||||
case "setBackgroundImage":
|
|
||||||
let uri = call.arguments as! String
|
|
||||||
set_background_image(self.viewer!, uri)
|
|
||||||
render(self.viewer!)
|
|
||||||
self.registry.textureFrameAvailable(self.textureId!)
|
|
||||||
result("OK")
|
|
||||||
case "resize":
|
|
||||||
let args = call.arguments as! Array<Double>
|
|
||||||
let width = Int(args[0])
|
|
||||||
let height = Int(args[1])
|
|
||||||
createPixelBuffer(width: width, height:height)
|
|
||||||
result("OK")
|
|
||||||
case "loadSkybox":
|
|
||||||
load_skybox(self.viewer!, call.arguments as! String)
|
|
||||||
result("OK");
|
|
||||||
case "removeSkybox":
|
|
||||||
remove_skybox(self.viewer!)
|
|
||||||
result("OK");
|
|
||||||
case "loadGlb":
|
|
||||||
let assetPtr = load_glb(self.viewer, call.arguments as! String)
|
|
||||||
result(unsafeBitCast(assetPtr, to:Int64.self));
|
|
||||||
case "loadGltf":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
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":
|
|
||||||
load_ibl(self.viewer, call.arguments as! String)
|
|
||||||
result("OK");
|
|
||||||
case "removeIbl":
|
|
||||||
remove_ibl(self.viewer)
|
|
||||||
result("OK");
|
|
||||||
case "setCamera":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
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<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let animationIndex = args[1] as! Int32;
|
|
||||||
let loop = args[2] as! Bool;
|
|
||||||
play_animation(assetPtr, animationIndex, loop)
|
|
||||||
result("OK");
|
|
||||||
case "stopAnimation":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let animationIndex = args[1] as! Int32
|
|
||||||
stop_animation(assetPtr, animationIndex) // TODO
|
|
||||||
result("OK");
|
|
||||||
case "getTargetNames":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let meshName = args[1] as! String
|
|
||||||
let numNames = get_target_name_count(assetPtr, meshName)
|
|
||||||
var names = [String]()
|
|
||||||
for i in 0...numNames - 1{
|
|
||||||
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
|
||||||
get_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...numNames - 1{
|
|
||||||
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
|
||||||
get_animation_name(assetPtr, outPtr, i)
|
|
||||||
names.append(String(cString:outPtr))
|
|
||||||
}
|
|
||||||
result(names);
|
|
||||||
case "applyWeights":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let weights = args[1] as! Array<Double>
|
|
||||||
weights.map { Float($0) }.withUnsafeBufferPointer {
|
|
||||||
apply_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(weights.count))
|
|
||||||
|
|
||||||
}
|
|
||||||
result("OK")
|
|
||||||
case "zoom":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let factor = args[1] as! Double
|
|
||||||
scroll(assetPtr, 0,0, Float(factor))
|
|
||||||
result("OK")
|
|
||||||
case "animateWeights":
|
|
||||||
let args = call.arguments as! Array<Any?>
|
|
||||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
|
||||||
let frameData = args[1] as! Array<Double>
|
|
||||||
let numWeights = args[2] as! Int
|
|
||||||
let numFrames = args[3] as! Int
|
|
||||||
let frameLenInMs = args[4] as! Double
|
|
||||||
frameData.map { Float($0)}.withUnsafeBufferPointer {
|
|
||||||
animate_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(numWeights), Int32(numFrames), Float(frameLenInMs))
|
|
||||||
}
|
|
||||||
result("OK")
|
|
||||||
case "panStart":
|
|
||||||
let args = call.arguments as! Array<Any>
|
|
||||||
grab_begin(self.viewer, args[0] as! Int32, args[1] as! Int32, true)
|
|
||||||
result("OK")
|
|
||||||
case "panUpdate":
|
|
||||||
let args = call.arguments as! Array<Any>
|
|
||||||
grab_update(self.viewer, args[0] as! Int32, args[1] as! Int32)
|
|
||||||
result("OK")
|
|
||||||
case "panEnd":
|
|
||||||
grab_end(self.viewer)
|
|
||||||
result("OK")
|
|
||||||
case "rotateStart":
|
|
||||||
let args = call.arguments as! Array<Any>
|
|
||||||
grab_begin(self.viewer, args[0] as! Int32, args[1] as! Int32, false)
|
|
||||||
result("OK")
|
|
||||||
case "rotateUpdate":
|
|
||||||
let args = call.arguments as! Array<Any>
|
|
||||||
grab_update(self.viewer, args[0] as! Int32, args[1] as! Int32)
|
|
||||||
result("OK")
|
|
||||||
case "rotateEnd":
|
|
||||||
grab_end(self.viewer)
|
|
||||||
result("OK")
|
|
||||||
case "setPosition":
|
|
||||||
let args = call.arguments as! Array<Any>
|
|
||||||
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<Any>
|
|
||||||
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")
|
|
||||||
default:
|
|
||||||
result(FlutterMethodNotImplemented)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#define _POLYVOX_FILAMENT_API_H
|
#define _POLYVOX_FILAMENT_API_H
|
||||||
|
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
#include "LightManager.hpp"
|
|
||||||
|
|
||||||
typedef struct ResourceBuffer ResourceBuffer;
|
typedef struct ResourceBuffer ResourceBuffer;
|
||||||
|
|
||||||
@@ -31,11 +30,10 @@ void scroll_begin(void* viewer);
|
|||||||
void scroll_update(void* viewer, float x, float y , float z);
|
void scroll_update(void* viewer, float x, float y , float z);
|
||||||
void scroll_end(void* viewer);
|
void scroll_end(void* viewer);
|
||||||
|
|
||||||
void grab_begin(void* viewer, int x, int y, bool pan);
|
void grab_begin(void* viewer, float x, float y, bool pan);
|
||||||
void grab_update(void* viewer, int x, int y);
|
void grab_update(void* viewer, float x, float y);
|
||||||
void grab_end(void* viewer);
|
void grab_end(void* viewer);
|
||||||
|
|
||||||
|
|
||||||
void apply_weights(void* asset, float* const weights, int count);
|
void apply_weights(void* asset, float* const weights, int count);
|
||||||
|
|
||||||
void animate_weights(void* asset, float* data, int numWeights, int numFrames, float frameRate);
|
void animate_weights(void* asset, float* data, int numWeights, int numFrames, float frameRate);
|
||||||
@@ -61,11 +59,10 @@ void set_texture(void* asset);
|
|||||||
void transform_to_unit_cube(void* asset);
|
void transform_to_unit_cube(void* asset);
|
||||||
|
|
||||||
void set_position(void* asset, float x, float y, float z);
|
void set_position(void* asset, float x, float y, float z);
|
||||||
|
|
||||||
void set_rotation(void* asset, float rads, float x, float y, float z);
|
void set_rotation(void* asset, float rads, float x, float y, float z);
|
||||||
|
void set_scale(void* asset, float scale);
|
||||||
|
|
||||||
void set_camera_position(void* viewer, float x, float y, float z);
|
void set_camera_position(void* viewer, float x, float y, float z);
|
||||||
|
|
||||||
void set_camera_rotation(void* viewer, float rads, float x, float y, float z);
|
void set_camera_rotation(void* viewer, float rads, float x, float y, float z);
|
||||||
void set_camera_focal_length(void* viewer, float focalLength);
|
void set_camera_focal_length(void* viewer, float focalLength);
|
||||||
void set_camera_focus_distance(void* viewer, float focusDistance);
|
void set_camera_focus_distance(void* viewer, float focusDistance);
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
void* filament_viewer_new_ios(void* texture, void* loadResource, void* freeResource, void* resources);
|
void* filament_viewer_new_ios(void* texture, void* loadResource, void* freeResource, void* resources);
|
||||||
|
|
||||||
void create_swap_chain(void* viewer, void* texture);
|
void create_swap_chain(void* viewer, void* texture);
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
|
|
||||||
10
ios/include/SwiftPolyvoxFilamentPlugin-Bridging-Header.h
Normal file
10
ios/include/SwiftPolyvoxFilamentPlugin-Bridging-Header.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SwiftPolyvoxFilamentPlugin_Bridging_Header_h
|
||||||
|
#define SwiftPolyvoxFilamentPlugin_Bridging_Header_h
|
||||||
|
|
||||||
|
void* filament_viewer_new_ios(void* texture, void* loadResource, void* freeResource, void* resources);
|
||||||
|
|
||||||
|
#import "PolyvoxFilamentIOSApi.h"
|
||||||
|
#import "PolyvoxFilamentApi.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -13,39 +13,36 @@ A new flutter plugin project.
|
|||||||
s.license = { :file => '../LICENSE' }
|
s.license = { :file => '../LICENSE' }
|
||||||
s.author = { 'Your Company' => 'email@example.com' }
|
s.author = { 'Your Company' => 'email@example.com' }
|
||||||
s.source = { :path => '.' }
|
s.source = { :path => '.' }
|
||||||
s.source_files = 'Classes/**/*', 'src/ResourceBuffer.hpp', 'src/FilamentViewer.cpp', 'src/SceneAsset.cpp', 'src/SceneAssetLoader.cpp', 'src/StreamBufferAdapter.cpp', 'src/image/imagematerial.c', 'src/image/imagematerials_ios.c'
|
s.source_files = 'src/*', 'src/ios/*', 'src/shaders/*.c', 'src/shaders/*.h', 'include/filament/*', 'include/*', 'include/material/*.h', 'include/material/*.c'
|
||||||
#s.header_dir = "include"
|
s.public_header_files = 'include/SwiftPolyvoxFilamentPlugin-Bridging-Header.h', 'include/PolyvoxFilamentIOSApi.h', 'include/PolyvoxFilamentApi.h', 'include/ResourceBuffer.hpp' #, 'include/filament/*'
|
||||||
#s.header_mappings_dir = "include"
|
# s.header_mappings_dir = 'include'
|
||||||
s.dependency 'Flutter'
|
s.dependency 'Flutter'
|
||||||
s.platform = :ios, '12.1'
|
s.platform = :ios, '12.1'
|
||||||
s.static_framework = true
|
s.static_framework = true
|
||||||
s.vendored_libraries = "lib/*.a"
|
s.vendored_libraries = "lib/*.a"
|
||||||
|
|
||||||
s.library = "c++"
|
s.library = "c++"
|
||||||
|
|
||||||
s.user_target_xcconfig = {
|
s.user_target_xcconfig = {
|
||||||
'DEFINES_MODULE' => 'YES',
|
'DEFINES_MODULE' => 'YES',
|
||||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||||
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
||||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image "$(inherited)"',
|
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/shaders" "$(inherited)"',
|
||||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
||||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Flutter.framework does not contain a i386 slice.
|
|
||||||
s.pod_target_xcconfig = {
|
s.pod_target_xcconfig = {
|
||||||
'DEFINES_MODULE' => 'YES',
|
'DEFINES_MODULE' => 'YES',
|
||||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||||
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
||||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image "$(inherited)"',
|
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/shaders" "$(inherited)"',
|
||||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
||||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
||||||
}
|
}
|
||||||
|
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -69,7 +69,8 @@
|
|||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "SceneResources.hpp"
|
#include "SceneResources.hpp"
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
#include "image/imagematerials_ios.h"
|
#include "material/imagematerials_ios.h"
|
||||||
|
#include "material/unlitopaque.h"
|
||||||
#else
|
#else
|
||||||
#include "image/imagematerial.h"
|
#include "image/imagematerial.h"
|
||||||
#include "shaders/unlitopaque.h"
|
#include "shaders/unlitopaque.h"
|
||||||
@@ -98,7 +99,7 @@ namespace polyvox {
|
|||||||
public:
|
public:
|
||||||
UnlitMaterialProvider(Engine* engine) {
|
UnlitMaterialProvider(Engine* engine) {
|
||||||
_m = Material::Builder()
|
_m = Material::Builder()
|
||||||
.package(UNLITOPAQUE_UNLIT_OPAQUE_DATA, UNLITOPAQUE_UNLIT_OPAQUE_SIZE)
|
.package( UNLITOPAQUE_UNLIT_OPAQUE_DATA, UNLITOPAQUE_UNLIT_OPAQUE_SIZE)
|
||||||
.build(*engine);
|
.build(*engine);
|
||||||
_ms[0] = _m;
|
_ms[0] = _m;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2021 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
|
||||||
#include <filament/Texture.h>
|
|
||||||
|
|
||||||
#include <imageio/HDRDecoder.h>
|
|
||||||
|
|
||||||
#include <utils/Log.h>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "common/NioUtils.h"
|
|
||||||
|
|
||||||
using namespace filament;
|
|
||||||
using namespace image;
|
|
||||||
using namespace utils;
|
|
||||||
|
|
||||||
using PixelBufferDescriptor = Texture::PixelBufferDescriptor;
|
|
||||||
|
|
||||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
|
||||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat) {
|
|
||||||
slog.e << "Creating HDR texture." << io::endl;
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
|
||||||
Texture::InternalFormat textureFormat = (Texture::InternalFormat) internalFormat;
|
|
||||||
|
|
||||||
auto dataPtr = (char const*) buffer.getData();
|
|
||||||
const size_t byteCount = buffer.getSize();
|
|
||||||
|
|
||||||
// This creates a copy but it's the easest way to create a memory stream.
|
|
||||||
std::string ins(dataPtr, byteCount);
|
|
||||||
std::istringstream in(ins);
|
|
||||||
|
|
||||||
LinearImage* image = new LinearImage(ImageDecoder::decode(in, "memory.hdr"));
|
|
||||||
|
|
||||||
// This can happen if a decoding error occurs.
|
|
||||||
if (image->getChannels() != 3) {
|
|
||||||
delete image;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture* texture = Texture::Builder()
|
|
||||||
.width(image->getWidth())
|
|
||||||
.height(image->getHeight())
|
|
||||||
.levels(0xff)
|
|
||||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
|
||||||
.format(textureFormat)
|
|
||||||
.build(*engine);
|
|
||||||
|
|
||||||
if (texture == nullptr) {
|
|
||||||
slog.e << "Unable to create Filament Texture from HDR image." << io::endl;
|
|
||||||
delete image;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* userdata) {
|
|
||||||
delete (LinearImage*) userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
PixelBufferDescriptor pbd(
|
|
||||||
(void const* ) image->getPixelRef(),
|
|
||||||
image->getWidth() * image->getHeight() * 3 * sizeof(float),
|
|
||||||
PixelBufferDescriptor::PixelDataFormat::RGB,
|
|
||||||
PixelBufferDescriptor::PixelDataType::FLOAT,
|
|
||||||
freeCallback,
|
|
||||||
image);
|
|
||||||
|
|
||||||
// Note that the setImage call could fail (e.g. due to an invalid combination of internal format
|
|
||||||
// and PixelDataFormat) but there is no way of detecting such a failure.
|
|
||||||
texture->setImage(*engine, 0, std::move(pbd));
|
|
||||||
|
|
||||||
texture->generateMipmaps(*engine);
|
|
||||||
|
|
||||||
return (jlong) texture;
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
|
||||||
#include <filament/IndirectLight.h>
|
|
||||||
#include <filament/Skybox.h>
|
|
||||||
|
|
||||||
#include <image/KtxUtility.h>
|
|
||||||
|
|
||||||
#include <android/asset_manager.h>
|
|
||||||
#include <android/asset_manager_jni.h>
|
|
||||||
|
|
||||||
#include "common/NioUtils.h"
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
|
|
||||||
using namespace filament;
|
|
||||||
using namespace filament::math;
|
|
||||||
using namespace image;
|
|
||||||
|
|
||||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
|
||||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
|
|
||||||
|
|
||||||
static jlong nCreateKTXTexture(JNIEnv* env, jclass,
|
|
||||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
|
||||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
|
||||||
return (jlong) ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
|
||||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
|
||||||
delete bundle;
|
|
||||||
}, bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jlong nCreateIndirectLight(JNIEnv* env, jclass,
|
|
||||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
|
||||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
|
||||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
|
||||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
|
||||||
delete bundle;
|
|
||||||
}, bundle);
|
|
||||||
|
|
||||||
float3 harmonics[9];
|
|
||||||
bundle->getSphericalHarmonics(harmonics);
|
|
||||||
|
|
||||||
IndirectLight* indirectLight = IndirectLight::Builder()
|
|
||||||
.reflections(cubemap)
|
|
||||||
.irradiance(3, harmonics)
|
|
||||||
.intensity(30000)
|
|
||||||
.build(*engine);
|
|
||||||
|
|
||||||
return (jlong) indirectLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jlong nCreateSkybox(JNIEnv* env, jclass,
|
|
||||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb, jobject assetManager, jstring outpath) {
|
|
||||||
|
|
||||||
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
|
|
||||||
|
|
||||||
AAsset *asset = AAssetManager_open(mgr, "envs/default_env/default_env_skybox.ktx", AASSET_MODE_BUFFER);
|
|
||||||
if(asset == nullptr) {
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Couldn't open asset");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t length = AAsset_getLength(asset);
|
|
||||||
const void * buffer = AAsset_getBuffer(asset);
|
|
||||||
jboolean isCopy = (jboolean)false;
|
|
||||||
const char* out_cstr = env->GetStringUTFChars(outpath, &isCopy);
|
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Opening outfile %s for writing", out_cstr);
|
|
||||||
|
|
||||||
FILE* outfile = fopen(out_cstr, "w");
|
|
||||||
|
|
||||||
fwrite(buffer, 1, length, outfile);
|
|
||||||
|
|
||||||
fclose(outfile);
|
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Closed outfile %s", out_cstr);
|
|
||||||
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
// __android_log_print(ANDROID_LOG_VERBOSE, "UTILS", "CREATing autobuffer");
|
|
||||||
// AutoBuffer buffer(env, javaBuffer, remaining);
|
|
||||||
// __android_log_print(ANDROID_LOG_VERBOSE, "UTILS", "CREATied autobuffer");
|
|
||||||
|
|
||||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer, length);
|
|
||||||
// KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "UTILS", "CREATED BUNDLE FROM API");
|
|
||||||
|
|
||||||
|
|
||||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
|
||||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
|
||||||
delete bundle;
|
|
||||||
}, bundle);
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "UTILS", "CREATED TEXTURE");
|
|
||||||
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
|
|
||||||
jfloatArray outSphericalHarmonics_) {
|
|
||||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
|
||||||
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
|
||||||
|
|
||||||
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
|
|
||||||
const auto success = bundle.getSphericalHarmonics(
|
|
||||||
reinterpret_cast<filament::math::float3*>(outSphericalHarmonics)
|
|
||||||
);
|
|
||||||
env->ReleaseFloatArrayElements(outSphericalHarmonics_, outSphericalHarmonics, JNI_ABORT);
|
|
||||||
|
|
||||||
return success ? JNI_TRUE : JNI_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
|
||||||
JNIEnv* env;
|
|
||||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
// KTXLoader
|
|
||||||
jclass ktxloaderClass = env->FindClass("app/polyvox/filament/KTXLoader2");
|
|
||||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
|
||||||
static const JNINativeMethod ktxMethods[] = {
|
|
||||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
|
||||||
{(char*)"nCreateIndirectLight", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
|
|
||||||
{(char*)"nCreateSkybox", (char*)"(JLjava/nio/Buffer;IZLandroid/content/res/AssetManager;Ljava/lang/String;)J", reinterpret_cast<void*>(nCreateSkybox)},
|
|
||||||
{(char*)"nGetSphericalHarmonics", (char*)"(Ljava/nio/Buffer;I[F)Z", reinterpret_cast<void*>(nGetSphericalHarmonics)},
|
|
||||||
};
|
|
||||||
rc = env->RegisterNatives(ktxloaderClass, ktxMethods, sizeof(ktxMethods) / sizeof(JNINativeMethod));
|
|
||||||
if (rc != JNI_OK) return rc;
|
|
||||||
|
|
||||||
// HDRLoader
|
|
||||||
jclass hdrloaderClass = env->FindClass("com/google/android/filament/utils/HDRLoader");
|
|
||||||
if (hdrloaderClass == nullptr) return JNI_ERR;
|
|
||||||
static const JNINativeMethod hdrMethods[] = {
|
|
||||||
{(char*)"nCreateHDRTexture", (char*)"(JLjava/nio/Buffer;II)J", reinterpret_cast<void*>(nCreateHDRTexture)},
|
|
||||||
};
|
|
||||||
rc = env->RegisterNatives(hdrloaderClass, hdrMethods, sizeof(hdrMethods) / sizeof(JNINativeMethod));
|
|
||||||
if (rc != JNI_OK) return rc;
|
|
||||||
|
|
||||||
return JNI_VERSION_1_6;
|
|
||||||
}
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,54 +0,0 @@
|
|||||||
material {
|
|
||||||
name : Image,
|
|
||||||
parameters : [
|
|
||||||
{
|
|
||||||
type : sampler2d,
|
|
||||||
name : image
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : mat4,
|
|
||||||
name : transform,
|
|
||||||
precision : high
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : float3,
|
|
||||||
name : backgroundColor
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type : int,
|
|
||||||
name : showImage
|
|
||||||
}
|
|
||||||
],
|
|
||||||
variables : [
|
|
||||||
imageUV
|
|
||||||
],
|
|
||||||
vertexDomain : device,
|
|
||||||
depthWrite : false,
|
|
||||||
shadingModel : unlit,
|
|
||||||
variantFilter : [ skinning, shadowReceiver, vsm ],
|
|
||||||
culling: none
|
|
||||||
}
|
|
||||||
|
|
||||||
vertex {
|
|
||||||
void materialVertex(inout MaterialVertexInputs material) {
|
|
||||||
material.imageUV.st = getPosition().st * 0.5 + 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment {
|
|
||||||
void material(inout MaterialInputs material) {
|
|
||||||
prepareMaterial(material);
|
|
||||||
|
|
||||||
vec4 bg = vec4(materialParams.backgroundColor, 1.0);
|
|
||||||
highp vec2 uv = (materialParams.transform * vec4(saturate(variable_imageUV.st), 1.0, 1.0)).st;
|
|
||||||
if (materialParams.showImage == 0 || uv.s > 1.0 || uv.s < 0.0 || uv.t < 0.0 || uv.t > 1.0) {
|
|
||||||
material.baseColor = bg;
|
|
||||||
} else {
|
|
||||||
uv.t = 1.0 - uv.t;
|
|
||||||
vec4 color = max(texture(materialParams_image, uv.st), 0.0);
|
|
||||||
color.rgb *= color.a;
|
|
||||||
// Manual, pre-multiplied srcOver with opaque destination optimization
|
|
||||||
material.baseColor.rgb = color.rgb + bg.rgb * (1.0 - color.a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
353
ios/src/ios/SwiftPolyvoxFilamentPlugin.swift
Normal file
353
ios/src/ios/SwiftPolyvoxFilamentPlugin.swift
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
import Flutter
|
||||||
|
import UIKit
|
||||||
|
import OpenGLES.ES3
|
||||||
|
import GLKit
|
||||||
|
|
||||||
|
public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture {
|
||||||
|
|
||||||
|
var registrar : FlutterPluginRegistrar
|
||||||
|
var textureId: Int64?
|
||||||
|
var registry: FlutterTextureRegistry
|
||||||
|
|
||||||
|
var width: Double = 0
|
||||||
|
var height: Double = 0
|
||||||
|
|
||||||
|
var context: EAGLContext?;
|
||||||
|
var targetPixelBuffer: CVPixelBuffer?;
|
||||||
|
var textureCache: CVOpenGLESTextureCache?;
|
||||||
|
var texture: CVOpenGLESTexture? = nil;
|
||||||
|
var frameBuffer: GLuint = 0;
|
||||||
|
|
||||||
|
|
||||||
|
var pixelBufferAttrs = [
|
||||||
|
kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_32BGRA),
|
||||||
|
kCVPixelBufferOpenGLCompatibilityKey: kCFBooleanTrue,
|
||||||
|
kCVPixelBufferOpenGLESCompatibilityKey: kCFBooleanTrue,
|
||||||
|
kCVPixelBufferIOSurfacePropertiesKey: [:]
|
||||||
|
] as CFDictionary
|
||||||
|
|
||||||
|
var resources:NSMutableDictionary = [:]
|
||||||
|
var viewer:UnsafeMutableRawPointer? = nil
|
||||||
|
|
||||||
|
var displayLink:CADisplayLink? = nil
|
||||||
|
|
||||||
|
static var messenger : FlutterBinaryMessenger? = nil;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
||||||
|
|
||||||
|
let uriString = String(cString:uri.assumingMemoryBound(to: UInt8.self))
|
||||||
|
|
||||||
|
let key = instance.registrar.lookupKey(forAsset:uriString)
|
||||||
|
|
||||||
|
let path = Bundle.main.path(forResource: key, ofType:nil)
|
||||||
|
do {
|
||||||
|
let foo: String = path!
|
||||||
|
let data = try Data(contentsOf: URL(fileURLWithPath:foo))
|
||||||
|
let resId = instance.resources.count
|
||||||
|
let nsData = data as NSData
|
||||||
|
instance.resources[resId] = nsData
|
||||||
|
let rawPtr = nsData.bytes
|
||||||
|
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
|
||||||
|
} catch {
|
||||||
|
print("Error opening file: \(error)")
|
||||||
|
return ResourceBuffer()
|
||||||
|
}
|
||||||
|
return ResourceBuffer()
|
||||||
|
}
|
||||||
|
|
||||||
|
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
||||||
|
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
||||||
|
instance.resources.removeObject(forKey:rid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDisplayLink() {
|
||||||
|
displayLink = CADisplayLink(target: self,
|
||||||
|
selector: #selector(doRender))
|
||||||
|
displayLink!.add(to: .current, forMode: RunLoop.Mode.default)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func doRender() {
|
||||||
|
if(viewer != nil && _rendering) {
|
||||||
|
render(viewer, 0)
|
||||||
|
self.registry.textureFrameAvailable(self.textureId!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func copyPixelBuffer() -> Unmanaged<CVPixelBuffer>? {
|
||||||
|
if(targetPixelBuffer == nil) {
|
||||||
|
print("empty")
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return Unmanaged.passRetained(targetPixelBuffer!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
let _messenger = registrar.messenger();
|
||||||
|
messenger = _messenger;
|
||||||
|
let channel = FlutterMethodChannel(name: "app.polyvox.filament/event", binaryMessenger: _messenger)
|
||||||
|
let instance = SwiftPolyvoxFilamentPlugin(textureRegistry: registrar.textures(), registrar:registrar)
|
||||||
|
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(textureRegistry: FlutterTextureRegistry, registrar:FlutterPluginRegistrar) {
|
||||||
|
self.registry = textureRegistry;
|
||||||
|
self.registrar = registrar
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
print("Error allocating pixel buffer")
|
||||||
|
}
|
||||||
|
if(self.viewer != nil) {
|
||||||
|
create_swap_chain(self.viewer, unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self))
|
||||||
|
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Pixel buffer created")
|
||||||
|
}
|
||||||
|
|
||||||
|
private func initialize(width:Int32, height:Int32) {
|
||||||
|
|
||||||
|
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 = filament_viewer_new_ios(
|
||||||
|
unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self),
|
||||||
|
loadResourcePtr!,
|
||||||
|
freeResourcePtr!,
|
||||||
|
Unmanaged.passUnretained(self).toOpaque()
|
||||||
|
)
|
||||||
|
|
||||||
|
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
||||||
|
|
||||||
|
createDisplayLink()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
|
let methodName = call.method;
|
||||||
|
|
||||||
|
switch methodName {
|
||||||
|
case "initialize":
|
||||||
|
let args = call.arguments as! Array<Int32>
|
||||||
|
initialize(width:args[0], height:args[1])
|
||||||
|
result(self.textureId);
|
||||||
|
case "setBackgroundImage":
|
||||||
|
let uri = call.arguments as! String
|
||||||
|
set_background_image(self.viewer!, uri)
|
||||||
|
render(self.viewer!, 0)
|
||||||
|
self.registry.textureFrameAvailable(self.textureId!)
|
||||||
|
result("OK")
|
||||||
|
case "setBackgroundImagePosition":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
set_background_image_position(self.viewer, Float(args[0] as! Double), Float(args[1] as! Double), args[2] as! Bool)
|
||||||
|
result("OK");
|
||||||
|
case "resize":
|
||||||
|
let args = call.arguments as! Array<Double>
|
||||||
|
let width = Int(args[0])
|
||||||
|
let height = Int(args[1])
|
||||||
|
createPixelBuffer(width: width, height:height)
|
||||||
|
result("OK")
|
||||||
|
case "loadSkybox":
|
||||||
|
load_skybox(self.viewer!, call.arguments as! String)
|
||||||
|
result("OK");
|
||||||
|
case "removeSkybox":
|
||||||
|
remove_skybox(self.viewer!)
|
||||||
|
result("OK");
|
||||||
|
case "loadGlb":
|
||||||
|
let assetPtr = load_glb(self.viewer, call.arguments as! String)
|
||||||
|
result(unsafeBitCast(assetPtr, to:Int64.self));
|
||||||
|
case "loadGltf":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
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":
|
||||||
|
load_ibl(self.viewer, call.arguments as! String)
|
||||||
|
result("OK");
|
||||||
|
case "removeIbl":
|
||||||
|
remove_ibl(self.viewer)
|
||||||
|
result("OK");
|
||||||
|
case "setCamera":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
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<Any?>
|
||||||
|
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 "stopAnimation":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
let animationIndex = args[1] as! Int32
|
||||||
|
stop_animation(assetPtr, animationIndex) // TODO
|
||||||
|
result("OK");
|
||||||
|
case "getTargetNames":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
let meshName = args[1] as! String
|
||||||
|
let numNames = get_target_name_count(assetPtr, meshName)
|
||||||
|
var names = [String]()
|
||||||
|
for i in 0...numNames - 1{
|
||||||
|
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
||||||
|
get_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...numNames - 1{
|
||||||
|
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
||||||
|
get_animation_name(assetPtr, outPtr, i)
|
||||||
|
names.append(String(cString:outPtr))
|
||||||
|
}
|
||||||
|
result(names);
|
||||||
|
case "applyWeights":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
let weights = args[1] as! Array<Double>
|
||||||
|
weights.map { Float($0) }.withUnsafeBufferPointer {
|
||||||
|
apply_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(weights.count))
|
||||||
|
|
||||||
|
}
|
||||||
|
result("OK")
|
||||||
|
case "zoomBegin":
|
||||||
|
scroll_begin(self.viewer)
|
||||||
|
result("OK")
|
||||||
|
case "zoomUpdate":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
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")
|
||||||
|
case "animateWeights":
|
||||||
|
let args = call.arguments as! Array<Any?>
|
||||||
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
let frameData = args[1] as! Array<Double>
|
||||||
|
let numWeights = args[2] as! Int
|
||||||
|
let numFrames = args[3] as! Int
|
||||||
|
let frameLenInMs = args[4] as! Double
|
||||||
|
frameData.map { Float($0)}.withUnsafeBufferPointer {
|
||||||
|
animate_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(numWeights), Int32(numFrames), Float(frameLenInMs))
|
||||||
|
}
|
||||||
|
result("OK")
|
||||||
|
case "panStart":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
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<Any>
|
||||||
|
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 "rotateStart":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
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<Any>
|
||||||
|
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 "setPosition":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
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<Any>
|
||||||
|
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<Any>
|
||||||
|
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<Any>
|
||||||
|
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<Any>
|
||||||
|
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))
|
||||||
|
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 "setRendering":
|
||||||
|
_rendering = call.arguments as! Bool
|
||||||
|
result("OK")
|
||||||
|
case "render":
|
||||||
|
doRender()
|
||||||
|
result("OK")
|
||||||
|
case "addLight":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
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 "removeLight":
|
||||||
|
remove_light(self.viewer,call.arguments as! Int32)
|
||||||
|
result(true);
|
||||||
|
case "clearLights":
|
||||||
|
clear_lights(self.viewer);
|
||||||
|
result(true);
|
||||||
|
case "setTexture":
|
||||||
|
let args = call.arguments as! Array<Any>
|
||||||
|
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||||
|
load_texture(assetPtr, args[1] as! String, args[2] as! Int32)
|
||||||
|
result("OK");
|
||||||
|
default:
|
||||||
|
result(FlutterMethodNotImplemented)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user