From 964fdab8bcaf05c3b86da32478b3e6825c2afd6e Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 9 Dec 2022 14:42:54 +0800 Subject: [PATCH] more method channel work for Linux --- linux/polyvox_filament_plugin.cc | 235 ++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 1 deletion(-) diff --git a/linux/polyvox_filament_plugin.cc b/linux/polyvox_filament_plugin.cc index 82b397b0..06aafc57 100644 --- a/linux/polyvox_filament_plugin.cc +++ b/linux/polyvox_filament_plugin.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -44,6 +45,18 @@ struct _PolyvoxFilamentPlugin { G_DEFINE_TYPE(PolyvoxFilamentPlugin, polyvox_filament_plugin, g_object_get_type()) +static bool _rendering = false; + +static gboolean on_frame_tick(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer self) { + if(_rendering) { + PolyvoxFilamentPlugin* plugin = (PolyvoxFilamentPlugin*)self; + render(plugin->_viewer, 0); + fl_texture_registrar_mark_texture_frame_available(plugin->texture_registrar, + plugin->texture); + } + return TRUE; +} + static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { @@ -58,6 +71,7 @@ static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* 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)); + auto texture = create_filament_texture(uint32_t(width), uint32_t(height), self->texture_registrar); //auto texture = create_filament_pb_texture(uint32_t(width), uint32_t(height), self->texture_registrar); @@ -69,6 +83,9 @@ static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* freeResource ); + 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*)texture)->texture_id,width,height); @@ -77,7 +94,7 @@ static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* g_autoptr(FlValue) result = fl_value_new_int(reinterpret_cast(texture)); - + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } @@ -157,6 +174,178 @@ static FlMethodResponse* _get_animation_names(PolyvoxFilamentPlugin* self, FlMet return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } +static FlMethodResponse* _remove_asset(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto assetPtr = (void*)fl_value_get_int(args); + remove_asset(self->_viewer, assetPtr); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _transform_to_unit_cube(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto assetPtr = (void*)fl_value_get_int(args); + transform_to_unit_cube(assetPtr); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _rotate_start(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_begin(self->_viewer, x,y, false); + + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _rotate_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* _rotate_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* _pan_start(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_begin(self->_viewer, x,y, true); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _pan_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* _pan_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* _set_camera_position(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 z = (float)fl_value_get_float(fl_value_get_list_value(args, 2)); + set_camera_position(self->_viewer, x,y, z); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _set_camera_rotation(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + auto rads = (float)fl_value_get_float(fl_value_get_list_value(args,0 )); + auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 1)); + auto y = (float)fl_value_get_float(fl_value_get_list_value(args, 2)); + auto z = (float)fl_value_get_float(fl_value_get_list_value(args, 3)); + + set_camera_rotation(self->_viewer, rads, x,y, z); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _set_rendering(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + _rendering = (bool)fl_value_get_bool(args); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _zoom_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) { + 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) { + 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 z = (float)fl_value_get_float(fl_value_get_list_value(args, 2)); + + scroll_update(self->_viewer, x,y, z); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _play_animation(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 animationId = (int)fl_value_get_int(fl_value_get_list_value(args, 1)); + auto loop = (bool)fl_value_get_bool(fl_value_get_list_value(args, 2)); + auto reverse = (bool)fl_value_get_bool(fl_value_get_list_value(args, 3)); + play_animation(assetPtr, animationId, loop, reverse); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + + +static FlMethodResponse* _stop_animation(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 animationId = (int)fl_value_get_int(fl_value_get_list_value(args, 1)); + stop_animation(assetPtr, animationId); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + 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 weightsValue = fl_value_get_list_value(args, 1); + float* const weights = (float* const) fl_value_get_float32_list(weightsValue); + size_t len = fl_value_get_length(weightsValue); + apply_weights(assetPtr, weights, (int)len); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + +static FlMethodResponse* _animate_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 weightsValue = fl_value_get_list_value(args, 1); + + float* const weights = (float* const) fl_value_get_float32_list(weightsValue); + int64_t numWeights = fl_value_get_int(fl_value_get_list_value(args, 2)); + int64_t numFrames = fl_value_get_int(fl_value_get_list_value(args, 3)); + float frameLengthInMs = fl_value_get_float(fl_value_get_list_value(args, 4)); + + animate_weights(assetPtr, weights, numWeights, numFrames, 1000.0f / frameLengthInMs); + + g_autoptr(FlValue) result = fl_value_new_string("OK"); + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} // Called when a method call is received from Flutter. static void polyvox_filament_plugin_handle_method_call( @@ -193,6 +382,50 @@ static void polyvox_filament_plugin_handle_method_call( response = _load_glb(self, method_call); } else if(strcmp(method, "getAnimationNames") == 0) { response = _get_animation_names(self, method_call); + } else if(strcmp(method, "clearAssets") == 0) { + clear_assets(self->_viewer); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + response = FL_METHOD_RESPONSE(fl_method_success_response_new(result)); + } else if(strcmp(method, "removeAsset") == 0) { + response = _remove_asset(self, method_call); + } else if(strcmp(method, "transformToUnitCube") == 0) { + response = _transform_to_unit_cube(self, method_call); + } else if(strcmp(method, "clearLights") == 0) { + clear_lights(self->_viewer); + g_autoptr(FlValue) result = fl_value_new_string("OK"); + response = FL_METHOD_RESPONSE(fl_method_success_response_new(result)); + } else if(strcmp(method, "panStart") == 0) { + response = _pan_start(self, method_call); + } else if(strcmp(method, "panEnd") == 0) { + response = _pan_end(self, method_call); + } else if(strcmp(method, "panUpdate") == 0) { + response = _pan_update(self, method_call); + } else if(strcmp(method, "rotateStart") == 0) { + response = _rotate_start(self, method_call); + } else if(strcmp(method, "rotateEnd") == 0) { + response = _rotate_end(self, method_call); + } else if(strcmp(method, "rotateUpdate") == 0) { + response = _rotate_update(self, method_call); + } else if(strcmp(method, "setCameraPosition") == 0) { + response = _set_camera_position(self, method_call); + } else if(strcmp(method, "setCameraRotation") == 0) { + response = _set_camera_rotation(self, method_call); + } else if(strcmp(method, "setRendering") == 0) { + response = _set_rendering(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, "playAnimation") == 0) { + response = _play_animation(self, method_call); + } else if(strcmp(method, "stopAnimation") == 0) { + response = _stop_animation(self, method_call); + } else if(strcmp(method, "applyWeights") == 0) { + response = _apply_weights(self, method_call); + } else if(strcmp(method, "animateWeights") == 0) { + response = _animate_weights(self, method_call); } else { response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); }