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 4f02f74c..05dc2348 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 @@ -1667,6 +1667,8 @@ class ThermionViewerFFI extends ThermionViewer { throw Exception("Failed to create geometry"); } + print(" is shadow caster : ${RenderableManager_isShadowCaster(_renderableManager!, SceneAsset_getEntity(assetPtr))} is shadow recevier : ${RenderableManager_isShadowReceiver(_renderableManager!, SceneAsset_getEntity(assetPtr))} " ); + var asset = FFIAsset( assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this); diff --git a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart index f35ebd11..2061b01b 100644 --- a/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart +++ b/thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart @@ -439,7 +439,7 @@ abstract class ThermionViewer { Future getMainCameraEntity(); /// - /// Returns the Camera instance for the main camera. + /// Returns the Camera instance for the main camera. /// Future getMainCamera(); @@ -460,7 +460,7 @@ abstract class ThermionViewer { Future setToneMapping(ToneMapper mapper); /// - /// Sets the strength of the bloom. + /// Sets the strength of the bloom (requires postprocessing). /// Future setBloom(double bloom); @@ -597,7 +597,7 @@ abstract class ThermionViewer { double viewportX, double viewportY, double x, double y, double z); /// - /// Enable/disable postprocessing effects (anti-aliasing, tone mapping). Disabled by default. + /// Enable/disable postprocessing effects (anti-aliasing, tone mapping, bloom). Disabled by default. /// Future setPostProcessing(bool enabled); diff --git a/thermion_dart/native/include/c_api/TLightManager.h b/thermion_dart/native/include/c_api/TLightManager.h index 9018eacc..a8e5f85a 100644 --- a/thermion_dart/native/include/c_api/TLightManager.h +++ b/thermion_dart/native/include/c_api/TLightManager.h @@ -11,7 +11,14 @@ extern "C" EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z); EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z); - + EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager, EntityId entity, int type); + EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity); + EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, double r, double g, double b); + EMSCRIPTEN_KEEPALIVE void LightManager_setIntensity(TLightManager *tLightManager, EntityId entity, double intensity); + EMSCRIPTEN_KEEPALIVE void LightManager_setFalloff(TLightManager *tLightManager, EntityId entity, double falloff); + EMSCRIPTEN_KEEPALIVE void LightManager_setSpotLightCone(TLightManager *tLightManager, EntityId entity, double inner, double outer); + EMSCRIPTEN_KEEPALIVE void LightManager_setShadowCaster(TLightManager *tLightManager, EntityId entity, bool enabled); + #ifdef __cplusplus } #endif diff --git a/thermion_dart/native/include/c_api/TRenderableManager.h b/thermion_dart/native/include/c_api/TRenderableManager.h index 031778f6..037efff2 100644 --- a/thermion_dart/native/include/c_api/TRenderableManager.h +++ b/thermion_dart/native/include/c_api/TRenderableManager.h @@ -8,11 +8,43 @@ extern "C" { #endif - EMSCRIPTEN_KEEPALIVE void RenderableManager_setMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex, TMaterialInstance *tMaterialInstance); - EMSCRIPTEN_KEEPALIVE void RenderableManager_setPriority(TRenderableManager *tRenderableManager, EntityId entityId, int priority); - EMSCRIPTEN_KEEPALIVE TMaterialInstance *RenderableManager_getMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex); - EMSCRIPTEN_KEEPALIVE bool RenderableManager_isRenderable(TRenderableManager *tRenderableManager, EntityId entityId); + EMSCRIPTEN_KEEPALIVE void RenderableManager_setMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex, TMaterialInstance *tMaterialInstance); + EMSCRIPTEN_KEEPALIVE void RenderableManager_setPriority(TRenderableManager *tRenderableManager, EntityId entityId, int priority); + EMSCRIPTEN_KEEPALIVE TMaterialInstance *RenderableManager_getMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex); + EMSCRIPTEN_KEEPALIVE bool RenderableManager_isRenderable(TRenderableManager *tRenderableManager, EntityId entityId); + + // New boolean methods + + /** + * Checks if the given entity has a renderable component + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_hasComponent(TRenderableManager *tRenderableManager, EntityId entityId); + + /** + * Returns true if this manager has no components + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_empty(TRenderableManager *tRenderableManager); + + /** + * Returns whether a light channel is enabled on a specified renderable + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_getLightChannel(TRenderableManager *tRenderableManager, EntityId entityId, unsigned int channel); + + /** + * Checks if the renderable can cast shadows + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowCaster(TRenderableManager *tRenderableManager, EntityId entityId); + + /** + * Checks if the renderable can receive shadows + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowReceiver(TRenderableManager *tRenderableManager, EntityId entityId); + + /** + * Returns whether large-scale fog is enabled for this renderable + */ + EMSCRIPTEN_KEEPALIVE bool RenderableManager_getFogEnabled(TRenderableManager *tRenderableManager, EntityId entityId); + #ifdef __cplusplus } -#endif - +#endif \ No newline at end of file diff --git a/thermion_dart/native/src/c_api/TLightManager.cpp b/thermion_dart/native/src/c_api/TLightManager.cpp index 7225b0e3..9edcd06d 100644 --- a/thermion_dart/native/src/c_api/TLightManager.cpp +++ b/thermion_dart/native/src/c_api/TLightManager.cpp @@ -1,33 +1,94 @@ - #include - #include #include "c_api/APIExport.h" #include "Log.hpp" - -extern "C" -{ - #include "c_api/TLightManager.h" - EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z) { - auto lightManager = reinterpret_cast(tLightManager); - auto instance = lightManager->getInstance(utils::Entity::import(light)); - if(!instance.isValid()) { - Log("Warning: invalid light instance"); - return; - } - lightManager->setPosition(instance, filament::math::float3 { x, y, z }); +extern "C" { + +EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z) { + auto lightManager = reinterpret_cast(tLightManager); + auto instance = lightManager->getInstance(utils::Entity::import(light)); + if (!instance.isValid()) { + Log("Warning: invalid light instance"); + return; + } + lightManager->setPosition(instance, filament::math::float3 { static_cast(x), static_cast(y), static_cast(z) }); +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z) { + auto lightManager = reinterpret_cast(tLightManager); + auto instance = lightManager->getInstance(utils::Entity::import(light)); + if (!instance.isValid()) { + Log("Warning: invalid light instance"); + return; + } + lightManager->setDirection(instance, filament::math::float3 { static_cast(x), static_cast(y), static_cast(z) }); +} + +EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TLightManager *tLightManager, EntityId entity, int type) { + auto* lm = reinterpret_cast(tLightManager); + filament::LightManager::Type lightType; + + switch (type) { + case 0: lightType = filament::LightManager::Type::SUN; break; + case 1: lightType = filament::LightManager::Type::DIRECTIONAL; break; + case 2: lightType = filament::LightManager::Type::POINT; break; + case 3: lightType = filament::LightManager::Type::FOCUSED_SPOT; break; + case 4: lightType = filament::LightManager::Type::SPOT; break; + default: return -1; } - EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z) { - auto lightManager = reinterpret_cast(tLightManager); - auto instance = lightManager->getInstance(utils::Entity::import(light)); - if(!instance.isValid()) { - Log("Warning: invalid light instance"); - return; - } - lightManager->setPosition(instance, filament::math::float3 { x, y, z }); + filament::LightManager::Builder builder(lightType); + return false; + // auto result = builder.build(*lm->getEngine(), utils::Entity::import(entity)); + // return result == filament::LightManager::Result::Success ? 0 : -1; +} + +EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) { + auto* lm = reinterpret_cast(tLightManager); + lm->destroy(utils::Entity::import(entity)); +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setColor(TLightManager *tLightManager, EntityId entity, double r, double g, double b) { + auto* lm = reinterpret_cast(tLightManager); + auto instance = lm->getInstance(utils::Entity::import(entity)); + if (instance.isValid()) { + lm->setColor(instance, {static_cast(r), static_cast(g), static_cast(b)}); } -} \ No newline at end of file +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setIntensity(TLightManager *tLightManager, EntityId entity, double intensity) { + auto* lm = reinterpret_cast(tLightManager); + auto instance = lm->getInstance(utils::Entity::import(entity)); + if (instance.isValid()) { + lm->setIntensity(instance, static_cast(intensity)); + } +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setFalloff(TLightManager *tLightManager, EntityId entity, double falloff) { + auto* lm = reinterpret_cast(tLightManager); + auto instance = lm->getInstance(utils::Entity::import(entity)); + if (instance.isValid()) { + lm->setFalloff(instance, static_cast(falloff)); + } +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setSpotLightCone(TLightManager *tLightManager, EntityId entity, double inner, double outer) { + auto* lm = reinterpret_cast(tLightManager); + auto instance = lm->getInstance(utils::Entity::import(entity)); + if (instance.isValid()) { + lm->setSpotLightCone(instance, static_cast(inner), static_cast(outer)); + } +} + +EMSCRIPTEN_KEEPALIVE void LightManager_setShadowCaster(TLightManager *tLightManager, EntityId entity, bool enabled) { + auto* lm = reinterpret_cast(tLightManager); + auto instance = lm->getInstance(utils::Entity::import(entity)); + if (instance.isValid()) { + lm->setShadowCaster(instance, enabled); + } +} + +} // extern "C" diff --git a/thermion_dart/native/src/c_api/TRenderableManager.cpp b/thermion_dart/native/src/c_api/TRenderableManager.cpp index c69ccc0c..cba4739a 100644 --- a/thermion_dart/native/src/c_api/TRenderableManager.cpp +++ b/thermion_dart/native/src/c_api/TRenderableManager.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -8,7 +7,6 @@ namespace thermion { - extern "C" { using namespace filament; @@ -47,5 +45,56 @@ namespace thermion auto renderableInstance = renderableManager->getInstance(entity); return renderableInstance.isValid(); } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_hasComponent(TRenderableManager *tRenderableManager, EntityId entityId) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + const auto &entity = utils::Entity::import(entityId); + return renderableManager->hasComponent(entity); + } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_empty(TRenderableManager *tRenderableManager) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + return renderableManager->empty(); + } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_getLightChannel(TRenderableManager *tRenderableManager, EntityId entityId, unsigned int channel) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + const auto &entity = utils::Entity::import(entityId); + auto renderableInstance = renderableManager->getInstance(entity); + if (!renderableInstance.isValid()) { + return false; + } + return renderableManager->getLightChannel(renderableInstance, channel); + } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowCaster(TRenderableManager *tRenderableManager, EntityId entityId) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + const auto &entity = utils::Entity::import(entityId); + auto renderableInstance = renderableManager->getInstance(entity); + if (!renderableInstance.isValid()) { + return false; + } + return renderableManager->isShadowCaster(renderableInstance); + } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_isShadowReceiver(TRenderableManager *tRenderableManager, EntityId entityId) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + const auto &entity = utils::Entity::import(entityId); + auto renderableInstance = renderableManager->getInstance(entity); + if (!renderableInstance.isValid()) { + return false; + } + return renderableManager->isShadowReceiver(renderableInstance); + } + + EMSCRIPTEN_KEEPALIVE bool RenderableManager_getFogEnabled(TRenderableManager *tRenderableManager, EntityId entityId) { + auto *renderableManager = reinterpret_cast(tRenderableManager); + const auto &entity = utils::Entity::import(entityId); + auto renderableInstance = renderableManager->getInstance(entity); + if (!renderableInstance.isValid()) { + return false; + } + return renderableManager->getFogEnabled(renderableInstance); + } } } \ No newline at end of file diff --git a/thermion_dart/native/src/scene/SceneManager.cpp b/thermion_dart/native/src/scene/SceneManager.cpp index f4c48fc6..c759d860 100644 --- a/thermion_dart/native/src/scene/SceneManager.cpp +++ b/thermion_dart/native/src/scene/SceneManager.cpp @@ -531,6 +531,9 @@ namespace thermion { auto light = EntityManager::get().create(); + // LightManager::ShadowOptions shadowOptions; + // shadowOptions.stable = true; + auto result = LightManager::Builder(t) .color(Color::cct(colour)) .intensity(intensity) @@ -541,6 +544,7 @@ namespace thermion .sunHaloFalloff(sunHaloFallof) .position(filament::math::float3(posX, posY, posZ)) .direction(filament::math::float3(dirX, dirY, dirZ)) + // .shadowOptions(shadowOptions) .castShadows(shadows) .build(*_engine, light); if (result != LightManager::Builder::Result::Success)