run all Android work on separate thread, add HotReloadPathHelper, separate loadTexture/setTexture
This commit is contained in:
@@ -7,44 +7,69 @@
|
||||
#include <android/log.h>
|
||||
#include <android/native_activity.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace polyvox;
|
||||
using namespace std;
|
||||
|
||||
static AAssetManager* am;
|
||||
static vector<AAsset*> _assets;
|
||||
uint64_t id = -1;
|
||||
static map<uint32_t, AAsset*> _apk_assets;
|
||||
static map<uint32_t, void*> _file_assets;
|
||||
static uint32_t _i = 0;
|
||||
|
||||
static ResourceBuffer loadResource(const char* name) {
|
||||
|
||||
id++;
|
||||
|
||||
AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
|
||||
if(asset == nullptr) {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Couldn't locate asset [ %s ]", name);
|
||||
return ResourceBuffer(nullptr, 0, 0);
|
||||
|
||||
string name_str(name);
|
||||
auto id = _i++;
|
||||
|
||||
if (name_str.rfind("file://", 0) == 0) {
|
||||
streampos length;
|
||||
ifstream is(name_str.substr(7), ios::binary);
|
||||
is.seekg (0, ios::end);
|
||||
length = is.tellg();
|
||||
char * buffer;
|
||||
buffer = new char [length];
|
||||
is.seekg (0, ios::beg);
|
||||
is.read (buffer, length);
|
||||
is.close();
|
||||
_file_assets[id] = buffer;
|
||||
return ResourceBuffer(buffer, length, id);
|
||||
} else {
|
||||
AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
|
||||
if(asset == nullptr) {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Couldn't locate asset [ %s ]", name);
|
||||
return ResourceBuffer(nullptr, 0, 0);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Loading asset [ %s ]", name);
|
||||
|
||||
off_t length = AAsset_getLength(asset);
|
||||
const void * buffer = AAsset_getBuffer(asset);
|
||||
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Read [ %lu ] bytes into buffer", length);
|
||||
|
||||
_apk_assets[id] = asset;
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Loaded asset [ %s ] of length %zu at index %d", name, length, id);
|
||||
return ResourceBuffer(buffer, length, id);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Loading asset [ %s ]", name);
|
||||
off_t length = AAsset_getLength(asset);
|
||||
const void * buffer = AAsset_getBuffer(asset);
|
||||
|
||||
uint8_t *buf = new uint8_t[length ];
|
||||
memcpy(buf,buffer, length);
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Read [ %lu ] bytes into buffer", length);
|
||||
_assets.push_back(asset);
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Loaded asset [ %s ] of length %zu", name, length);
|
||||
return ResourceBuffer(buf, length, id);
|
||||
|
||||
}
|
||||
|
||||
static void freeResource(uint32_t id) {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Freeing loaded resource at index [ %d ] ", id);
|
||||
AAsset* asset = _assets[id];
|
||||
if(asset) {
|
||||
AAsset_close(asset);
|
||||
auto apk_it = _apk_assets.find(id);
|
||||
if (apk_it != _apk_assets.end()) {
|
||||
AAsset_close(apk_it->second);
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Closed Android asset");
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Attempting to free resource at index [ %d ] that has already been released.", id);
|
||||
auto file_it = _file_assets.find(id);
|
||||
if (file_it != _file_assets.end()) {
|
||||
free(file_it->second);
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Freed asset from filesystem.");
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "FATAL - could not find Android or filesystem (hot reload) asset under id %d", id);
|
||||
}
|
||||
}
|
||||
_assets[id] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -78,7 +78,8 @@ interface FilamentInterop : Library {
|
||||
|
||||
fun set_background_image(viewer:Pointer, path:String);
|
||||
|
||||
fun set_texture(asset:Pointer, path:String, renderableIndex:Int);
|
||||
fun load_texture(asset:Pointer, path:String, renderableIndex:Int);
|
||||
fun set_texture(asset:Pointer);
|
||||
|
||||
fun transform_to_unit_cube(asset:Pointer);
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import java.io.*
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import android.util.Log
|
||||
|
||||
|
||||
class HotReloadPathHelper {
|
||||
companion object {
|
||||
fun getAssetPath(path: String, packageName: String): String? {
|
||||
// iterate over evr
|
||||
val shortName = packageName.split(".").last().split("_").last()
|
||||
val packagePath = "/data/user/0/${packageName}/code_cache/"
|
||||
Log.v("FFI", "Looking for shortName ${shortName} under package path ${packagePath}")
|
||||
val files = File(packagePath).listFiles().filter {
|
||||
it.path.split("/").last().startsWith(shortName)
|
||||
}.map {
|
||||
val f = File(it.path + "/${shortName}/build/${path}")
|
||||
Log.v("FFI", "Looking for ${f.path.toString()}")
|
||||
f
|
||||
}.filter {
|
||||
it.exists()
|
||||
}.sortedBy {
|
||||
Log.v("FFI", it.path.toString())
|
||||
it.lastModified()
|
||||
}
|
||||
Log.v("FFI", files.size.toString())
|
||||
if(files.size > 0)
|
||||
return files.first().path;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import androidx.annotation.NonNull
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
|
||||
import io.flutter.embedding.engine.FlutterJNI
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
@@ -12,6 +13,8 @@ import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
import io.flutter.embedding.engine.loader.FlutterApplicationInfo
|
||||
import io.flutter.embedding.engine.loader.ApplicationInfoLoader
|
||||
|
||||
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference
|
||||
|
||||
@@ -25,6 +28,7 @@ import android.content.pm.PackageManager
|
||||
import io.flutter.FlutterInjector
|
||||
|
||||
import android.os.CountDownTimer
|
||||
import android.os.Handler
|
||||
|
||||
import android.opengl.GLU
|
||||
import javax.microedition.khronos.egl.EGLConfig
|
||||
@@ -74,6 +78,10 @@ import android.view.Surface.CHANGE_FRAME_RATE_ALWAYS
|
||||
import android.view.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT
|
||||
import android.view.SurfaceHolder
|
||||
|
||||
import java.util.Timer
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
|
||||
/** PolyvoxFilamentPlugin */
|
||||
class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
@@ -84,7 +92,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
private val startTime = System.nanoTime()
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
choreographer.postFrameCallback(this)
|
||||
synchronized(lock) {
|
||||
executor.execute {
|
||||
if(_viewer != null) {
|
||||
if(!surface.isValid()) {
|
||||
Log.v(TAG, "INVALID")
|
||||
@@ -126,6 +134,8 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
|
||||
private lateinit var activity:Activity
|
||||
|
||||
private val executor = Executors.newFixedThreadPool(1);
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
this.flutterPluginBinding = flutterPluginBinding
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME)
|
||||
@@ -137,144 +147,162 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
lifecycle = (binding.lifecycle as? HiddenLifecycleReference)?.lifecycle
|
||||
activity = binding.activity
|
||||
choreographer = Choreographer.getInstance()
|
||||
choreographer.postFrameCallback(frameCallback)
|
||||
activity.window.setFormat(PixelFormat.RGBA_8888)
|
||||
|
||||
}
|
||||
|
||||
fun getAssetPath(path:String) : String {
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val key = loader.getLookupKeyForAsset(path)
|
||||
val hotReloadPath = HotReloadPathHelper.getAssetPath(key, activity.getPackageName())
|
||||
if(hotReloadPath != null) {
|
||||
return "file://" + hotReloadPath;
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
"initialize" -> {
|
||||
if(_viewer != null) {
|
||||
synchronized(lock) {
|
||||
print("Deleting existing viewer")
|
||||
_lib.filament_viewer_delete(_viewer!!);
|
||||
_viewer = null;
|
||||
}
|
||||
}
|
||||
if(surfaceTexture != null) {
|
||||
print("Releasing existing texture")
|
||||
surfaceTexture!!.release()
|
||||
surfaceTexture = null;
|
||||
}
|
||||
val args = call.arguments as ArrayList<Int>
|
||||
val width = args[0]
|
||||
val height = args[1]
|
||||
|
||||
print("Initializing")
|
||||
|
||||
val entry = flutterPluginBinding.textureRegistry.createSurfaceTexture();
|
||||
executor.execute {
|
||||
if(_viewer != null) {
|
||||
synchronized(lock) {
|
||||
print("Deleting existing viewer")
|
||||
_lib.filament_viewer_delete(_viewer!!);
|
||||
print("Deleted viewer")
|
||||
_viewer = null;
|
||||
}
|
||||
}
|
||||
if(surfaceTexture != null) {
|
||||
print("Releasing existing texture")
|
||||
surfaceTexture!!.release()
|
||||
surfaceTexture = null;
|
||||
}
|
||||
val args = call.arguments as ArrayList<Int>
|
||||
val width = args[0]
|
||||
val height = args[1]
|
||||
|
||||
|
||||
surfaceTexture = entry.surfaceTexture()
|
||||
|
||||
surfaceTexture!!.setDefaultBufferSize(width, height)
|
||||
|
||||
surface = Surface(surfaceTexture!!)
|
||||
|
||||
_viewer = _lib.filament_viewer_new_android(
|
||||
surface as Object,
|
||||
JNIEnv.CURRENT,
|
||||
(activity as Context).assets)
|
||||
|
||||
|
||||
|
||||
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
||||
|
||||
result.success(entry.id().toInt())
|
||||
|
||||
choreographer = Choreographer.getInstance()
|
||||
|
||||
surfaceTexture = entry.surfaceTexture()
|
||||
|
||||
surfaceTexture!!.setDefaultBufferSize(width, height)
|
||||
|
||||
surface = Surface(surfaceTexture!!)
|
||||
|
||||
_viewer = _lib.filament_viewer_new_android(
|
||||
surface as Object,
|
||||
JNIEnv.CURRENT,
|
||||
(activity as Context).assets)
|
||||
|
||||
choreographer.postFrameCallback(frameCallback)
|
||||
|
||||
activity.window.setFormat(PixelFormat.RGBA_8888)
|
||||
|
||||
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
||||
|
||||
result.success(entry.id().toInt())
|
||||
}
|
||||
}
|
||||
"resize" -> {
|
||||
val args = call.arguments as ArrayList<Int>
|
||||
val width = args[0]
|
||||
val height = args[1]
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Int>
|
||||
val width = args[0]
|
||||
val height = args[1]
|
||||
|
||||
surfaceTexture!!.setDefaultBufferSize(width, height)
|
||||
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
||||
result.success(null)
|
||||
}
|
||||
"reloadAssets" -> {
|
||||
// context = context.createPackageContext(context.getPackageName(), 0)
|
||||
// val assetManager = context.getAssets()
|
||||
// val flutterJNI = FlutterJNI.Factory.provideFlutterJNI()
|
||||
// flutterJNI.updateJavaAssetManager(assetManager, flutterApplicationInfo.flutterAssetsDir)
|
||||
surfaceTexture!!.setDefaultBufferSize(width, height)
|
||||
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
||||
result.success(null)
|
||||
}
|
||||
}
|
||||
"setBackgroundImage" -> {
|
||||
val args = call.arguments as String
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
_lib.set_background_image(_viewer!!, loader.getLookupKeyForAsset(args))
|
||||
_lib.render(_viewer!!)
|
||||
executor.execute {
|
||||
_lib.set_background_image(_viewer!!, getAssetPath(call.arguments as String))
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"loadSkybox" -> {
|
||||
val args = call.arguments as String
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
_lib.load_skybox(_viewer!!, loader.getLookupKeyForAsset(args))
|
||||
executor.execute {
|
||||
_lib.load_skybox(_viewer!!, getAssetPath(call.arguments as String))
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"loadIbl" -> {
|
||||
val args = call.arguments as String
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
|
||||
_lib.load_ibl(_viewer!!, loader.getLookupKeyForAsset(args))
|
||||
executor.execute {
|
||||
_lib.load_ibl(_viewer!!, getAssetPath(call.arguments as String))
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"removeIbl" -> {
|
||||
_lib.remove_ibl(_viewer!!)
|
||||
result.success(true);
|
||||
executor.execute {
|
||||
_lib.remove_ibl(_viewer!!)
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
"removeSkybox" -> {
|
||||
_lib.remove_skybox(_viewer!!)
|
||||
result.success(true);
|
||||
executor.execute {
|
||||
_lib.remove_skybox(_viewer!!)
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
"loadGlb" -> {
|
||||
if (_viewer == null)
|
||||
return;
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val key = loader.getLookupKeyForAsset(call.arguments as String)
|
||||
val key2 = loader.getLookupKeyForAsset(call.arguments as String, (activity as Context).packageName)
|
||||
val path = loader.findAppBundlePath()
|
||||
|
||||
executor.execute {
|
||||
val assetPtr = _lib.load_glb(
|
||||
_viewer!!,
|
||||
key
|
||||
getAssetPath(call.arguments as String)
|
||||
)
|
||||
result.success(Pointer.nativeValue(assetPtr));
|
||||
}
|
||||
}
|
||||
"loadGltf" -> {
|
||||
if (_viewer == null)
|
||||
return;
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val assetPtr = _lib.load_gltf(
|
||||
_viewer!!,
|
||||
loader.getLookupKeyForAsset(args[0] as String),
|
||||
loader.getLookupKeyForAsset(args[1] as String)
|
||||
getAssetPath(args[0] as String),
|
||||
getAssetPath(args[1] as String)
|
||||
)
|
||||
result.success(Pointer.nativeValue(assetPtr));
|
||||
}
|
||||
}
|
||||
"transformToUnitCube" -> {
|
||||
val assetPtr = Pointer(call.arguments as Long);
|
||||
_lib.transform_to_unit_cube(assetPtr)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val assetPtr = Pointer(call.arguments as Long);
|
||||
_lib.transform_to_unit_cube(assetPtr)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"setPosition" -> {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
_lib.set_position(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat())
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
_lib.set_position(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat())
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"setRotation" -> {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
_lib.set_rotation(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat(), (args[4] as Double).toFloat())
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
_lib.set_rotation(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat(), (args[4] as Double).toFloat())
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"setTexture" -> {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val assetPtr = Pointer(args[0] as Long);
|
||||
_lib.set_texture(assetPtr, loader.getLookupKeyForAsset(args[1] as String), args[2] as Int)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long);
|
||||
_lib.load_texture(assetPtr, getAssetPath(args[1] as String), args[2] as Int)
|
||||
print("Texture loaded")
|
||||
result.success("OK");
|
||||
}
|
||||
|
||||
}
|
||||
"setCamera" -> {
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val success = _lib.set_camera(
|
||||
_viewer!!,
|
||||
@@ -286,110 +314,143 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
} else {
|
||||
result.error("failed","failed", "Failed to set camera")
|
||||
}
|
||||
}
|
||||
}
|
||||
"zoom" -> {
|
||||
if(_viewer == null)
|
||||
return;
|
||||
_lib.scroll(_viewer!!, 0.0f, 0.0f, (call.arguments as Double).toFloat())
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.scroll(_viewer!!, 0.0f, 0.0f, (call.arguments as Double).toFloat())
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"getTargetNames" -> {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val meshName = args[1] as String
|
||||
val names = mutableListOf<String>()
|
||||
val outPtr = Memory(256)
|
||||
for(i in 0.._lib.get_target_name_count(assetPtr, meshName) - 1) {
|
||||
_lib.get_target_name(assetPtr, meshName, outPtr, i)
|
||||
val name = outPtr.getString(0)
|
||||
names.add(name)
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val meshName = args[1] as String
|
||||
val names = mutableListOf<String>()
|
||||
val outPtr = Memory(256)
|
||||
for(i in 0.._lib.get_target_name_count(assetPtr, meshName) - 1) {
|
||||
_lib.get_target_name(assetPtr, meshName, outPtr, i)
|
||||
val name = outPtr.getString(0)
|
||||
names.add(name)
|
||||
}
|
||||
result.success(names)
|
||||
}
|
||||
result.success(names)
|
||||
}
|
||||
"getAnimationNames" -> {
|
||||
val assetPtr = Pointer(call.arguments as Long)
|
||||
val names = mutableListOf<String>()
|
||||
val outPtr = Memory(256)
|
||||
for(i in 0.._lib.get_animation_count(assetPtr) - 1) {
|
||||
_lib.get_animation_name(assetPtr, outPtr, i)
|
||||
val name = outPtr.getString(0)
|
||||
names.add(name)
|
||||
executor.execute {
|
||||
val assetPtr = Pointer(call.arguments as Long)
|
||||
val names = mutableListOf<String>()
|
||||
val outPtr = Memory(256)
|
||||
for(i in 0.._lib.get_animation_count(assetPtr) - 1) {
|
||||
_lib.get_animation_name(assetPtr, outPtr, i)
|
||||
val name = outPtr.getString(0)
|
||||
names.add(name)
|
||||
}
|
||||
result.success(names)
|
||||
}
|
||||
result.success(names)
|
||||
}
|
||||
"applyWeights" -> {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val weights = args[1] as ArrayList<Float>;
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<*>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val weights = args[1] as ArrayList<Float>;
|
||||
|
||||
_lib.apply_weights(assetPtr, weights.toFloatArray(), weights.size)
|
||||
result.success("OK");
|
||||
_lib.apply_weights(assetPtr, weights.toFloatArray(), weights.size)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"animateWeights" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val frames = args[1] as ArrayList<Float>;
|
||||
val numWeights = args[2] as Int
|
||||
val numFrames = args[3] as Int
|
||||
val frameLenInMs = args[4] as Double
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
val assetPtr = Pointer(args[0] as Long)
|
||||
val frames = args[1] as ArrayList<Float>;
|
||||
val numWeights = args[2] as Int
|
||||
val numFrames = args[3] as Int
|
||||
val frameLenInMs = args[4] as Double
|
||||
|
||||
_lib.animate_weights(assetPtr, frames.toFloatArray(), numWeights, numFrames, frameLenInMs.toFloat())
|
||||
result.success("OK");
|
||||
_lib.animate_weights(assetPtr, frames.toFloatArray(), numWeights, numFrames, frameLenInMs.toFloat())
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"panStart" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"panUpdate" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"panEnd" -> {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"rotateStart" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, false)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, false)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"rotateUpdate" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"rotateEnd" -> {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"grabStart" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"grabUpdate" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"grabEnd" -> {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.grab_end(_viewer!!)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"removeAsset" -> {
|
||||
_lib.remove_asset(_viewer!!, Pointer(call.arguments as Long))
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.remove_asset(_viewer!!, Pointer(call.arguments as Long))
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"clearAssets" -> {
|
||||
_lib.clear_assets(_viewer!!)
|
||||
result.success("OK");
|
||||
executor.execute {
|
||||
_lib.clear_assets(_viewer!!)
|
||||
result.success("OK");
|
||||
}
|
||||
}
|
||||
"playAnimation" -> {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean)
|
||||
result.success("OK")
|
||||
executor.execute {
|
||||
val args = call.arguments as ArrayList<Any?>
|
||||
_lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean)
|
||||
result.success("OK")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
result.notImplemented()
|
||||
|
||||
Reference in New Issue
Block a user