From a8a2f14b3435731e47cf77e032cd78c5134d0fd4 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 19 Mar 2025 23:22:19 +0800 Subject: [PATCH] refactoring --- .../lib/src/filament/src/filament_app.dart | 2 +- .../viewer/src/ffi/src/background_image.dart | 27 ++++++++-- .../src/viewer/src/ffi/src/ffi_camera.dart | 2 +- .../viewer/src/ffi/src/ffi_filament_app.dart | 49 +++++++++++-------- .../lib/src/viewer/src/ffi/src/ffi_view.dart | 6 +-- .../viewer/src/ffi/src/thermion_dart.g.dart | 33 ++++++++----- .../src/ffi/src/thermion_viewer_ffi.dart | 11 +++-- thermion_dart/native/include/c_api/TCamera.h | 5 +- .../c_api/ThermionDartRenderThreadApi.h | 4 +- thermion_dart/native/src/c_api/TCamera.cpp | 13 +++-- thermion_dart/native/src/c_api/TScene.cpp | 3 ++ thermion_dart/native/src/c_api/TView.cpp | 1 + .../src/c_api/ThermionDartRenderThreadApi.cpp | 6 ++- 13 files changed, 106 insertions(+), 56 deletions(-) diff --git a/thermion_dart/lib/src/filament/src/filament_app.dart b/thermion_dart/lib/src/filament/src/filament_app.dart index 5f17b5ed..0ff24665 100644 --- a/thermion_dart/lib/src/filament/src/filament_app.dart +++ b/thermion_dart/lib/src/filament/src/filament_app.dart @@ -227,7 +227,7 @@ abstract class FilamentApp { /// /// /// - Future capture(covariant View view); + Future capture(covariant View view, {bool captureRenderTarget = false}); /// /// diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart b/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart index 2023091f..fcd24076 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/background_image.dart @@ -25,6 +25,9 @@ class BackgroundImage extends ThermionAsset { BackgroundImage._( this.asset, this.scene, this.texture, this.sampler, this.mi); + /// + /// + /// Future destroy() async { Scene_removeEntity(scene.scene, entity); @@ -33,6 +36,9 @@ class BackgroundImage extends ThermionAsset { await mi.destroy(); } + /// + /// + /// static Future create( ThermionViewer viewer, FFIScene scene) async { var imageMaterialInstance = @@ -41,29 +47,40 @@ class BackgroundImage extends ThermionAsset { var backgroundImage = await viewer.createGeometry(GeometryHelper.fullscreenQuad()); await imageMaterialInstance.setParameterInt("showImage", 0); - await imageMaterialInstance.setParameterMat4("transform", Matrix4.identity()); - + await imageMaterialInstance.setParameterMat4( + "transform", Matrix4.identity()); + backgroundImage.setMaterialInstanceAt(imageMaterialInstance); await scene.add(backgroundImage as FFIAsset); return BackgroundImage._( backgroundImage, scene, null, null, imageMaterialInstance); } + /// + /// + /// Future setBackgroundColor(double r, double g, double b, double a) async { await mi.setParameterFloat4("backgroundColor", r, g, b, a); } + /// + /// + /// Future setImage(Uint8List imageData) async { final image = await FilamentApp.instance!.decodeImage(imageData); - texture ??= await FilamentApp.instance! - .createTexture(await image.getWidth(), await image.getHeight()); - + texture ??= await FilamentApp.instance!.createTexture( + await image.getWidth(), await image.getHeight(), + textureFormat: TextureFormat.RGBA32F); + await texture! + .setLinearImage(image, PixelDataFormat.RGBA, PixelDataType.FLOAT); sampler ??= await FilamentApp.instance!.createTextureSampler() as FFITextureSampler; await mi.setParameterTexture( "image", texture as FFITexture, sampler as FFITextureSampler); + await setBackgroundColor(1, 1, 1, 0); + await mi.setParameterInt("showImage", 1); } /// diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart index b02c86e6..53c9ba87 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart @@ -81,7 +81,7 @@ class FFICamera extends Camera { /// @override Future setModelMatrix(Matrix4 matrix) async { - Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix)); + Camera_setModelMatrix(camera, matrix.storage.address); } @override diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart index 286e9438..f22c43bb 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_filament_app.dart @@ -211,7 +211,7 @@ class FFIFilamentApp extends FilamentApp { TextureFormat textureFormat = TextureFormat.RGBA16F, int? importedTextureHandle}) async { var bitmask = flags.fold(0, (a, b) => a | b.value); - print("bitmask $bitmask"); + final texturePtr = await withPointerCallback((cb) { Texture_buildRenderThread( engine, @@ -247,24 +247,24 @@ class FFIFilamentApp extends FilamentApp { TextureCompareMode compareMode = TextureCompareMode.NONE, TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async { final samplerPtr = TextureSampler_create(); - TextureSampler_setMinFilter( - samplerPtr, TSamplerMinFilter.values[minFilter.index]); - TextureSampler_setMagFilter( - samplerPtr, TSamplerMagFilter.values[magFilter.index]); - TextureSampler_setWrapModeS( - samplerPtr, TSamplerWrapMode.values[wrapS.index]); - TextureSampler_setWrapModeT( - samplerPtr, TSamplerWrapMode.values[wrapT.index]); - TextureSampler_setWrapModeR( - samplerPtr, TSamplerWrapMode.values[wrapR.index]); - if (anisotropy > 0) { - TextureSampler_setAnisotropy(samplerPtr, anisotropy); - } + // TextureSampler_setMinFilter( + // samplerPtr, TSamplerMinFilter.values[minFilter.index]); + // TextureSampler_setMagFilter( + // samplerPtr, TSamplerMagFilter.values[magFilter.index]); + // TextureSampler_setWrapModeS( + // samplerPtr, TSamplerWrapMode.values[wrapS.index]); + // TextureSampler_setWrapModeT( + // samplerPtr, TSamplerWrapMode.values[wrapT.index]); + // TextureSampler_setWrapModeR( + // samplerPtr, TSamplerWrapMode.values[wrapR.index]); + // if (anisotropy > 0) { + // TextureSampler_setAnisotropy(samplerPtr, anisotropy); + // } - TextureSampler_setCompareMode( - samplerPtr, - TSamplerCompareMode.values[compareMode.index], - TSamplerCompareFunc.values[compareFunc.index]); + // TextureSampler_setCompareMode( + // samplerPtr, + // TSamplerCompareMode.values[compareMode.index], + // TSamplerCompareFunc.values[compareFunc.index]); return FFITextureSampler(samplerPtr); } @@ -555,11 +555,16 @@ class FFIFilamentApp extends FilamentApp { /// /// /// - Future capture(covariant FFIView view) async { + Future capture(covariant FFIView view, + {bool captureRenderTarget = false}) async { final viewport = await view.getViewport(); final swapChain = _viewMappings[view]; final out = Uint8List(viewport.width * viewport.height * 4); + await withVoidCallback((cb) { + Engine_flushAndWaitRenderThead(engine, cb); + }); + await withBoolCallback((cb) { Renderer_beginFrameRenderThread(renderer, swapChain!.swapChain, 0, cb); }); @@ -570,11 +575,15 @@ class FFIFilamentApp extends FilamentApp { cb, ); }); + + if (captureRenderTarget && view.renderTarget == null) { + throw Exception(); + } await withVoidCallback((cb) { Renderer_readPixelsRenderThread( renderer, view.view, - view.renderTarget?.renderTarget ?? nullptr, + captureRenderTarget ? view.renderTarget!.renderTarget : nullptr, TPixelDataFormat.PIXELDATAFORMAT_RGBA, TPixelDataType.PIXELDATATYPE_UBYTE, out.address, diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart index d76b5746..7b78446c 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart @@ -2,7 +2,6 @@ import 'package:thermion_dart/src/filament/src/scene.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart'; -import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart'; import 'package:thermion_dart/src/filament/src/layers.dart'; import 'package:thermion_dart/src/filament/src/shared_types.dart'; import 'callbacks.dart'; @@ -75,14 +74,15 @@ class FFIView extends View { @override Future setBloom(bool enabled, double strength) async { await withVoidCallback((cb) { - View_setBloomRenderThread(view, enabled, strength); + View_setBloomRenderThread(view, enabled, strength, cb); }); } @override Future setToneMapper(ToneMapper mapper) async { + await withVoidCallback((cb) => View_setToneMappingRenderThread( - view, app.engine, TToneMapping.values[mapper.index]); + view, app.engine, TToneMapping.values[mapper.index], cb)); } Future setStencilBufferEnabled(bool enabled) async { diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index 84d703cd..4fbadd1a 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -1165,12 +1165,6 @@ external void Camera_setExposure( double sensitivity, ); -@ffi.Native, double4x4)>(isLeaf: true) -external void Camera_setModelMatrix( - ffi.Pointer camera, - double4x4 matrix, -); - @ffi.Native)>(isLeaf: true) external double4x4 Camera_getModelMatrix( ffi.Pointer camera, @@ -1199,11 +1193,11 @@ external void Camera_getFrustum( ); @ffi.Native< - ffi.Void Function( - ffi.Pointer, double4x4, ffi.Double, ffi.Double)>(isLeaf: true) + ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Double, + ffi.Double)>(isLeaf: true) external void Camera_setProjectionMatrix( ffi.Pointer camera, - double4x4 matrix, + ffi.Pointer matrix, double near, double far, ); @@ -1271,6 +1265,13 @@ external void Camera_setCustomProjectionWithCulling( double far, ); +@ffi.Native, ffi.Pointer)>( + isLeaf: true) +external void Camera_setModelMatrix( + ffi.Pointer camera, + ffi.Pointer tModelMatrix, +); + @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) @@ -1938,31 +1939,39 @@ external void Material_createImageMaterialRenderThread( @ffi.Native< ffi.Void Function( - ffi.Pointer, ffi.Pointer, ffi.UnsignedInt)>( + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedInt, + ffi.Pointer>)>( symbol: "View_setToneMappingRenderThread", isLeaf: true) external void _View_setToneMappingRenderThread( ffi.Pointer tView, ffi.Pointer tEngine, int toneMapping, + ffi.Pointer> callback, ); void View_setToneMappingRenderThread( ffi.Pointer tView, ffi.Pointer tEngine, TToneMapping toneMapping, + ffi.Pointer> callback, ) => _View_setToneMappingRenderThread( tView, tEngine, toneMapping.value, + callback, ); -@ffi.Native, ffi.Bool, ffi.Double)>( - isLeaf: true) +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Bool, ffi.Double, + ffi.Pointer>)>(isLeaf: true) external void View_setBloomRenderThread( ffi.Pointer tView, bool enabled, double strength, + ffi.Pointer> callback, ); @ffi.Native< diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index 69da56ae..4565bb0f 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -234,6 +234,7 @@ class ThermionViewerFFI extends ThermionViewer { } Pointer? indirectLight; + Pointer? skybox; /// @@ -418,6 +419,8 @@ class ThermionViewerFFI extends ThermionViewer { _assets.add(thermionAsset); + await scene.add(thermionAsset); + return thermionAsset; } @@ -450,9 +453,10 @@ class ThermionViewerFFI extends ThermionViewer { @override Future destroyAsset(covariant FFIAsset asset) async { await scene.remove(asset); - - await withVoidCallback((cb) => SceneAsset_destroyRenderThread(asset.asset, cb)); - + + await withVoidCallback( + (cb) => SceneAsset_destroyRenderThread(asset.asset, cb)); + // if (asset.boundingBoxAsset != null) { // await asset.setBoundingBoxVisibility(false); // await withVoidCallback((callback) => @@ -786,5 +790,4 @@ class ThermionViewerFFI extends ThermionViewer { // gizmoEntities.toSet() // ..add(SceneAsset_getEntity(gizmo.cast()))); } - } diff --git a/thermion_dart/native/include/c_api/TCamera.h b/thermion_dart/native/include/c_api/TCamera.h index 6c3b2977..7a32a38b 100644 --- a/thermion_dart/native/include/c_api/TCamera.h +++ b/thermion_dart/native/include/c_api/TCamera.h @@ -16,13 +16,12 @@ enum TProjection { // Camera methods EMSCRIPTEN_KEEPALIVE void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity); -EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera *camera, double4x4 matrix); EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *const camera); EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera); EMSCRIPTEN_KEEPALIVE double4x4 Camera_getProjectionMatrix(TCamera *const camera); EMSCRIPTEN_KEEPALIVE double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera); EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *camera, double* out); -EMSCRIPTEN_KEEPALIVE void Camera_setProjectionMatrix(TCamera *camera, double4x4 matrix, double near, double far); +EMSCRIPTEN_KEEPALIVE void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far); EMSCRIPTEN_KEEPALIVE void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal); EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera); EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera); @@ -41,7 +40,7 @@ EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling( double near, double far ); -EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix); +EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix); EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength); EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera); EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right, diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index afdd81aa..79264ea0 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -77,8 +77,8 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *)); EMSCRIPTEN_KEEPALIVE void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *)); - EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, TToneMapping toneMapping); - EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength); + EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, TToneMapping toneMapping, void (*callback)()); + EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)()); EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)()); FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback); diff --git a/thermion_dart/native/src/c_api/TCamera.cpp b/thermion_dart/native/src/c_api/TCamera.cpp index df69ab14..2649319e 100644 --- a/thermion_dart/native/src/c_api/TCamera.cpp +++ b/thermion_dart/native/src/c_api/TCamera.cpp @@ -43,13 +43,14 @@ namespace thermion } EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *tCamera, double near, double far, double aspect, double focalLength) { + TRACE("Setting lens projection %f %f %f %f", near, far, aspect, focalLength); auto *camera = reinterpret_cast(tCamera); - camera->setLensProjection(near, far, aspect, focalLength); + camera->setLensProjection(focalLength, aspect, near, far); } - EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera *tCamera, double4x4 tModelMatrix) { + EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera *tCamera, double *tModelMatrix) { auto *camera = reinterpret_cast(tCamera); - auto modelMatrix = convert_double4x4_to_mat4(tModelMatrix); + auto modelMatrix = convert_double_to_mat4f(tModelMatrix); camera->setModelMatrix(modelMatrix); } @@ -65,6 +66,12 @@ namespace thermion return camera->getFocusDistance(); } + EMSCRIPTEN_KEEPALIVE double4x4 Camera_getProjectionMatrix(TCamera *const tCamera) { + auto *camera = reinterpret_cast(tCamera); + return convert_mat4_to_double4x4(camera->getProjectionMatrix()); + } + + EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *tCamera, float distance) { auto *camera = reinterpret_cast(tCamera); return camera->setFocusDistance(distance); diff --git a/thermion_dart/native/src/c_api/TScene.cpp b/thermion_dart/native/src/c_api/TScene.cpp index 24eaff91..0821a061 100644 --- a/thermion_dart/native/src/c_api/TScene.cpp +++ b/thermion_dart/native/src/c_api/TScene.cpp @@ -28,17 +28,20 @@ namespace thermion { auto *scene = reinterpret_cast(tScene); scene->addEntity(utils::Entity::import(entityId)); + TRACE("Added entity %d", entityId); } EMSCRIPTEN_KEEPALIVE void Scene_removeEntity(TScene* tScene, EntityId entityId) { auto *scene = reinterpret_cast(tScene); scene->remove(utils::Entity::import(entityId)); + TRACE("Removed entity %d", entityId); } EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *tSkybox) { auto *scene = reinterpret_cast(tScene); auto *skybox = reinterpret_cast(tSkybox); scene->setSkybox(skybox); + TRACE("Set skybox"); } EMSCRIPTEN_KEEPALIVE void Scene_setIndirectLight(TScene* tScene, TIndirectLight *tIndirectLight) { diff --git a/thermion_dart/native/src/c_api/TView.cpp b/thermion_dart/native/src/c_api/TView.cpp index feb4df0f..c3b1f9d0 100644 --- a/thermion_dart/native/src/c_api/TView.cpp +++ b/thermion_dart/native/src/c_api/TView.cpp @@ -32,6 +32,7 @@ using namespace filament; { auto view = reinterpret_cast(tView); view->setViewport({0, 0, width, height}); + TRACE("Set viewport to %dx%d", width, height); } EMSCRIPTEN_KEEPALIVE TRenderTarget *View_getRenderTarget(TView *tView) { diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index c6eae607..77eab3fa 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -427,22 +427,24 @@ extern "C" auto fut = _rl->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, TToneMapping toneMapping) + EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, TToneMapping toneMapping, void (*callback)()) { std::packaged_task lambda( [=] { View_setToneMapping(tView, tEngine, toneMapping); + callback(); }); auto fut = _rl->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength) + EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)()) { std::packaged_task lambda( [=] { View_setBloom(tView, enabled, strength); + callback(); }); auto fut = _rl->add_task(lambda); }