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
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "LightManager.hpp"
|
||||
|
||||
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_end(void* viewer);
|
||||
|
||||
void grab_begin(void* viewer, int x, int y, bool pan);
|
||||
void grab_update(void* viewer, int x, int y);
|
||||
void grab_begin(void* viewer, float x, float y, bool pan);
|
||||
void grab_update(void* viewer, float x, float y);
|
||||
void grab_end(void* viewer);
|
||||
|
||||
|
||||
void apply_weights(void* asset, float* const weights, int count);
|
||||
|
||||
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 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_scale(void* asset, float scale);
|
||||
|
||||
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_focal_length(void* viewer, float focalLength);
|
||||
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 create_swap_chain(void* viewer, void* texture);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#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.author = { 'Your Company' => 'email@example.com' }
|
||||
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.header_dir = "include"
|
||||
#s.header_mappings_dir = "include"
|
||||
s.source_files = 'src/*', 'src/ios/*', 'src/shaders/*.c', 'src/shaders/*.h', 'include/filament/*', 'include/*', 'include/material/*.h', 'include/material/*.c'
|
||||
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.dependency 'Flutter'
|
||||
s.platform = :ios, '12.1'
|
||||
s.static_framework = true
|
||||
s.vendored_libraries = "lib/*.a"
|
||||
|
||||
s.library = "c++"
|
||||
|
||||
s.user_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'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',
|
||||
"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)"',
|
||||
}
|
||||
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'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',
|
||||
"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)"',
|
||||
}
|
||||
|
||||
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
#include "Log.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#if TARGET_OS_IPHONE
|
||||
#include "image/imagematerials_ios.h"
|
||||
#include "material/imagematerials_ios.h"
|
||||
#include "material/unlitopaque.h"
|
||||
#else
|
||||
#include "image/imagematerial.h"
|
||||
#include "shaders/unlitopaque.h"
|
||||
@@ -98,7 +99,7 @@ namespace polyvox {
|
||||
public:
|
||||
UnlitMaterialProvider(Engine* engine) {
|
||||
_m = Material::Builder()
|
||||
.package(UNLITOPAQUE_UNLIT_OPAQUE_DATA, UNLITOPAQUE_UNLIT_OPAQUE_SIZE)
|
||||
.package( UNLITOPAQUE_UNLIT_OPAQUE_DATA, UNLITOPAQUE_UNLIT_OPAQUE_SIZE)
|
||||
.build(*engine);
|
||||
_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