From 25ada92574f32ad9309992bef56ba82cfe965b71 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 13 May 2025 22:36:17 +0800 Subject: [PATCH] add View_pickRenderThread method (only used in WASM builds so we can proxy the callback to the main thread --- .../filament/src/implementation/ffi_view.dart | 40 +++++++++---------- .../c_api/ThermionDartRenderThreadApi.h | 1 + .../src/c_api/ThermionDartRenderThreadApi.cpp | 7 ++++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart index 9bbce28a..7c4dcbb6 100644 --- a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart +++ b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart @@ -1,7 +1,6 @@ import 'dart:async'; -import 'dart:math'; - import 'package:logging/logging.dart'; +import 'package:thermion_dart/src/bindings/src/js_interop.dart'; import 'package:thermion_dart/src/filament/src/interface/scene.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart'; @@ -11,7 +10,6 @@ import 'package:thermion_dart/thermion_dart.dart'; import 'ffi_camera.dart'; class FFIView extends View { - late final _logger = Logger(this.runtimeType.toString()); int _renderOrder = 0; int get renderOrder => _renderOrder; @@ -26,15 +24,13 @@ class FFIView extends View { late CallbackHolder _onPickResultHolder; - FFIView(this.view, this.app) { final renderTargetPtr = View_getRenderTarget(view); if (renderTargetPtr != nullptr) { renderTarget = FFIRenderTarget(renderTargetPtr, app); } - - _onPickResultHolder = - _onPickResult.asCallback(); + + _onPickResultHolder = _onPickResult.asCallback(); } /// @@ -113,8 +109,8 @@ class FFIView extends View { @override Future setBloom(bool enabled, double strength) async { - await withVoidCallback((requestId,cb) { - View_setBloomRenderThread(view, enabled, strength, requestId,cb); + await withVoidCallback((requestId, cb) { + View_setBloomRenderThread(view, enabled, strength, requestId, cb); }); } @@ -174,27 +170,30 @@ class FFIView extends View { } int _pickRequestId = -1; - + static int kMaxPickRequests = 1024; - final _pickRequests = List<({void Function(PickResult) handler, int x, int y})?>.generate(kMaxPickRequests, (idx) => null); - - + final _pickRequests = + List<({void Function(PickResult) handler, int x, int y})?>.generate( + kMaxPickRequests, (idx) => null); + /// /// /// @override Future pick(int x, int y, void Function(PickResult) resultHandler) async { - _pickRequestId = max(_pickRequestId + 1, kMaxPickRequests); - + _pickRequestId++; + var pickRequestId = _pickRequestId; + _pickRequests[_pickRequestId % kMaxPickRequests] = (handler: resultHandler, x: x, y: y); - var pickRequestId = _pickRequestId; + var viewport = await getViewport(); y = viewport.height - y; - - View_pick( - view, pickRequestId, x, y, _onPickResultHolder.pointer); - + if (FILAMENT_WASM) { + View_pickRenderThread(view, pickRequestId, x, y, _onPickResultHolder.pointer); + } else { + View_pick(view, pickRequestId, x, y, _onPickResultHolder.pointer); + } } void _onPickResult(int requestId, ThermionEntity entityId, double depth, @@ -220,5 +219,4 @@ class FFIView extends View { fragZ: fragZ, )); } - } diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index 34cac45c..fb8799bc 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -87,6 +87,7 @@ namespace thermion void Material_createGizmoMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *)); void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *)); + void View_pickRenderThread(TView *tView, uint32_t requestId, uint32_t x, uint32_t y, PickCallback callback); void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, uint32_t requestId, VoidCallback onComplete); void View_setBloomRenderThread(TView *tView, bool enabled, double strength, uint32_t requestId, VoidCallback onComplete); void View_setCameraRenderThread(TView *tView, TCamera *tCamera, uint32_t requestId, VoidCallback onComplete); diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index 1ab23cc6..fce6a651 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -554,6 +554,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread( auto fut = _renderThread->add_task(lambda); } + EMSCRIPTEN_KEEPALIVE void View_pickRenderThread(TView *tView, uint32_t requestId, uint32_t x, uint32_t y, PickCallback callback) { + auto *view = reinterpret_cast(tView); + view->pick(x, y, [=](filament::View::PickingQueryResult const &result) { + PROXY(callback(requestId, utils::Entity::smuggle(result.renderable), result.depth, result.fragCoords.x, result.fragCoords.y, result.fragCoords.z)); + }); + } + EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, uint32_t requestId, VoidCallback onComplete) { std::packaged_task lambda(