diff --git a/android/src/main/cpp/filament_android.cpp b/android/src/main/cpp/filament_android.cpp index 823c2608..553c076d 100644 --- a/android/src/main/cpp/filament_android.cpp +++ b/android/src/main/cpp/filament_android.cpp @@ -9,10 +9,11 @@ using namespace polyvox; using namespace std; static AAssetManager* am; - static vector _assets; uint64_t id = -1; +static FilamentViewer* _viewer; + static polyvox::ResourceBuffer loadResource(const char* name) { id++; @@ -50,6 +51,10 @@ extern "C" { ((FilamentViewer*)viewer)->loadSkybox(skyboxPath, iblPath); } + void remove_skybox(void* viewer) { + ((FilamentViewer*)viewer)->removeSkybox(); + } + void load_glb(void* viewer, const char* assetPath) { ((FilamentViewer*)viewer)->loadGlb(assetPath); } @@ -67,9 +72,13 @@ extern "C" { JNIEnv* env, jobject assetManager ) { + if(_viewer) { + return _viewer; + } ANativeWindow* layer = ANativeWindow_fromSurface(env, surface); am = AAssetManager_fromJava(env, assetManager); - return new FilamentViewer((void*)layer, loadResource, freeResource); + _viewer = new FilamentViewer((void*)layer, loadResource, freeResource); + return _viewer; } void render( @@ -166,10 +175,6 @@ extern "C" { free(ptr); } - void release_source_assets(void* viewer) { - ((FilamentViewer*)viewer)->releaseSourceAssets(); - } - void remove_asset(void* viewer) { ((FilamentViewer*)viewer)->removeAsset(); } diff --git a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt index 8c2b9509..39e5ac95 100644 --- a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt +++ b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt @@ -64,5 +64,7 @@ interface FilamentInterop : Library { fun remove_asset(viewer:Pointer); + fun remove_skybox(viewer:Pointer); + } diff --git a/android/src/main/kotlin/app/polyvox/filament/FilamentView.kt b/android/src/main/kotlin/app/polyvox/filament/FilamentView.kt index 8789ba53..9f2b83fe 100644 --- a/android/src/main/kotlin/app/polyvox/filament/FilamentView.kt +++ b/android/src/main/kotlin/app/polyvox/filament/FilamentView.kt @@ -104,9 +104,9 @@ PlatformView { _methodChannel.invokeMethod("ready", null) choreographer = Choreographer.getInstance() - + // _view.setAlpha(0) _view.setZOrderOnTop(false) - _view.holder.setFormat(PixelFormat.OPAQUE) + _view.holder.setFormat(PixelFormat.TRANSPARENT) _view.holder.addCallback (object : SurfaceHolder.Callback { override fun surfaceChanged(holder:SurfaceHolder, format:Int, width:Int, height:Int) { @@ -151,19 +151,34 @@ PlatformView { override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { + "reloadAssets" -> { + // context = context.createPackageContext(context.getPackageName(), 0) + // val assetManager = context.getAssets() + // val flutterJNI = FlutterJNI.Factory.provideFlutterJNI() + // flutterJNI.updateJavaAssetManager(assetManager, flutterApplicationInfo.flutterAssetsDir) + } "loadSkybox" -> { val args = call.arguments as ArrayList val loader = FlutterInjector.instance().flutterLoader() _lib.load_skybox(_viewer!!, loader.getLookupKeyForAsset(args[0] as String), loader.getLookupKeyForAsset(args[1] as String)) result.success("OK"); } + "removeSkybox" -> { + _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, context.packageName) + val path = loader.findAppBundlePath() + Log.v(TAG, "key ${key} key2 ${key2} path : ${path}") + _lib.load_glb( _viewer!!, - loader.getLookupKeyForAsset(call.arguments as String) + key ) result.success("OK"); } @@ -297,10 +312,6 @@ PlatformView { _lib.grab_end(_viewer!!) result.success("OK"); } - "releaseSourceAssets" -> { - _lib.release_source_assets(_viewer!!) - result.success("OK"); - } "removeAsset" -> { _lib.remove_asset(_viewer!!) result.success("OK"); diff --git a/example/android/app/src/main/MainActivity.kt b/example/android/app/src/main/MainActivity.kt deleted file mode 100644 index 4442a61e..00000000 --- a/example/android/app/src/main/MainActivity.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.polyvox.filament_example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { - -} diff --git a/ios/Classes/FilamentMethodCallHandler.mm b/ios/Classes/FilamentMethodCallHandler.mm index cb1a111a..8e5beaca 100644 --- a/ios/Classes/FilamentMethodCallHandler.mm +++ b/ios/Classes/FilamentMethodCallHandler.mm @@ -41,6 +41,9 @@ using namespace std; if([@"loadSkybox" isEqualToString:call.method]) { _viewer->loadSkybox([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]); result(@"OK"); + } else if([@"loadSkybox" isEqualToString:call.method]) { + _viewer->removeSkybox(); + result(@"OK"); } else if([@"loadGlb" isEqualToString:call.method]) { _viewer->loadGlb([call.arguments UTF8String]); result(@"OK"); @@ -68,9 +71,6 @@ using namespace std; } else if([@"rotateEnd" isEqualToString:call.method]) { _viewer->manipulator->grabEnd(); result(@"OK"); - } else if([@"releaseSourceAssets" isEqualToString:call.method]) { - _viewer->releaseSourceAssets(); - result(@"OK"); } else if([@"animateWeights" isEqualToString:call.method]) { NSArray* frameData = call.arguments[0]; NSNumber* numWeights = call.arguments[1]; diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 38dea53f..6502022b 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -59,6 +59,8 @@ #include #include +#include + #include "Log.h" using namespace filament; @@ -259,27 +261,11 @@ namespace polyvox _scene->addEntities(_asset->getEntities(), _asset->getEntityCount()); }; - void FilamentViewer::releaseSourceAssets() - { - Log("Releasing source data"); - _asset->releaseSourceData(); - } - void FilamentViewer::loadGlb(const char *const uri) { Log("Loading GLB at URI %s", uri); - // if (_asset) - // { - // _asset->releaseSourceData(); - // _resourceLoader->evictResourceData(); - // _scene->removeEntities(_asset->getEntities(), _asset->getEntityCount()); - // _assetLoader->destroyAsset(_asset); - // } - // _asset = nullptr; - // _animator = nullptr; - ResourceBuffer rbuf = _loadResource(uri); _asset = _assetLoader->createAssetFromBinary( @@ -354,6 +340,8 @@ namespace polyvox Log("No asset loaded, ignoring call."); return; } + + mtx.lock(); _resourceLoader->evictResourceData(); _scene->removeEntities(_asset->getEntities(), _asset->getEntityCount()); @@ -362,6 +350,12 @@ namespace polyvox _animator = nullptr; _morphAnimationBuffer = nullptr; _embeddedAnimationBuffer = nullptr; + _view->setCamera(_mainCamera); + mtx.unlock(); + } + + void FilamentViewer::removeSkybox() { + _scene->setSkybox(nullptr); } @@ -384,7 +378,7 @@ namespace polyvox } const utils::Entity* cameras = _asset->getCameraEntities(); - Log("%d cameras found in current asset", cameraName, count); + Log("%zu cameras found in current asset", cameraName, count); for(int i=0; i < count; i++) { auto inst = _ncm->getInstance(cameras[i]); @@ -411,7 +405,10 @@ namespace polyvox unique_ptr> FilamentViewer::getAnimationNames() { - + if(!_asset) { + Log("No asset, ignoring call."); + return nullptr; + } size_t count = _animator->getAnimationCount(); Log("Found %d animations in asset.", count); @@ -428,6 +425,10 @@ namespace polyvox unique_ptr> FilamentViewer::getTargetNames(const char *meshName) { + if(!_asset) { + Log("No asset, ignoring call."); + return nullptr; + } Log("Retrieving morph target names for mesh %s", meshName); unique_ptr> names = make_unique>(); const Entity *entities = _asset->getEntities(); @@ -512,20 +513,19 @@ namespace polyvox void FilamentViewer::render() { + if (!_view || !_mainCamera || !_swapChain) { Log("Not ready for rendering"); return; } - - if (_morphAnimationBuffer) - { + + mtx.lock(); + if(_asset) { updateMorphAnimation(); - } - - if(_embeddedAnimationBuffer) { updateEmbeddedAnimation(); } + math::float3 eye, target, upward; manipulator->getLookAt(&eye, &target, &upward); @@ -537,6 +537,7 @@ namespace polyvox _renderer->render(_view); _renderer->endFrame(); } + mtx.unlock(); } void FilamentViewer::updateViewportAndCameraProjection(int width, int height, float contentScaleFactor) @@ -607,6 +608,9 @@ namespace polyvox } void FilamentViewer::updateEmbeddedAnimation() { + if(!_embeddedAnimationBuffer) { + return; + } duration dur = duration_cast>(high_resolution_clock::now() - _embeddedAnimationBuffer->lastTime); float startTime = 0; if(!_embeddedAnimationBuffer->hasStarted) { diff --git a/ios/src/FilamentViewer.hpp b/ios/src/FilamentViewer.hpp index 7181cc46..7e3060ef 100644 --- a/ios/src/FilamentViewer.hpp +++ b/ios/src/FilamentViewer.hpp @@ -92,14 +92,16 @@ namespace polyvox { public: FilamentViewer(void* layer, LoadResource loadResource, FreeResource freeResource); ~FilamentViewer(); + + void loadSkybox(const char* const skyboxUri, const char* const iblUri); + void removeSkybox(); + void loadGlb(const char* const uri); void loadGltf(const char* const uri, const char* relativeResourcePath); - void loadSkybox(const char* const skyboxUri, const char* const iblUri); void removeAsset(); void updateViewportAndCameraProjection(int height, int width, float scaleFactor); void render(); - void releaseSourceAssets(); unique_ptr> getTargetNames(const char* meshName); unique_ptr> getAnimationNames(); Manipulator* manipulator; @@ -158,8 +160,8 @@ namespace polyvox { AssetLoader* _assetLoader; FilamentAsset* _asset = nullptr; - // ResourceBuffer _assetBuffer; NameComponentManager* _ncm; + std::mutex mtx; // mutex to ensure thread safety when removing assets Entity _sun; Texture* _skyboxTexture; @@ -184,6 +186,7 @@ namespace polyvox { bool isAnimating; unique_ptr _morphAnimationBuffer; unique_ptr _embeddedAnimationBuffer; + }; diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index ea592306..fd641f15 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; abstract class FilamentController { void onFilamentViewCreated(int id); Future loadSkybox(String skyboxPath, String lightingPath); + Future removeSkybox(); Future loadGlb(String path); Future loadGltf(String path, String relativeResourcePath); Future panStart(double x, double y); @@ -62,6 +63,11 @@ class PolyvoxFilamentController extends FilamentController { await _channel.invokeMethod("loadSkybox", [skyboxPath, lightingPath]); } + @override + Future removeSkybox() async { + await _channel.invokeMethod("removeSkybox"); + } + Future loadGlb(String path) async { print("Loading GLB at $path "); await _channel.invokeMethod("loadGlb", path);