diff --git a/example/assets/cube.blend b/example/assets/cube.blend index 6b3f9403..7578da75 100644 Binary files a/example/assets/cube.blend and b/example/assets/cube.blend differ diff --git a/example/assets/cube.glb b/example/assets/cube.glb index f211d1c0..8397d6f2 100644 Binary files a/example/assets/cube.glb and b/example/assets/cube.glb differ diff --git a/example/lib/main.dart b/example/lib/main.dart index 44b35fae..40fa2cde 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -206,7 +206,7 @@ class _ExampleWidgetState extends State { .interpolateMorphWeights(0, 4, 0, 1) .build(); _filamentController.setMorphAnimationData(_cube!, animation); - }, "animate morph weights #1 and #2"), + }, "animate cylinder morph weights #1 and #2"), _item(() async { var morphs = await _filamentController.getMorphTargetNames(_cube!, "Cylinder"); @@ -217,19 +217,34 @@ class _ExampleWidgetState extends State { .interpolateMorphWeights(0, 4, 0, 1) .build(); _filamentController.setMorphAnimationData(_cube!, animation); - }, "animate morph weights #3 and #4"), + }, "animate cylinder morph weights #3 and #4"), + _item(() async { + var morphs = + await _filamentController.getMorphTargetNames(_cube!, "Cube"); + final animation = AnimationBuilder( + availableMorphs: morphs, framerate: 30, meshName: "Cube") + .setDuration(4) + .setMorphTargets(["Key 1", "Key 2"]) + .interpolateMorphWeights(0, 4, 0, 1) + .build(); + _filamentController.setMorphAnimationData(_cube!, animation); + }, "animate cube morph weights #1 and #2"), _item(() { _filamentController.setMaterialColor(_cube!, "Cone", 0, Colors.purple); - }, "set cone material color to purple") + }, "set cone material color to purple"), + _item(() { + _loop = !_loop; + setState(() {}); + }, "toggle animation looping ${_loop ? "OFF" : "ON"}") ]; if (_animations != null) { children.addAll(_animations!.map((a) => _item(() { _filamentController.playAnimation(_cube!, _animations!.indexOf(a), - replaceActive: true, crossfade: 0.5); + replaceActive: true, crossfade: 0.5, loop: _loop); }, "play animation ${_animations!.indexOf(a)} (replace/fade)"))); children.addAll(_animations!.map((a) => _item(() { _filamentController.playAnimation(_cube!, _animations!.indexOf(a), - replaceActive: false); + replaceActive: false, loop: _loop); }, "play animation ${_animations!.indexOf(a)} (noreplace)"))); } @@ -257,9 +272,7 @@ class _ExampleWidgetState extends State { // _item(36 () async { 'play animation 3'), // _item(34 () async { 'play animation 3 (noreplace)'), // _item(37 () async { 'stop animation 0'), - // _item(11 () async { - // Text( - // _loop ? "don't loop animation" : "loop animation")), + // _item(14 () async { 'set camera'), // _item(15 () async { 'animate weights'), // _item(16 () async { 'get target names'), diff --git a/ios/include/FilamentViewer.hpp b/ios/include/FilamentViewer.hpp index 6ae31988..373f92b6 100644 --- a/ios/include/FilamentViewer.hpp +++ b/ios/include/FilamentViewer.hpp @@ -42,11 +42,18 @@ using namespace camutils; typedef int32_t EntityId; namespace polyvox { + + enum ToneMapping { + ACES, FILMIC, LINEAR + }; + class FilamentViewer { public: FilamentViewer(const void* context, const ResourceLoaderWrapper* const resourceLoaderWrapper); ~FilamentViewer(); + void setToneMapping(ToneMapping toneMapping); + void setBloom(float strength); void loadSkybox(const char* const skyboxUri); void removeSkybox(); diff --git a/ios/include/PolyvoxFilamentApi.h b/ios/include/PolyvoxFilamentApi.h index 93363ef4..f6c24029 100644 --- a/ios/include/PolyvoxFilamentApi.h +++ b/ios/include/PolyvoxFilamentApi.h @@ -14,6 +14,8 @@ void clear_background_image(const void* const viewer); void set_background_image(const void* const viewer, const char *path); void set_background_image_position(const void* const viewer, float x, float y, bool clamp); void set_background_color(const void* const viewer, const float r, const float g, const float b, const float a); +void set_tone_mapping(const void* const viewer, int toneMapping); +void set_bloom(const void* const viewer, float strength); void load_skybox(const void* const viewer, const char *skyboxPath); void load_ibl(const void* const viewer, const char *iblPath, float intensity); void remove_skybox(const void* const viewer); diff --git a/ios/include/ResourceBuffer.hpp b/ios/include/ResourceBuffer.hpp index 182e10ae..2ba8e4e9 100644 --- a/ios/include/ResourceBuffer.hpp +++ b/ios/include/ResourceBuffer.hpp @@ -66,11 +66,11 @@ extern "C" { } } #endif - LoadResource mLoadResource; - FreeResource mFreeResource; - LoadResourceFromOwner mLoadResourceFromOwner; - FreeResourceFromOwner mFreeResourceFromOwner; - void* mOwner; + LoadResource mLoadResource = nullptr; + FreeResource mFreeResource = nullptr; + LoadResourceFromOwner mLoadResourceFromOwner = nullptr; + FreeResourceFromOwner mFreeResourceFromOwner = nullptr; + void* mOwner = nullptr; }; typedef struct ResourceLoaderWrapper ResourceLoaderWrapper; diff --git a/ios/src/AssetManager.cpp b/ios/src/AssetManager.cpp index e020b94f..fa37ceb4 100644 --- a/ios/src/AssetManager.cpp +++ b/ios/src/AssetManager.cpp @@ -303,6 +303,9 @@ void AssetManager::updateAnimations() { break; } } + if(anim.mLoop && elapsed >= anim.mDuration) { + anim.mStart = now; + } // animation has completed } else { completed.push_back(anim); @@ -390,9 +393,16 @@ void AssetManager::setMorphTargetWeights(EntityId entityId, const char* const en } RenderableManager &rm = _engine->getRenderableManager(); + + auto renderableInstance = rm.getInstance(entity); + + if(!renderableInstance.isValid()) { + Log("Warning: failed to find renderable instance for entity %s", entityName); + return; + } rm.setMorphWeights( - rm.getInstance(entity), + renderableInstance, weights, count ); diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index a4420ea5..ba5abb0e 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -136,21 +136,13 @@ FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* Log("Main camera created"); _view = _engine->createView(); - decltype(_view->getBloomOptions()) opts; - opts.enabled = true; - opts.strength = 0.6f; - _view->setBloomOptions(opts); + setToneMapping(ToneMapping::ACES); + + setBloom(0.6f); _view->setScene(_scene); _view->setCamera(_mainCamera); -// ToneMapper *tm = new ACESToneMapper(); - ToneMapper *tm = new LinearToneMapper(); - colorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine); - delete tm; - - _view->setColorGrading(colorGrading); - _cameraFocalLength = 28.0f; _mainCamera->setLensProjection(_cameraFocalLength, 1.0f, kNearPlane, kFarPlane); @@ -243,6 +235,35 @@ FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* _scene->addEntity(imageEntity); } +void FilamentViewer::setBloom(float strength) { + decltype(_view->getBloomOptions()) opts; + opts.enabled = true; + opts.strength = strength; + _view->setBloomOptions(opts); +} + +void FilamentViewer::setToneMapping(ToneMapping toneMapping) { + + ToneMapper* tm; + switch(toneMapping) { + case ToneMapping::ACES: + tm = new ACESToneMapper(); + break; + case ToneMapping::LINEAR: + tm = new LinearToneMapper(); + break; + case ToneMapping::FILMIC: + tm = new FilmicToneMapper(); + break; + } + + + auto newColorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine); + _view->setColorGrading(newColorGrading); + _engine->destroy(colorGrading); + delete tm; +} + void FilamentViewer::setFrameInterval(float frameInterval) { Renderer::FrameRateOptions fro; fro.interval = frameInterval; diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index 446aaf69..c97b4c9b 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -48,6 +48,15 @@ extern "C" { ((FilamentViewer*)viewer)->setBackgroundImagePosition(x, y, clamp); } + FLUTTER_PLUGIN_EXPORT void set_tone_mapping(const void* const viewer, int toneMapping) { + ((FilamentViewer*)viewer)->setToneMapping((ToneMapping)toneMapping); + } + + FLUTTER_PLUGIN_EXPORT void set_bloom(const void* const viewer, float strength) { + Log("Setting bloom to %f", strength); + ((FilamentViewer*)viewer)->setBloom(strength); + } + FLUTTER_PLUGIN_EXPORT void load_skybox(const void* const viewer, const char* skyboxPath) { ((FilamentViewer*)viewer)->loadSkybox(skyboxPath); } @@ -191,6 +200,8 @@ extern "C" { ); } + + FLUTTER_PLUGIN_EXPORT bool set_morph_animation( void* assetManager, EntityId asset, diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index 6c93567f..a2f1503d 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -13,6 +13,8 @@ typedef AssetManager = int; typedef FilamentEntity = int; const FilamentEntity FILAMENT_ASSET_ERROR = 0; +enum ToneMapper { ACES, FILMIC, LINEAR } + class FilamentController { late MethodChannel _channel = MethodChannel("app.polyvox.filament/event"); @@ -112,8 +114,8 @@ class FilamentController { await _channel.invokeMethod("updateViewportAndCameraProjection", [size.width.toInt(), size.height.toInt(), 1.0]); - _assetManager = await _channel.invokeMethod("getAssetManager"); + _textureIdController.add(_textureId); } @@ -206,8 +208,8 @@ class FilamentController { } Future loadGlb(String path, {bool unlit = false}) async { - var asset = await _channel - .invokeMethod("loadGlb", [_assetManager, path, unlit ? 1 : 0]); + var asset = + await _channel.invokeMethod("loadGlb", [_assetManager, path, unlit]); if (asset == FILAMENT_ASSET_ERROR) { throw Exception("An error occurred loading the asset at $path"); } @@ -359,15 +361,8 @@ class FilamentController { bool reverse = false, bool replaceActive = true, double crossfade = 0.0}) async { - await _channel.invokeMethod("playAnimation", [ - _assetManager, - asset, - index, - loop ? 1 : 0, - reverse ? 1 : 0, - replaceActive, - crossfade - ]); + await _channel.invokeMethod("playAnimation", + [_assetManager, asset, index, loop, reverse, replaceActive, crossfade]); } void setAnimationFrame( @@ -387,6 +382,18 @@ class FilamentController { } } + void setToneMapping(ToneMapper mapper) async { + if (!await _channel.invokeMethod("setToneMapping", mapper.index)) { + throw Exception("Failed to set tone mapper"); + } + } + + void setBloom(double bloom) async { + if (!await _channel.invokeMethod("setBloom", bloom)) { + throw Exception("Failed to set bloom"); + } + } + void setCameraFocalLength(double focalLength) async { await _channel.invokeMethod("setCameraFocalLength", focalLength); } diff --git a/linux/polyvox_filament_plugin.cc b/linux/polyvox_filament_plugin.cc index 1bdca77f..71303bde 100644 --- a/linux/polyvox_filament_plugin.cc +++ b/linux/polyvox_filament_plugin.cc @@ -62,11 +62,28 @@ static gboolean on_frame_tick(GtkWidget* widget, GdkFrameClock* frame_clock, gpo static FlMethodResponse* _create_filament_viewer(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { auto callback = new ResourceLoaderWrapper(loadResource, freeResource); + FlValue* args = fl_method_call_get_args(method_call); + + const double width = fl_value_get_float(fl_value_get_list_value(args, 0)); + const double height = fl_value_get_float(fl_value_get_list_value(args, 1)); + + self->width = width; + self->height = height; + auto context = glXGetCurrentContext(); self->viewer = (polyvox::FilamentViewer*)create_filament_viewer( (void*)context, callback ); + + GtkWidget *w = gtk_widget_get_toplevel (GTK_WIDGET(self->fl_view)); + gtk_widget_add_tick_callback(w, on_frame_tick, self,NULL); + + // don't pass a surface to the SwapChain as we are effectively creating a headless SwapChain that will render into a RenderTarget associated with a texture + create_swap_chain(self->viewer, nullptr, width, height); + create_render_target(self->viewer, ((FilamentTextureGL*)self->texture)->texture_id,width,height); + update_viewport_and_camera_projection(self->viewer, width, height, 1.0f); + g_autoptr(FlValue) result = fl_value_new_int(reinterpret_cast(self->viewer)); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); @@ -91,10 +108,31 @@ static FlMethodResponse* _create_texture(PolyvoxFilamentPlugin* self, FlMethodCa g_autoptr(FlValue) result = fl_value_new_int(reinterpret_cast(texture)); + + Log("Successfully created texture."); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } + +static FlMethodResponse* _update_viewport_and_camera_projection(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + + auto width = fl_value_get_int(fl_value_get_list_value(args, 0)); + auto height = fl_value_get_int(fl_value_get_list_value(args, 1)); + auto scaleFactor = fl_value_get_float(fl_value_get_list_value(args, 2)); + + update_viewport_and_camera_projection(self->viewer, width, height, scaleFactor); + + return FL_METHOD_RESPONSE(fl_method_success_response_new(fl_value_new_bool(true))); +} + + +static FlMethodResponse* _get_asset_manager(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + auto assetManager = get_asset_manager(self->viewer); + return FL_METHOD_RESPONSE(fl_method_success_response_new(fl_value_new_int(reinterpret_cast(assetManager)))); +} + static FlMethodResponse* _resize(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { FlValue* args = fl_method_call_get_args(method_call); @@ -165,9 +203,12 @@ static FlMethodResponse* _set_background_image(PolyvoxFilamentPlugin* self, FlMe } static FlMethodResponse* _set_background_color(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { - - const float* color = fl_value_get_float32_list(fl_method_call_get_args(method_call)); - set_background_color(self->viewer, color[0], color[1], color[2], color[2]); + FlValue* args = fl_method_call_get_args(method_call); + const float r = fl_value_get_float(fl_value_get_list_value(args, 0)); + const float g = fl_value_get_float(fl_value_get_list_value(args, 1)); + const float b = fl_value_get_float(fl_value_get_list_value(args, 2)); + const float a = fl_value_get_float(fl_value_get_list_value(args, 3)); + set_background_color(self->viewer, r,g,b,a); g_autoptr(FlValue) result = fl_value_new_string("OK"); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); @@ -196,9 +237,10 @@ static FlMethodResponse* _add_light(PolyvoxFilamentPlugin* self, FlMethodCall* m static FlMethodResponse* _load_glb(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { FlValue* args = fl_method_call_get_args(method_call); - auto path = fl_value_get_string(fl_value_get_list_value(args, 0)); - auto unlit = fl_value_get_bool(fl_value_get_list_value(args, 1)); - auto entityId = load_glb(self->viewer, path, unlit); + auto assetManager = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); + auto path = fl_value_get_string(fl_value_get_list_value(args, 1)); + auto unlit = fl_value_get_bool(fl_value_get_list_value(args, 2)); + auto entityId = load_glb(assetManager, path, unlit); g_autoptr(FlValue) result = fl_value_new_int((int64_t)entityId); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } @@ -418,19 +460,45 @@ static FlMethodResponse* _set_frame_interval(PolyvoxFilamentPlugin* self, FlMeth return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } -static FlMethodResponse* _zoom_begin(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { +static FlMethodResponse* _grab_begin(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 0)); + auto y = (float)fl_value_get_float(fl_value_get_list_value(args, 1)); + auto pan = (bool)fl_value_get_bool(fl_value_get_list_value(args, 2)); + grab_begin(self->viewer, x, y, pan); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _grab_end(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + grab_end(self->viewer); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _grab_update(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 0)); + auto y = (float)fl_value_get_float(fl_value_get_list_value(args, 1)); + + grab_update(self->viewer, x,y); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _scroll_begin(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { scroll_begin(self->viewer); g_autoptr(FlValue) result = fl_value_new_string("OK"); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } -static FlMethodResponse* _zoom_end(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { +static FlMethodResponse* _scroll_end(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { scroll_end(self->viewer); g_autoptr(FlValue) result = fl_value_new_string("OK"); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } -static FlMethodResponse* _zoom_update(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { +static FlMethodResponse* _scroll_update(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { FlValue* args = fl_method_call_get_args(method_call); auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 0)); auto y = (float)fl_value_get_float(fl_value_get_list_value(args, 1)); @@ -466,51 +534,69 @@ static FlMethodResponse* _stop_animation(PolyvoxFilamentPlugin* self, FlMethodCa return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } -static FlMethodResponse* _apply_weights(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { - // FlValue* args = fl_method_call_get_args(method_call); - // auto assetPtr = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); - // auto entityName = fl_value_get_string(fl_value_get_list_value(args, 1)); - // auto weightsValue = fl_value_get_list_value(args, 2); - // float* const weights = (float* const) fl_value_get_float32_list(weightsValue); - // size_t len = fl_value_get_length(weightsValue); - // apply_weights(assetPtr, entityName, weights, (int)len); + +static FlMethodResponse* _set_morph_target_weights(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto assetManager = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); + auto asset = (EntityId)fl_value_get_int(fl_value_get_list_value(args, 1)); + auto entityName = fl_value_get_string(fl_value_get_list_value(args, 2)); + auto flWeights = fl_value_get_list_value(args, 3); + size_t numWeights = fl_value_get_length(flWeights); + + std::vector weights(numWeights); + for(int i =0; i < numWeights; i++) { + float val = fl_value_get_float(fl_value_get_list_value(flWeights, i)); + weights[i] = val; + } + + set_morph_target_weights(assetManager, asset, entityName, weights.data(), (int)numWeights); + g_autoptr(FlValue) result = fl_value_new_string("OK"); return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } +template class std::vector; + static FlMethodResponse* _set_morph_animation(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { - throw std::invalid_argument( "received negative value" ); - // int64_t assetManager = std::any_cast(args[0]); - // EntityId asset = std::any_cast(args[1]); - // std::string entityName = std::any_cast(fl_value_get_string(fl_value_get_list_value(args, 2))); + FlValue* args = fl_method_call_get_args(method_call); + auto assetManager = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); + auto asset = (EntityId)fl_value_get_int(fl_value_get_list_value(args, 1)); + auto entityName = fl_value_get_string(fl_value_get_list_value(args, 2)); + + auto morphDataList = fl_value_get_list_value(args, 3); + auto morphDataListLength = fl_value_get_length(morphDataList); + auto morphData = std::vector(morphDataListLength); + + for(int i =0; i < morphDataListLength; i++) { + morphData[i] = fl_value_get_float(fl_value_get_list_value(morphDataList, i)); + } - // std::vector morphData = std::any_cast>(args[3]); - // std::vector morphIndices = std::any_cast>(args[4]); - // int32_t numMorphTargets = std::any_cast(args[5]); - // int32_t numFrames = std::any_cast(args[6]); - // double frameLengthInMs = std::any_cast(args[7]); + auto morphIndicesList = fl_value_get_list_value(args, 4); + auto morphIndicesListLength = fl_value_get_length(morphIndicesList); + auto indices = std::vector(morphIndicesListLength); + + for(int i =0; i < morphIndicesListLength; i++) { + FlValue* flMorphIndex = fl_value_get_list_value(morphIndicesList, i); + indices[i] = static_cast(fl_value_get_int(flMorphIndex)); + } + + int64_t numMorphTargets = fl_value_get_int(fl_value_get_list_value(args, 5)); + int64_t numFrames = fl_value_get_int(fl_value_get_list_value(args, 6)); + float frameLengthInMs = fl_value_get_float(fl_value_get_list_value(args, 7)); - // // Convert morphData from double to float - // std::vector frameData; - // frameData.reserve(morphData.size()); - // for (double value : morphData) { - // frameData.push_back(static_cast(value)); - // } + bool success = set_morph_animation( + assetManager, + asset, + (const char *const)entityName, + (const float *const)morphData.data(), + (const int* const)indices.data(), + static_cast(numMorphTargets), + static_cast(numFrames), + frameLengthInMs + ); + g_autoptr(FlValue) result = fl_value_new_bool(success); - // void* am = reinterpret_cast(assetManager); - - // bool success = set_morph_animation( - // am, - // asset, - // entityName.c_str(), - // frameData, - // morphIndices, - // numMorphTargets, - // numFrames, - // static_cast(frameLengthInMs) - // ); - - // return success; + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } static FlMethodResponse* _set_animation(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { @@ -596,12 +682,11 @@ static FlMethodResponse* _get_morph_target_names(PolyvoxFilamentPlugin* self, Fl auto assetManager = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); auto asset = (EntityId)fl_value_get_int(fl_value_get_list_value(args, 1)); auto meshName = fl_value_get_string(fl_value_get_list_value(args, 2)); + g_autoptr(FlValue) result = fl_value_new_list(); auto numNames = get_morph_target_name_count(assetManager, asset, meshName); - std::cout << numNames << " morph targets found in mesh " << meshName << std::endl; - for(int i = 0; i < numNames; i++) { gchar out[255]; get_morph_target_name(assetManager, asset, meshName, out, i); @@ -611,7 +696,18 @@ static FlMethodResponse* _get_morph_target_names(PolyvoxFilamentPlugin* self, Fl return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } +static FlMethodResponse* _set_tone_mapping(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + polyvox::ToneMapping toneMapping = static_cast(fl_value_get_int(args)); + set_tone_mapping(self->viewer, toneMapping); + return FL_METHOD_RESPONSE(fl_method_success_response_new(fl_value_new_bool(true))); +} +static FlMethodResponse* _set_bloom(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + set_bloom(self->viewer, fl_value_get_float(args)); + return FL_METHOD_RESPONSE(fl_method_success_response_new(fl_value_new_bool(true))); +} // Called when a method call is received from Flutter. static void polyvox_filament_plugin_handle_method_call( @@ -626,6 +722,14 @@ static void polyvox_filament_plugin_handle_method_call( response = _create_filament_viewer(self, method_call); } else if(strcmp(method, "createTexture") == 0) { response = _create_texture(self, method_call); + } else if(strcmp(method, "updateViewportAndCameraProjection")==0){ + response = _update_viewport_and_camera_projection(self, method_call); + } else if(strcmp(method, "getAssetManager") ==0){ + response = _get_asset_manager(self, method_call); + } else if(strcmp(method, "setToneMapping") == 0) { + response = _set_tone_mapping(self, method_call); + } else if(strcmp(method, "setBloom") == 0) { + response = _set_bloom(self, method_call); } else if(strcmp(method, "resize") == 0) { response = _resize(self, method_call); } else if(strcmp(method, "getContext") == 0) { @@ -704,20 +808,26 @@ static void polyvox_filament_plugin_handle_method_call( response = _set_camera_rotation(self, method_call); } else if(strcmp(method, "setFrameInterval") == 0) { response = _set_frame_interval(self, method_call); - } else if(strcmp(method, "zoomBegin") == 0) { - response = _zoom_begin(self, method_call); - } else if(strcmp(method, "zoomEnd") == 0) { - response = _zoom_end(self, method_call); - } else if(strcmp(method, "zoomUpdate") == 0) { - response = _zoom_update(self, method_call); + } else if(strcmp(method, "scrollBegin") == 0) { + response = _scroll_begin(self, method_call); + } else if(strcmp(method, "scrollEnd") == 0) { + response = _scroll_end(self, method_call); + } else if(strcmp(method, "scrollUpdate") == 0) { + response = _scroll_update(self, method_call); + } else if(strcmp(method, "grabBegin") == 0) { + response = _grab_begin(self, method_call); + } else if(strcmp(method, "grabEnd") == 0) { + response = _grab_end(self, method_call); + } else if(strcmp(method, "grabUpdate") == 0) { + response = _grab_update(self, method_call); } else if(strcmp(method, "playAnimation") == 0) { response = _play_animation(self, method_call); } else if(strcmp(method, "stopAnimation") == 0) { response = _stop_animation(self, method_call); } else if(strcmp(method, "setMorphTargetWeights") == 0) { - response = _apply_weights(self, method_call); - } else if(strcmp(method, "setAnimation") == 0) { - response = _set_animation(self, method_call); + response = _set_morph_target_weights(self, method_call); + } else if(strcmp(method, "setMorphAnimation") == 0) { + response = _set_morph_animation(self, method_call); } else if(strcmp(method, "getMorphTargetNames") == 0) { response = _get_morph_target_names(self, method_call); } else if(strcmp(method, "setPosition") == 0) {