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/log.h>
|
||||||
#include <android/native_activity.h>
|
#include <android/native_activity.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
using namespace polyvox;
|
using namespace polyvox;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static AAssetManager* am;
|
static AAssetManager* am;
|
||||||
static vector<AAsset*> _assets;
|
static map<uint32_t, AAsset*> _apk_assets;
|
||||||
uint64_t id = -1;
|
static map<uint32_t, void*> _file_assets;
|
||||||
|
static uint32_t _i = 0;
|
||||||
|
|
||||||
static ResourceBuffer loadResource(const char* name) {
|
static ResourceBuffer loadResource(const char* name) {
|
||||||
|
|
||||||
id++;
|
|
||||||
|
string name_str(name);
|
||||||
AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
|
auto id = _i++;
|
||||||
if(asset == nullptr) {
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Couldn't locate asset [ %s ]", name);
|
if (name_str.rfind("file://", 0) == 0) {
|
||||||
return ResourceBuffer(nullptr, 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) {
|
static void freeResource(uint32_t id) {
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Freeing loaded resource at index [ %d ] ", id);
|
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Freeing loaded resource at index [ %d ] ", id);
|
||||||
AAsset* asset = _assets[id];
|
auto apk_it = _apk_assets.find(id);
|
||||||
if(asset) {
|
if (apk_it != _apk_assets.end()) {
|
||||||
AAsset_close(asset);
|
AAsset_close(apk_it->second);
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Closed Android asset");
|
||||||
} else {
|
} 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" {
|
extern "C" {
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ interface FilamentInterop : Library {
|
|||||||
|
|
||||||
fun set_background_image(viewer:Pointer, path:String);
|
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);
|
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 androidx.lifecycle.Lifecycle
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.FlutterJNI
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
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
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||||
import io.flutter.plugin.common.MethodChannel.Result
|
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
|
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference
|
||||||
|
|
||||||
@@ -25,6 +28,7 @@ import android.content.pm.PackageManager
|
|||||||
import io.flutter.FlutterInjector
|
import io.flutter.FlutterInjector
|
||||||
|
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
|
import android.os.Handler
|
||||||
|
|
||||||
import android.opengl.GLU
|
import android.opengl.GLU
|
||||||
import javax.microedition.khronos.egl.EGLConfig
|
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.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT
|
||||||
import android.view.SurfaceHolder
|
import android.view.SurfaceHolder
|
||||||
|
|
||||||
|
import java.util.Timer
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
|
||||||
/** PolyvoxFilamentPlugin */
|
/** PolyvoxFilamentPlugin */
|
||||||
class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||||
@@ -84,7 +92,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
|||||||
private val startTime = System.nanoTime()
|
private val startTime = System.nanoTime()
|
||||||
override fun doFrame(frameTimeNanos: Long) {
|
override fun doFrame(frameTimeNanos: Long) {
|
||||||
choreographer.postFrameCallback(this)
|
choreographer.postFrameCallback(this)
|
||||||
synchronized(lock) {
|
executor.execute {
|
||||||
if(_viewer != null) {
|
if(_viewer != null) {
|
||||||
if(!surface.isValid()) {
|
if(!surface.isValid()) {
|
||||||
Log.v(TAG, "INVALID")
|
Log.v(TAG, "INVALID")
|
||||||
@@ -126,6 +134,8 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
|||||||
|
|
||||||
private lateinit var activity:Activity
|
private lateinit var activity:Activity
|
||||||
|
|
||||||
|
private val executor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
this.flutterPluginBinding = flutterPluginBinding
|
this.flutterPluginBinding = flutterPluginBinding
|
||||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME)
|
channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME)
|
||||||
@@ -137,144 +147,162 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
|||||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||||
lifecycle = (binding.lifecycle as? HiddenLifecycleReference)?.lifecycle
|
lifecycle = (binding.lifecycle as? HiddenLifecycleReference)?.lifecycle
|
||||||
activity = binding.activity
|
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) {
|
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||||
when (call.method) {
|
when (call.method) {
|
||||||
"initialize" -> {
|
"initialize" -> {
|
||||||
if(_viewer != null) {
|
print("Initializing")
|
||||||
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]
|
|
||||||
|
|
||||||
val entry = flutterPluginBinding.textureRegistry.createSurfaceTexture();
|
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" -> {
|
"resize" -> {
|
||||||
val args = call.arguments as ArrayList<Int>
|
executor.execute {
|
||||||
val width = args[0]
|
val args = call.arguments as ArrayList<Int>
|
||||||
val height = args[1]
|
val width = args[0]
|
||||||
|
val height = args[1]
|
||||||
|
|
||||||
surfaceTexture!!.setDefaultBufferSize(width, height)
|
surfaceTexture!!.setDefaultBufferSize(width, height)
|
||||||
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
_lib.update_viewport_and_camera_projection(_viewer!!, width, height, 1.0f);
|
||||||
result.success(null)
|
result.success(null)
|
||||||
}
|
|
||||||
"reloadAssets" -> {
|
|
||||||
// context = context.createPackageContext(context.getPackageName(), 0)
|
|
||||||
// val assetManager = context.getAssets()
|
|
||||||
// val flutterJNI = FlutterJNI.Factory.provideFlutterJNI()
|
|
||||||
// flutterJNI.updateJavaAssetManager(assetManager, flutterApplicationInfo.flutterAssetsDir)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"setBackgroundImage" -> {
|
"setBackgroundImage" -> {
|
||||||
val args = call.arguments as String
|
executor.execute {
|
||||||
val loader = FlutterInjector.instance().flutterLoader()
|
_lib.set_background_image(_viewer!!, getAssetPath(call.arguments as String))
|
||||||
_lib.set_background_image(_viewer!!, loader.getLookupKeyForAsset(args))
|
|
||||||
_lib.render(_viewer!!)
|
|
||||||
result.success("OK");
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"loadSkybox" -> {
|
"loadSkybox" -> {
|
||||||
val args = call.arguments as String
|
executor.execute {
|
||||||
val loader = FlutterInjector.instance().flutterLoader()
|
_lib.load_skybox(_viewer!!, getAssetPath(call.arguments as String))
|
||||||
_lib.load_skybox(_viewer!!, loader.getLookupKeyForAsset(args))
|
|
||||||
result.success("OK");
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"loadIbl" -> {
|
"loadIbl" -> {
|
||||||
val args = call.arguments as String
|
executor.execute {
|
||||||
val loader = FlutterInjector.instance().flutterLoader()
|
_lib.load_ibl(_viewer!!, getAssetPath(call.arguments as String))
|
||||||
|
|
||||||
_lib.load_ibl(_viewer!!, loader.getLookupKeyForAsset(args))
|
|
||||||
result.success("OK");
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"removeIbl" -> {
|
"removeIbl" -> {
|
||||||
_lib.remove_ibl(_viewer!!)
|
executor.execute {
|
||||||
result.success(true);
|
_lib.remove_ibl(_viewer!!)
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"removeSkybox" -> {
|
"removeSkybox" -> {
|
||||||
_lib.remove_skybox(_viewer!!)
|
executor.execute {
|
||||||
result.success(true);
|
_lib.remove_skybox(_viewer!!)
|
||||||
|
result.success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"loadGlb" -> {
|
"loadGlb" -> {
|
||||||
if (_viewer == null)
|
executor.execute {
|
||||||
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()
|
|
||||||
|
|
||||||
val assetPtr = _lib.load_glb(
|
val assetPtr = _lib.load_glb(
|
||||||
_viewer!!,
|
_viewer!!,
|
||||||
key
|
getAssetPath(call.arguments as String)
|
||||||
)
|
)
|
||||||
result.success(Pointer.nativeValue(assetPtr));
|
result.success(Pointer.nativeValue(assetPtr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"loadGltf" -> {
|
"loadGltf" -> {
|
||||||
if (_viewer == null)
|
executor.execute {
|
||||||
return;
|
|
||||||
val args = call.arguments as ArrayList<Any?>
|
val args = call.arguments as ArrayList<Any?>
|
||||||
val loader = FlutterInjector.instance().flutterLoader()
|
|
||||||
val assetPtr = _lib.load_gltf(
|
val assetPtr = _lib.load_gltf(
|
||||||
_viewer!!,
|
_viewer!!,
|
||||||
loader.getLookupKeyForAsset(args[0] as String),
|
getAssetPath(args[0] as String),
|
||||||
loader.getLookupKeyForAsset(args[1] as String)
|
getAssetPath(args[1] as String)
|
||||||
)
|
)
|
||||||
result.success(Pointer.nativeValue(assetPtr));
|
result.success(Pointer.nativeValue(assetPtr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"transformToUnitCube" -> {
|
"transformToUnitCube" -> {
|
||||||
val assetPtr = Pointer(call.arguments as Long);
|
executor.execute {
|
||||||
_lib.transform_to_unit_cube(assetPtr)
|
val assetPtr = Pointer(call.arguments as Long);
|
||||||
result.success("OK");
|
_lib.transform_to_unit_cube(assetPtr)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"setPosition" -> {
|
"setPosition" -> {
|
||||||
val args = call.arguments as ArrayList<*>
|
executor.execute {
|
||||||
val assetPtr = Pointer(args[0] as Long)
|
val args = call.arguments as ArrayList<*>
|
||||||
_lib.set_position(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat())
|
val assetPtr = Pointer(args[0] as Long)
|
||||||
result.success("OK");
|
_lib.set_position(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat())
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"setRotation" -> {
|
"setRotation" -> {
|
||||||
val args = call.arguments as ArrayList<*>
|
executor.execute {
|
||||||
val assetPtr = Pointer(args[0] as Long)
|
val args = call.arguments as ArrayList<*>
|
||||||
_lib.set_rotation(assetPtr, (args[1] as Double).toFloat(), (args[2] as Double).toFloat(), (args[3] as Double).toFloat(), (args[4] as Double).toFloat())
|
val assetPtr = Pointer(args[0] as Long)
|
||||||
result.success("OK");
|
_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" -> {
|
"setTexture" -> {
|
||||||
val args = call.arguments as ArrayList<*>
|
executor.execute {
|
||||||
val loader = FlutterInjector.instance().flutterLoader()
|
val args = call.arguments as ArrayList<*>
|
||||||
val assetPtr = Pointer(args[0] as Long);
|
val assetPtr = Pointer(args[0] as Long);
|
||||||
_lib.set_texture(assetPtr, loader.getLookupKeyForAsset(args[1] as String), args[2] as Int)
|
_lib.load_texture(assetPtr, getAssetPath(args[1] as String), args[2] as Int)
|
||||||
result.success("OK");
|
print("Texture loaded")
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
"setCamera" -> {
|
"setCamera" -> {
|
||||||
|
executor.execute {
|
||||||
val args = call.arguments as ArrayList<*>
|
val args = call.arguments as ArrayList<*>
|
||||||
val success = _lib.set_camera(
|
val success = _lib.set_camera(
|
||||||
_viewer!!,
|
_viewer!!,
|
||||||
@@ -286,110 +314,143 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
|
|||||||
} else {
|
} else {
|
||||||
result.error("failed","failed", "Failed to set camera")
|
result.error("failed","failed", "Failed to set camera")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"zoom" -> {
|
"zoom" -> {
|
||||||
if(_viewer == null)
|
executor.execute {
|
||||||
return;
|
_lib.scroll(_viewer!!, 0.0f, 0.0f, (call.arguments as Double).toFloat())
|
||||||
_lib.scroll(_viewer!!, 0.0f, 0.0f, (call.arguments as Double).toFloat())
|
result.success("OK");
|
||||||
result.success("OK");
|
}
|
||||||
}
|
}
|
||||||
"getTargetNames" -> {
|
"getTargetNames" -> {
|
||||||
val args = call.arguments as ArrayList<*>
|
executor.execute {
|
||||||
val assetPtr = Pointer(args[0] as Long)
|
val args = call.arguments as ArrayList<*>
|
||||||
val meshName = args[1] as String
|
val assetPtr = Pointer(args[0] as Long)
|
||||||
val names = mutableListOf<String>()
|
val meshName = args[1] as String
|
||||||
val outPtr = Memory(256)
|
val names = mutableListOf<String>()
|
||||||
for(i in 0.._lib.get_target_name_count(assetPtr, meshName) - 1) {
|
val outPtr = Memory(256)
|
||||||
_lib.get_target_name(assetPtr, meshName, outPtr, i)
|
for(i in 0.._lib.get_target_name_count(assetPtr, meshName) - 1) {
|
||||||
val name = outPtr.getString(0)
|
_lib.get_target_name(assetPtr, meshName, outPtr, i)
|
||||||
names.add(name)
|
val name = outPtr.getString(0)
|
||||||
|
names.add(name)
|
||||||
|
}
|
||||||
|
result.success(names)
|
||||||
}
|
}
|
||||||
result.success(names)
|
|
||||||
}
|
}
|
||||||
"getAnimationNames" -> {
|
"getAnimationNames" -> {
|
||||||
val assetPtr = Pointer(call.arguments as Long)
|
executor.execute {
|
||||||
val names = mutableListOf<String>()
|
val assetPtr = Pointer(call.arguments as Long)
|
||||||
val outPtr = Memory(256)
|
val names = mutableListOf<String>()
|
||||||
for(i in 0.._lib.get_animation_count(assetPtr) - 1) {
|
val outPtr = Memory(256)
|
||||||
_lib.get_animation_name(assetPtr, outPtr, i)
|
for(i in 0.._lib.get_animation_count(assetPtr) - 1) {
|
||||||
val name = outPtr.getString(0)
|
_lib.get_animation_name(assetPtr, outPtr, i)
|
||||||
names.add(name)
|
val name = outPtr.getString(0)
|
||||||
|
names.add(name)
|
||||||
|
}
|
||||||
|
result.success(names)
|
||||||
}
|
}
|
||||||
result.success(names)
|
|
||||||
}
|
}
|
||||||
"applyWeights" -> {
|
"applyWeights" -> {
|
||||||
val args = call.arguments as ArrayList<*>
|
executor.execute {
|
||||||
val assetPtr = Pointer(args[0] as Long)
|
val args = call.arguments as ArrayList<*>
|
||||||
val weights = args[1] as ArrayList<Float>;
|
val assetPtr = Pointer(args[0] as Long)
|
||||||
|
val weights = args[1] as ArrayList<Float>;
|
||||||
|
|
||||||
_lib.apply_weights(assetPtr, weights.toFloatArray(), weights.size)
|
_lib.apply_weights(assetPtr, weights.toFloatArray(), weights.size)
|
||||||
result.success("OK");
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"animateWeights" -> {
|
"animateWeights" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
val assetPtr = Pointer(args[0] as Long)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
val frames = args[1] as ArrayList<Float>;
|
val assetPtr = Pointer(args[0] as Long)
|
||||||
val numWeights = args[2] as Int
|
val frames = args[1] as ArrayList<Float>;
|
||||||
val numFrames = args[3] as Int
|
val numWeights = args[2] as Int
|
||||||
val frameLenInMs = args[4] as Double
|
val numFrames = args[3] as Int
|
||||||
|
val frameLenInMs = args[4] as Double
|
||||||
|
|
||||||
_lib.animate_weights(assetPtr, frames.toFloatArray(), numWeights, numFrames, frameLenInMs.toFloat())
|
_lib.animate_weights(assetPtr, frames.toFloatArray(), numWeights, numFrames, frameLenInMs.toFloat())
|
||||||
result.success("OK");
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"panStart" -> {
|
"panStart" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"panUpdate" -> {
|
"panUpdate" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"panEnd" -> {
|
"panEnd" -> {
|
||||||
_lib.grab_end(_viewer!!)
|
executor.execute {
|
||||||
result.success("OK");
|
_lib.grab_end(_viewer!!)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"rotateStart" -> {
|
"rotateStart" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, false)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, false)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"rotateUpdate" -> {
|
"rotateUpdate" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"rotateEnd" -> {
|
"rotateEnd" -> {
|
||||||
_lib.grab_end(_viewer!!)
|
executor.execute {
|
||||||
result.success("OK");
|
_lib.grab_end(_viewer!!)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"grabStart" -> {
|
"grabStart" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_begin(_viewer!!, args[0] as Int, args[1] as Int, true)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"grabUpdate" -> {
|
"grabUpdate" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK");
|
_lib.grab_update(_viewer!!, args[0] as Int, args[1] as Int)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"grabEnd" -> {
|
"grabEnd" -> {
|
||||||
_lib.grab_end(_viewer!!)
|
executor.execute {
|
||||||
result.success("OK");
|
_lib.grab_end(_viewer!!)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"removeAsset" -> {
|
"removeAsset" -> {
|
||||||
_lib.remove_asset(_viewer!!, Pointer(call.arguments as Long))
|
executor.execute {
|
||||||
result.success("OK");
|
_lib.remove_asset(_viewer!!, Pointer(call.arguments as Long))
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"clearAssets" -> {
|
"clearAssets" -> {
|
||||||
_lib.clear_assets(_viewer!!)
|
executor.execute {
|
||||||
result.success("OK");
|
_lib.clear_assets(_viewer!!)
|
||||||
|
result.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"playAnimation" -> {
|
"playAnimation" -> {
|
||||||
val args = call.arguments as ArrayList<Any?>
|
executor.execute {
|
||||||
_lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean)
|
val args = call.arguments as ArrayList<Any?>
|
||||||
result.success("OK")
|
_lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean)
|
||||||
|
result.success("OK")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
result.notImplemented()
|
result.notImplemented()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:polyvox_filament/filament_controller.dart';
|
import 'package:polyvox_filament/filament_controller.dart';
|
||||||
import 'package:polyvox_filament/filament_widget.dart';
|
import 'package:polyvox_filament/filament_widget.dart';
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
@@ -223,6 +224,9 @@ class _MyAppState extends State<MyApp> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
_vertical = !_vertical;
|
_vertical = !_vertical;
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
await _filamentController.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (BuildContext context) =>
|
itemBuilder: (BuildContext context) =>
|
||||||
@@ -302,6 +306,9 @@ class _MyAppState extends State<MyApp> {
|
|||||||
value: 19, child: Text('pan right')),
|
value: 19, child: Text('pan right')),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
value: 25, child: Text(_vertical ? 'set horizontal' : 'set vertical')),
|
value: 25, child: Text(_vertical ? 'set horizontal' : 'set vertical')),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: 26, child: Text(
|
||||||
|
"reload native assets")),
|
||||||
])))
|
])))
|
||||||
])));
|
])));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
|
|||||||
.presentationDeadlineNanos = (uint64_t)0,
|
.presentationDeadlineNanos = (uint64_t)0,
|
||||||
.vsyncOffsetNanos = (uint64_t)0});
|
.vsyncOffsetNanos = (uint64_t)0});
|
||||||
Renderer::FrameRateOptions fro;
|
Renderer::FrameRateOptions fro;
|
||||||
fro.interval = 30;
|
fro.interval = 60;
|
||||||
_renderer->setFrameRateOptions(fro);
|
_renderer->setFrameRateOptions(fro);
|
||||||
|
|
||||||
_scene = _engine->createScene();
|
_scene = _engine->createScene();
|
||||||
@@ -119,6 +119,7 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
|
|||||||
Log("Scene created");
|
Log("Scene created");
|
||||||
|
|
||||||
Entity camera = EntityManager::get().create();
|
Entity camera = EntityManager::get().create();
|
||||||
|
|
||||||
_mainCamera = _engine->createCamera(camera);
|
_mainCamera = _engine->createCamera(camera);
|
||||||
Log("Main camera created");
|
Log("Main camera created");
|
||||||
_view = _engine->createView();
|
_view = _engine->createView();
|
||||||
@@ -185,14 +186,15 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
|
|||||||
_scene->addEntity(_sun);
|
_scene->addEntity(_sun);
|
||||||
|
|
||||||
Log("Added sun");
|
Log("Added sun");
|
||||||
|
|
||||||
_sceneAssetLoader = new SceneAssetLoader(_loadResource,
|
_sceneAssetLoader = new SceneAssetLoader(_loadResource,
|
||||||
_freeResource,
|
_freeResource,
|
||||||
_assetLoader,
|
_assetLoader,
|
||||||
_resourceLoader,
|
_resourceLoader,
|
||||||
_ncm,
|
_ncm,
|
||||||
_engine,
|
_engine,
|
||||||
_scene);
|
_scene,
|
||||||
|
tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
static constexpr float4 sFullScreenTriangleVertices[3] = {
|
||||||
@@ -336,23 +338,20 @@ void FilamentViewer::setBackgroundImage(const char *resourcePath) {
|
|||||||
|
|
||||||
FilamentViewer::~FilamentViewer() {
|
FilamentViewer::~FilamentViewer() {
|
||||||
clearAssets();
|
clearAssets();
|
||||||
_resourceLoader->asyncCancelLoad();
|
Log("Deleting SceneAssetLoader");
|
||||||
Log("c1");
|
|
||||||
_materialProvider->destroyMaterials();
|
|
||||||
Log("c2");
|
|
||||||
AssetLoader::destroy(&_assetLoader);
|
|
||||||
Log("c3");
|
|
||||||
delete _sceneAssetLoader;
|
delete _sceneAssetLoader;
|
||||||
|
_resourceLoader->asyncCancelLoad();
|
||||||
|
_materialProvider->destroyMaterials();
|
||||||
|
AssetLoader::destroy(&_assetLoader);
|
||||||
|
_engine->destroy(_sun);
|
||||||
|
_engine->destroyCameraComponent(_mainCamera->getEntity());
|
||||||
|
_mainCamera = nullptr;
|
||||||
_engine->destroy(_view);
|
_engine->destroy(_view);
|
||||||
Log("c4");
|
|
||||||
_engine->destroy(_scene);
|
_engine->destroy(_scene);
|
||||||
Log("c5");
|
|
||||||
_engine->destroy(_renderer);
|
_engine->destroy(_renderer);
|
||||||
Log("c6");
|
|
||||||
_engine->destroy(_swapChain);
|
_engine->destroy(_swapChain);
|
||||||
Log("c7");
|
|
||||||
Engine::destroy(&_engine); // clears engine*
|
Engine::destroy(&_engine); // clears engine*
|
||||||
Log("c8");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer *FilamentViewer::getRenderer() { return _renderer; }
|
Renderer *FilamentViewer::getRenderer() { return _renderer; }
|
||||||
@@ -401,8 +400,11 @@ SceneAsset *FilamentViewer::loadGltf(const char *const uri,
|
|||||||
|
|
||||||
void FilamentViewer::clearAssets() {
|
void FilamentViewer::clearAssets() {
|
||||||
Log("Clearing all assets");
|
Log("Clearing all assets");
|
||||||
mtx.lock();
|
// mtx.lock();
|
||||||
_view->setCamera(_mainCamera);
|
if(_mainCamera) {
|
||||||
|
_view->setCamera(_mainCamera);
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto asset : _assets) {
|
for (auto asset : _assets) {
|
||||||
_sceneAssetLoader->remove(asset);
|
_sceneAssetLoader->remove(asset);
|
||||||
@@ -410,7 +412,8 @@ void FilamentViewer::clearAssets() {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
_assets.clear();
|
_assets.clear();
|
||||||
mtx.unlock();
|
// mtx.unlock();
|
||||||
|
Log("Cleared all assets");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::removeAsset(SceneAsset *asset) {
|
void FilamentViewer::removeAsset(SceneAsset *asset) {
|
||||||
@@ -555,7 +558,7 @@ void FilamentViewer::render() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtx.lock();
|
// mtx.lock();
|
||||||
for (auto &asset : _assets) {
|
for (auto &asset : _assets) {
|
||||||
asset->updateAnimations();
|
asset->updateAnimations();
|
||||||
}
|
}
|
||||||
@@ -569,7 +572,7 @@ void FilamentViewer::render() {
|
|||||||
_renderer->render(_view);
|
_renderer->render(_view);
|
||||||
_renderer->endFrame();
|
_renderer->endFrame();
|
||||||
}
|
}
|
||||||
mtx.unlock();
|
// mtx.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::updateViewportAndCameraProjection(
|
void FilamentViewer::updateViewportAndCameraProjection(
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ namespace polyvox {
|
|||||||
Material* _imageMaterial = nullptr;
|
Material* _imageMaterial = nullptr;
|
||||||
TextureSampler _imageSampler;
|
TextureSampler _imageSampler;
|
||||||
ColorGrading *colorGrading = nullptr;
|
ColorGrading *colorGrading = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ extern "C" {
|
|||||||
void* filament_viewer_new(void* texture, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t)) {
|
void* filament_viewer_new(void* texture, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void filament_viewer_delete(void* viewer) {
|
void filament_viewer_delete(void* viewer) {
|
||||||
delete((FilamentViewer*)viewer);
|
delete((FilamentViewer*)viewer);
|
||||||
@@ -135,8 +134,12 @@ extern "C" {
|
|||||||
((FilamentViewer*)viewer)->clearAssets();
|
((FilamentViewer*)viewer)->clearAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_texture(void* asset, const char* assetPath, int renderableIndex) {
|
void load_texture(void* asset, const char* assetPath, int renderableIndex) {
|
||||||
((SceneAsset*)asset)->setTexture(assetPath, renderableIndex);
|
((SceneAsset*)asset)->loadTexture(assetPath, renderableIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_texture(void* asset) {
|
||||||
|
((SceneAsset*)asset)->setTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_to_unit_cube(void* asset) {
|
void transform_to_unit_cube(void* asset) {
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ void remove_asset(void* viewer, void* asset);
|
|||||||
|
|
||||||
void clear_assets(void* viewer);
|
void clear_assets(void* viewer);
|
||||||
|
|
||||||
void set_texture(void* asset, const char* assetPath, int renderableIndex);
|
void load_texture(void* asset, const char* assetPath, int renderableIndex);
|
||||||
|
void set_texture(void* asset);
|
||||||
|
|
||||||
void transform_to_unit_cube(void* asset);
|
void transform_to_unit_cube(void* asset);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,11 @@ SceneAsset::SceneAsset(FilamentAsset *asset, Engine *engine,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneAsset::~SceneAsset() {
|
SceneAsset::~SceneAsset() {
|
||||||
// we defer all destructor work to SceneAssetLoader so we don't need to do anything here
|
// most other destructor work is deferred to SceneAssetLoader so we don't need to do anything here
|
||||||
|
if(_texture) {
|
||||||
|
_engine->destroy(_texture);
|
||||||
|
_texture = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAsset::applyWeights(float *weights, int count) {
|
void SceneAsset::applyWeights(float *weights, int count) {
|
||||||
@@ -121,26 +125,35 @@ void SceneAsset::stopAnimation(int index) {
|
|||||||
_embeddedAnimationStatus[index].started = false;
|
_embeddedAnimationStatus[index].started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAsset::setTexture(const char* resourcePath, int renderableIndex) {
|
void SceneAsset::loadTexture(const char* resourcePath, int renderableIndex) {
|
||||||
Log("Setting texture to %s for renderableIndex %d", resourcePath, renderableIndex);
|
|
||||||
ResourceBuffer imageResource = _loadResource(resourcePath);
|
|
||||||
|
|
||||||
polyvox::StreamBufferAdapter sb((char *)imageResource.data, (char *)imageResource.data + imageResource.size);
|
Log("Loading texture at %s for renderableIndex %d", resourcePath, renderableIndex);
|
||||||
|
|
||||||
std::istream *inputStream = new std::istream(&sb);
|
string rp("flutter_assets/assets/background.png");
|
||||||
|
|
||||||
|
if(_texture) {
|
||||||
|
_engine->destroy(_texture);
|
||||||
|
_texture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceBuffer imageResource = _loadResource(rp.c_str());
|
||||||
|
|
||||||
|
StreamBufferAdapter sb((char *)imageResource.data, (char *)imageResource.data + imageResource.size);
|
||||||
|
|
||||||
|
istream *inputStream = new std::istream(&sb);
|
||||||
|
|
||||||
LinearImage *image = new LinearImage(ImageDecoder::decode(
|
LinearImage *image = new LinearImage(ImageDecoder::decode(
|
||||||
*inputStream, resourcePath, ImageDecoder::ColorSpace::SRGB));
|
*inputStream, rp.c_str(), ImageDecoder::ColorSpace::SRGB));
|
||||||
|
|
||||||
if (!image->isValid()) {
|
if (!image->isValid()) {
|
||||||
Log("Invalid image : %s", resourcePath);
|
Log("Invalid image : %s", rp.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t channels = image->getChannels();
|
uint32_t channels = image->getChannels();
|
||||||
uint32_t w = image->getWidth();
|
uint32_t w = image->getWidth();
|
||||||
uint32_t h = image->getHeight();
|
uint32_t h = image->getHeight();
|
||||||
auto texture = Texture::Builder()
|
_texture = Texture::Builder()
|
||||||
.width(w)
|
.width(w)
|
||||||
.height(h)
|
.height(h)
|
||||||
.levels(0xff)
|
.levels(0xff)
|
||||||
@@ -149,8 +162,10 @@ void SceneAsset::setTexture(const char* resourcePath, int renderableIndex) {
|
|||||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||||
.build(*_engine);
|
.build(*_engine);
|
||||||
|
|
||||||
|
Log("build texture");
|
||||||
|
|
||||||
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
|
||||||
void *data) {
|
void *data) {
|
||||||
delete reinterpret_cast<LinearImage *>(data);
|
delete reinterpret_cast<LinearImage *>(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,20 +174,26 @@ void SceneAsset::setTexture(const char* resourcePath, int renderableIndex) {
|
|||||||
channels == 3 ? Texture::Format::RGB : Texture::Format::RGBA,
|
channels == 3 ? Texture::Format::RGB : Texture::Format::RGBA,
|
||||||
Texture::Type::FLOAT, freeCallback);
|
Texture::Type::FLOAT, freeCallback);
|
||||||
|
|
||||||
texture->setImage(*_engine, 0, std::move(buffer));
|
_texture->setImage(*_engine, 0, std::move(buffer));
|
||||||
|
Log("set image");
|
||||||
|
setTexture();
|
||||||
|
delete inputStream;
|
||||||
|
|
||||||
size_t mic = _asset->getMaterialInstanceCount();
|
_freeResource(imageResource.id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneAsset::setTexture() {
|
||||||
|
|
||||||
MaterialInstance* const* inst = _asset->getMaterialInstances();
|
MaterialInstance* const* inst = _asset->getMaterialInstances();
|
||||||
|
size_t mic = _asset->getMaterialInstanceCount();
|
||||||
Log("Material instance count : %d", mic);
|
Log("Material instance count : %d", mic);
|
||||||
|
|
||||||
RenderableManager &rm = _engine->getRenderableManager();
|
RenderableManager &rm = _engine->getRenderableManager();
|
||||||
auto sampler = TextureSampler();
|
auto sampler = TextureSampler();
|
||||||
inst[0]->setParameter("baseColorIndex",0);
|
inst[0]->setParameter("baseColorIndex",0);
|
||||||
inst[0]->setParameter("baseColorMap",texture,sampler);
|
inst[0]->setParameter("baseColorMap",_texture,sampler);
|
||||||
|
|
||||||
delete inputStream;
|
|
||||||
|
|
||||||
_freeResource(imageResource.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAsset::updateEmbeddedAnimations() {
|
void SceneAsset::updateEmbeddedAnimations() {
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
#include <filament/Renderer.h>
|
#include <filament/Renderer.h>
|
||||||
#include <filament/Scene.h>
|
#include <filament/Scene.h>
|
||||||
|
#include <filament/Texture.h>
|
||||||
|
|
||||||
#include <gltfio/AssetLoader.h>
|
#include <gltfio/AssetLoader.h>
|
||||||
#include <gltfio/FilamentAsset.h>
|
#include <gltfio/FilamentAsset.h>
|
||||||
#include <gltfio/ResourceLoader.h>
|
#include <gltfio/ResourceLoader.h>
|
||||||
|
|
||||||
|
|
||||||
#include <utils/NameComponentManager.h>
|
#include <utils/NameComponentManager.h>
|
||||||
|
|
||||||
#include "SceneResources.hpp"
|
#include "SceneResources.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace polyvox {
|
namespace polyvox {
|
||||||
using namespace filament;
|
using namespace filament;
|
||||||
using namespace filament::gltfio;
|
using namespace filament::gltfio;
|
||||||
@@ -32,7 +33,8 @@ namespace polyvox {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
void setTexture(const char* resourcePath, int renderableIndex);
|
void loadTexture(const char* resourcePath, int renderableIndex);
|
||||||
|
void setTexture();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Update the bone/morph target animations to reflect the current frame (if applicable).
|
/// Update the bone/morph target animations to reflect the current frame (if applicable).
|
||||||
@@ -79,6 +81,7 @@ namespace polyvox {
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
FilamentAsset* _asset = nullptr;
|
FilamentAsset* _asset = nullptr;
|
||||||
Engine* _engine = nullptr;
|
Engine* _engine = nullptr;
|
||||||
NameComponentManager* _ncm;
|
NameComponentManager* _ncm;
|
||||||
@@ -86,6 +89,7 @@ namespace polyvox {
|
|||||||
void updateMorphAnimation();
|
void updateMorphAnimation();
|
||||||
void updateEmbeddedAnimations();
|
void updateEmbeddedAnimations();
|
||||||
|
|
||||||
|
|
||||||
Animator* _animator;
|
Animator* _animator;
|
||||||
|
|
||||||
// animation flags;
|
// animation flags;
|
||||||
@@ -95,5 +99,8 @@ namespace polyvox {
|
|||||||
LoadResource _loadResource;
|
LoadResource _loadResource;
|
||||||
FreeResource _freeResource;
|
FreeResource _freeResource;
|
||||||
|
|
||||||
|
// a slot to preload textures
|
||||||
|
filament::Texture* _texture = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,8 @@ namespace polyvox {
|
|||||||
ResourceLoader* resourceLoader,
|
ResourceLoader* resourceLoader,
|
||||||
NameComponentManager* ncm,
|
NameComponentManager* ncm,
|
||||||
Engine* engine,
|
Engine* engine,
|
||||||
Scene* scene);
|
Scene* scene,
|
||||||
|
workqueue::threadpool& threadpool);
|
||||||
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
|
SceneAsset* fromGltf(const char* uri, const char* relativeResourcePath);
|
||||||
SceneAsset* fromGlb(const char* uri);
|
SceneAsset* fromGlb(const char* uri);
|
||||||
void remove(SceneAsset* asset);
|
void remove(SceneAsset* asset);
|
||||||
@@ -37,6 +38,7 @@ namespace polyvox {
|
|||||||
NameComponentManager* _ncm;
|
NameComponentManager* _ncm;
|
||||||
Scene* _scene;
|
Scene* _scene;
|
||||||
Engine* _engine;
|
Engine* _engine;
|
||||||
|
workqueue::threadpool& _threadpool;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user