From d7edf105c490a4b43531cffc03733c356fd73289 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 21 May 2024 13:23:23 +0800 Subject: [PATCH] addLight now accepts a LightType enum; added support for setting falloff, spot light radius, sun radius & halo --- .../abstract_filament_viewer.dart | 38 ++++++++++++----- .../compatibility/native/dart_filament.g.dart | 24 +++++++++++ .../dart_filament/filament_viewer_impl.dart | 34 ++++++++++++--- .../native/include/DartFilamentApi.h | 19 ++++++++- .../native/include/DartFilamentFFIApi.h | 6 +++ .../native/include/FilamentViewer.hpp | 18 +++++++- dart_filament/native/src/DartFilamentApi.cpp | 37 +++++++++++++++- .../native/src/DartFilamentFFIApi.cpp | 42 ++++++++++++++++--- dart_filament/native/src/FilamentViewer.cpp | 36 +++++++++++++--- 9 files changed, 224 insertions(+), 30 deletions(-) diff --git a/dart_filament/lib/dart_filament/abstract_filament_viewer.dart b/dart_filament/lib/dart_filament/abstract_filament_viewer.dart index 693bae42..5bcbd84e 100644 --- a/dart_filament/lib/dart_filament/abstract_filament_viewer.dart +++ b/dart_filament/lib/dart_filament/abstract_filament_viewer.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:vector_math/vector_math_64.dart'; import 'dart:async'; import 'package:animation_tools_dart/animation_tools_dart.dart'; @@ -6,6 +8,15 @@ import 'package:dart_filament/dart_filament/entities/filament_entity.dart'; // "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates. typedef FilamentPickResult = ({FilamentEntity entity, double x, double y}); +enum LightType { + SUN, //!< Directional light that also draws a sun's disk in the sky. + DIRECTIONAL, //!< Directional light, emits light in a given direction. + POINT, //!< Point light, emits light from a position, in all directions. + FOCUSED_SPOT, //!< Physically correct spot light. + SPOT, +} + + // copied from filament/backened/DriverEnums.h enum PrimitiveType { // don't change the enums values (made to match GL) @@ -119,17 +130,13 @@ abstract class AbstractFilamentViewer { Future removeIbl(); /// - /// Adds a dynamic light to the scene. - /// copied from filament LightManager.h - /// enum class Type : uint8_t { - /// SUN, //!< Directional light that also draws a sun's disk in the sky. - /// DIRECTIONAL, //!< Directional light, emits light in a given direction. - /// POINT, //!< Point light, emits light from a position, in all directions. - /// FOCUSED_SPOT, //!< Physically correct spot light. - /// SPOT, //!< Spot light with coupling of outer cone and illumination disabled. - /// }; + /// Add a light to the scene. + /// See LightManager.h for details + /// Note that [sunAngularRadius] is in degrees, + /// whereas [spotLightConeInner] and [spotLightConeOuter] are in radians + /// Future addLight( - int type, + LightType type, double colour, double intensity, double posX, @@ -138,7 +145,16 @@ abstract class AbstractFilamentViewer { double dirX, double dirY, double dirZ, - bool castShadows); + { + double falloffRadius=1.0, + double spotLightConeInner=pi/8, + double spotLightConeOuter=pi/4, + double sunAngularRadius=0.545, + double sunHaloSize=10.0, + double sunHaloFallof=80.0, + bool castShadows=true + } + ); Future removeLight(FilamentEntity light); diff --git a/dart_filament/lib/dart_filament/compatibility/native/dart_filament.g.dart b/dart_filament/lib/dart_filament/compatibility/native/dart_filament.g.dart index 70e67217..fa3da1ea 100644 --- a/dart_filament/lib/dart_filament/compatibility/native/dart_filament.g.dart +++ b/dart_filament/lib/dart_filament/compatibility/native/dart_filament.g.dart @@ -163,6 +163,12 @@ external void remove_ibl( ffi.Float, ffi.Float, ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, ffi.Bool)>( symbol: 'add_light', assetId: 'package:dart_filament/dart_filament.dart') external int add_light( @@ -176,6 +182,12 @@ external int add_light( double dirX, double dirY, double dirZ, + double falloffRadius, + double spotLightConeInner, + double spotLightConeOuter, + double sunAngularRadius, + double sunHaloSize, + double sunHaloFallof, bool shadows, ); @@ -1307,6 +1319,12 @@ external void remove_ibl_ffi( ffi.Float, ffi.Float, ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, ffi.Bool, ffi.Pointer>)>( symbol: 'add_light_ffi', @@ -1322,6 +1340,12 @@ external void add_light_ffi( double dirX, double dirY, double dirZ, + double falloffRadius, + double spotLightConeInner, + double spotLightConeOuter, + double sunAngularRadius, + double sunHaloSize, + double sunHaloFallof, bool shadows, ffi.Pointer> callback, ); diff --git a/dart_filament/lib/dart_filament/filament_viewer_impl.dart b/dart_filament/lib/dart_filament/filament_viewer_impl.dart index 9006a932..d494e66a 100644 --- a/dart_filament/lib/dart_filament/filament_viewer_impl.dart +++ b/dart_filament/lib/dart_filament/filament_viewer_impl.dart @@ -1,8 +1,10 @@ import 'dart:async'; import 'dart:ffi'; import 'dart:io'; +import 'dart:math'; import 'package:animation_tools_dart/animation_tools_dart.dart'; import 'package:dart_filament/dart_filament/entities/filament_entity.dart'; +import 'package:dart_filament/dart_filament/entities/gizmo.dart'; import 'package:vector_math/vector_math_64.dart'; import 'abstract_filament_viewer.dart'; @@ -100,6 +102,9 @@ class FilamentViewer extends AbstractFilamentViewer { }); } + Gizmo? _gizmo; + Gizmo? get gizmo => _gizmo; + Future _initialize() async { final uberarchivePtr = uberArchivePath?.toNativeUtf8(allocator: allocator).cast() ?? @@ -119,6 +124,11 @@ class FilamentViewer extends AbstractFilamentViewer { _scene = SceneImpl(this); await setCameraManipulatorOptions(zoomSpeed: 10.0); + + final out = calloc(3); + get_gizmo(_sceneManager!, out); + _gizmo = Gizmo(out[0], out[1], out[2], this); + calloc.free(out); this._initialized.complete(true); } @@ -217,7 +227,7 @@ class FilamentViewer extends AbstractFilamentViewer { @override Future addLight( - int type, + LightType type, double colour, double intensity, double posX, @@ -226,10 +236,16 @@ class FilamentViewer extends AbstractFilamentViewer { double dirX, double dirY, double dirZ, - bool castShadows) async { + {double falloffRadius = 1.0, + double spotLightConeInner = pi / 8, + double spotLightConeOuter = pi / 4, + double sunAngularRadius = 0.545, + double sunHaloSize = 10.0, + double sunHaloFallof = 80.0, + bool castShadows = true}) async { var entity = await withIntCallback((callback) => add_light_ffi( _viewer!, - type, + type.index, colour, intensity, posX, @@ -238,8 +254,17 @@ class FilamentViewer extends AbstractFilamentViewer { dirX, dirY, dirZ, + falloffRadius, + spotLightConeInner, + spotLightConeOuter, + sunAngularRadius = 0.545, + sunHaloSize = 10.0, + sunHaloFallof = 80.0, castShadows, callback)); + if (entity == _FILAMENT_ASSET_ERROR) { + throw Exception("Failed to add light to scene"); + } _scene.registerLight(entity); return entity; @@ -1144,6 +1169,5 @@ class FilamentViewer extends AbstractFilamentViewer { set_priority(_sceneManager!, entityId, priority); } - @override - AbstractGizmo? get gizmo => null; + } diff --git a/dart_filament/native/include/DartFilamentApi.h b/dart_filament/native/include/DartFilamentApi.h index 6bf9c67e..e4c76873 100644 --- a/dart_filament/native/include/DartFilamentApi.h +++ b/dart_filament/native/include/DartFilamentApi.h @@ -71,7 +71,24 @@ extern "C" EMSCRIPTEN_KEEPALIVE void rotate_ibl(const void *const viewer, float *rotationMatrix); EMSCRIPTEN_KEEPALIVE void remove_skybox(const void *const viewer); EMSCRIPTEN_KEEPALIVE void remove_ibl(const void *const viewer); - EMSCRIPTEN_KEEPALIVE EntityId add_light(const void *const viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows); + EMSCRIPTEN_KEEPALIVE EntityId add_light( + const void *const viewer, + uint8_t type, + float colour, + float intensity, + float posX, + float posY, + float posZ, + float dirX, + float dirY, + float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, + bool shadows); EMSCRIPTEN_KEEPALIVE void remove_light(const void *const viewer, EntityId entityId); EMSCRIPTEN_KEEPALIVE void clear_lights(const void *const viewer); EMSCRIPTEN_KEEPALIVE EntityId load_glb(void *sceneManager, const char *assetPath, int numInstances); diff --git a/dart_filament/native/include/DartFilamentFFIApi.h b/dart_filament/native/include/DartFilamentFFIApi.h index cdfa77a5..f4a144f9 100644 --- a/dart_filament/native/include/DartFilamentFFIApi.h +++ b/dart_filament/native/include/DartFilamentFFIApi.h @@ -54,6 +54,12 @@ extern "C" float dirX, float dirY, float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, bool shadows, void (*callback)(EntityId)); EMSCRIPTEN_KEEPALIVE void remove_light_ffi(void *const viewer, EntityId entityId); diff --git a/dart_filament/native/include/FilamentViewer.hpp b/dart_filament/native/include/FilamentViewer.hpp index 8d1b4e41..5ef235c9 100644 --- a/dart_filament/native/include/FilamentViewer.hpp +++ b/dart_filament/native/include/FilamentViewer.hpp @@ -127,7 +127,23 @@ namespace flutter_filament void scrollEnd(); void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y)); - EntityId addLight(LightManager::Type t, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows); + EntityId addLight( + LightManager::Type t, + float colour, + float intensity, + float posX, + float posY, + float posZ, + float dirX, + float dirY, + float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, + bool shadows); void removeLight(EntityId entityId); void clearLights(); void setPostProcessing(bool enabled); diff --git a/dart_filament/native/src/DartFilamentApi.cpp b/dart_filament/native/src/DartFilamentApi.cpp index 094f6ab8..29142371 100644 --- a/dart_filament/native/src/DartFilamentApi.cpp +++ b/dart_filament/native/src/DartFilamentApi.cpp @@ -99,9 +99,42 @@ extern "C" ((FilamentViewer *)viewer)->removeIbl(); } - EntityId add_light(const void *const viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows) + EntityId add_light( + const void *const viewer, + uint8_t type, + float colour, + float intensity, + float posX, + float posY, + float posZ, + float dirX, + float dirY, + float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, + bool shadows) { - return ((FilamentViewer *)viewer)->addLight((LightManager::Type)type, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, shadows); + return ((FilamentViewer *)viewer)->addLight( + (LightManager::Type)type, + colour, + intensity, + posX, + posY, + posZ, + dirX, + dirY, + dirZ, + falloffRadius, + spotLightConeInner, + spotLightConeOuter, + sunAngularRadius, + sunHaloSize, + sunHaloFallof, + shadows); } EMSCRIPTEN_KEEPALIVE void remove_light(const void *const viewer, int32_t entityId) diff --git a/dart_filament/native/src/DartFilamentFFIApi.cpp b/dart_filament/native/src/DartFilamentFFIApi.cpp index 77afef01..3b04925d 100644 --- a/dart_filament/native/src/DartFilamentFFIApi.cpp +++ b/dart_filament/native/src/DartFilamentFFIApi.cpp @@ -480,14 +480,46 @@ extern "C" auto fut = _rl->add_task(lambda); } - void add_light_ffi(void *const viewer, uint8_t type, float colour, - float intensity, float posX, float posY, float posZ, - float dirX, float dirY, float dirZ, bool shadows, void (*callback)(EntityId)) + void add_light_ffi( + void *const viewer, + uint8_t type, + float colour, + float intensity, + float posX, + float posY, + float posZ, + float dirX, + float dirY, + float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, + bool shadows, + void (*callback)(EntityId)) { std::packaged_task lambda([=] { - auto entity = add_light(viewer, type, colour, intensity, posX, posY, posZ, dirX, - dirY, dirZ, shadows); + auto entity = add_light( + viewer, + type, + colour, + intensity, + posX, + posY, + posZ, + dirX, + dirY, + dirZ, + falloffRadius, + spotLightConeInner, + spotLightConeOuter, + sunAngularRadius, + sunHaloSize, + sunHaloFallof, + shadows); #ifdef __EMSCRIPTEN__ MAIN_THREAD_EM_ASM({ moduleArg.dartFilamentResolveCallback($0, $1); diff --git a/dart_filament/native/src/FilamentViewer.cpp b/dart_filament/native/src/FilamentViewer.cpp index e8c79a29..1bd7680d 100644 --- a/dart_filament/native/src/FilamentViewer.cpp +++ b/dart_filament/native/src/FilamentViewer.cpp @@ -317,26 +317,52 @@ namespace flutter_filament Log("Set frame interval to %f", frameInterval); } - int32_t FilamentViewer::addLight(LightManager::Type t, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows) + EntityId FilamentViewer::addLight( + LightManager::Type t, + float colour, + float intensity, + float posX, + float posY, + float posZ, + float dirX, + float dirY, + float dirZ, + float falloffRadius, + float spotLightConeInner, + float spotLightConeOuter, + float sunAngularRadius, + float sunHaloSize, + float sunHaloFallof, + bool shadows) { auto light = EntityManager::get().create(); auto &transformManager = _engine->getTransformManager(); transformManager.create(light); auto parent = transformManager.getInstance(light); - auto builder = LightManager::Builder(t) + + auto result = LightManager::Builder(t) .color(Color::cct(colour)) .intensity(intensity) + .falloff(falloffRadius) + .spotLightCone(spotLightConeInner, spotLightConeOuter) + .sunAngularRadius(sunAngularRadius) + .sunHaloSize(sunHaloSize) + .sunHaloFalloff(sunHaloFallof) .position(math::float3(posX, posY, posZ)) .direction(math::float3(dirX, dirY, dirZ)) .castShadows(shadows) .build(*_engine, light); - _scene->addEntity(light); - _lights.push_back(light); + if(result != LightManager::Builder::Result::Success) { + Log("ERROR : failed to create light"); + } else { + _scene->addEntity(light); + _lights.push_back(light); + } auto entityId = Entity::smuggle(light); auto transformInstance = transformManager.getInstance(light); transformManager.setTransform(transformInstance, math::mat4::translation(math::float3{posX, posY, posZ})); - Log("Added light under entity ID %d of type %d with colour %f intensity %f at (%f, %f, %f) with direction (%f, %f, %f) with shadows %d", entityId, t, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, shadows); + // Log("Added light under entity ID %d of type %d with colour %f intensity %f at (%f, %f, %f) with direction (%f, %f, %f) with shadows %d", entityId, t, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, shadows); return entityId; }