refactor!: move light methods from FilamentViewer to SceneManager/TLightManager and rename clearLights/clearAssets to destroyLights/destroyAssets

This commit is contained in:
Nick Fisher
2025-01-04 14:43:37 +08:00
parent 3e181b6aff
commit baf86d1ade
21 changed files with 355 additions and 272 deletions

View File

@@ -29,6 +29,7 @@ class ThermionViewerFFI extends ThermionViewer {
Pointer<TMaterialProvider>? _unlitMaterialProvider;
Pointer<TMaterialProvider>? _ubershaderMaterialProvider;
Pointer<TTransformManager>? _transformManager;
Pointer<TLightManager>? _lightManager;
Pointer<TRenderableManager>? _renderableManager;
Pointer<TViewer>? _viewer;
Pointer<TAnimationManager>? _animationManager;
@@ -197,6 +198,7 @@ class ThermionViewerFFI extends ThermionViewer {
SceneManager_getUbershaderMaterialProvider(_sceneManager!);
_engine = Viewer_getEngine(_viewer!);
_transformManager = Engine_getTransformManager(_engine!);
_lightManager = Engine_getLightManager(_engine!);
_animationManager = SceneManager_getAnimationManager(_sceneManager!);
_nameComponentManager =
SceneManager_getNameComponentManager(_sceneManager!);
@@ -284,11 +286,11 @@ class ThermionViewerFFI extends ThermionViewer {
}
_disposing = true;
await setRendering(false);
await clearEntities();
await destroyAssets();
for (final mInstance in _materialInstances) {
await mInstance.dispose();
}
await clearLights();
await destroyLights();
Viewer_destroyOnRenderThread(_viewer!);
_sceneManager = null;
@@ -450,8 +452,8 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
var entity = add_light(
_viewer!,
var entity = SceneManager_addLight(
_sceneManager!,
directLight.type.index,
directLight.color,
directLight.intensity,
@@ -480,15 +482,15 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future removeLight(ThermionEntity entity) async {
remove_light(_viewer!, entity);
SceneManager_removeLight(_sceneManager!, entity);
}
///
///
///
@override
Future clearLights() async {
clear_lights(_viewer!);
Future destroyLights() async {
SceneManager_destroyLights(_sceneManager!);
}
///
@@ -987,7 +989,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
@override
Future clearEntities() async {
Future destroyAssets() async {
await withVoidCallback((callback) {
SceneManager_destroyAllRenderThread(_sceneManager!, callback);
});
@@ -1314,7 +1316,7 @@ class ThermionViewerFFI extends ThermionViewer {
@override
Future setLightPosition(
ThermionEntity lightEntity, double x, double y, double z) async {
set_light_position(_viewer!, lightEntity, x, y, z);
LightManager_setPosition(_lightManager!, lightEntity, x, y, z);
}
///
@@ -1324,8 +1326,8 @@ class ThermionViewerFFI extends ThermionViewer {
Future setLightDirection(
ThermionEntity lightEntity, Vector3 direction) async {
direction.normalize();
set_light_direction(
_viewer!, lightEntity, direction.x, direction.y, direction.z);
LightManager_setPosition(
_lightManager!, lightEntity, direction.x, direction.y, direction.z);
}
///

View File

@@ -206,7 +206,7 @@ abstract class ThermionViewer {
///
/// Remove all lights (excluding IBL) from the scene.
///
Future clearLights();
Future destroyLights();
///
/// Load the .glb asset at the given path, adding all entities to the scene.
@@ -386,7 +386,7 @@ abstract class ThermionViewer {
/// Removes/destroys all renderable entities from the scene (including cameras).
/// All [ThermionEntity] handles will no longer be valid after this method is called; ensure you immediately discard all references to all entities once this method is complete.
///
Future clearEntities();
Future destroyAssets();
///
/// Schedules the glTF animation at [index] in [asset] to start playing on the next frame.

View File

@@ -55,14 +55,14 @@ class ThermionViewerStub extends ThermionViewer {
}
@override
Future clearEntities() {
// TODO: implement clearEntities
Future destroyAssets() {
// TODO: implement destroyAssets
throw UnimplementedError();
}
@override
Future clearLights() {
// TODO: implement clearLights
Future destroyLights() {
// TODO: implement destroyLights
throw UnimplementedError();
}
@@ -1008,8 +1008,8 @@ class ThermionViewerStub extends ThermionViewer {
}
@override
Future removeEntity(ThermionAsset asset) {
// TODO: implement removeEntity
Future removeAsset(ThermionAsset asset) {
// TODO: implement removeAsset
throw UnimplementedError();
}
@@ -1074,8 +1074,8 @@ class ThermionViewerStub extends ThermionViewer {
}
@override
Future removeEntityFromScene(ThermionEntity entity) {
// TODO: implement removeEntityFromScene
Future removeAssetFromScene(ThermionEntity entity) {
// TODO: implement removeAssetFromScene
throw UnimplementedError();
}

View File

@@ -131,7 +131,7 @@
// JSPromise removeLight(ThermionEntity light) => viewer.removeLight(light).toJS;
// @JSExport()
// JSPromise clearLights() => viewer.clearLights().toJS;
// JSPromise destroyLights() => viewer.destroyLights().toJS;
// @JSExport()
// JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
@@ -319,12 +319,12 @@
// }
// @JSExport()
// JSPromise removeEntity(ThermionEntity entity) =>
// viewer.removeEntity(entity).toJS;
// JSPromise removeAsset(ThermionEntity entity) =>
// viewer.removeAsset(entity).toJS;
// @JSExport()
// JSPromise clearEntities() {
// return viewer.clearEntities().toJS;
// JSPromise destroyAssets() {
// return viewer.destroyAssets().toJS;
// }
// @JSExport()

View File

@@ -161,8 +161,8 @@
// }
// @override
// Future<void> clearLights() async {
// await _shim.clearLights().toDart;
// Future<void> destroyLights() async {
// await _shim.destroyLights().toDart;
// }
// @override
@@ -339,13 +339,13 @@
// }
// @override
// Future<void> removeEntity(ThermionEntity entity) async {
// await _shim.removeEntity(entity).toDart;
// Future<void> removeAsset(ThermionEntity entity) async {
// await _shim.removeAsset(entity).toDart;
// }
// @override
// Future<void> clearEntities() async {
// await _shim.clearEntities().toDart;
// Future<void> destroyAssets() async {
// await _shim.destroyAssets().toDart;
// }
// @override

View File

@@ -81,8 +81,8 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
@JS('removeLight')
external JSPromise removeLight(ThermionEntity light);
@JS('clearLights')
external JSPromise clearLights();
@JS('destroyLights')
external JSPromise destroyLights();
@JS('loadGlb')
external JSPromise<JSNumber> loadGlb(String path, int numInstances);
@@ -164,11 +164,11 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
JSNumber fadeOutInSecs,
JSNumber maxDelta);
@JS('removeEntity')
external JSPromise removeEntity(ThermionEntity entity);
@JS('removeAsset')
external JSPromise removeAsset(ThermionEntity entity);
@JS('clearEntities')
external JSPromise clearEntities();
@JS('destroyAssets')
external JSPromise destroyAssets();
@JS('zoomBegin')
external JSPromise zoomBegin();

View File

@@ -99,27 +99,7 @@ namespace thermion
return _engine;
}
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 setLightPosition(EntityId entityId, float x, float y, float z);
void setLightDirection(EntityId entityId, float x, float y, float z);
void removeLight(EntityId entityId);
void clearLights();
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)());
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)());
@@ -152,7 +132,6 @@ namespace thermion
std::mutex _renderMutex; // mutex to ensure thread safety when removing assets
std::vector<utils::Entity> _lights;
Texture *_skyboxTexture = nullptr;
Skybox *_skybox = nullptr;
Texture *_iblTexture = nullptr;

View File

@@ -7,12 +7,15 @@ extern "C"
#include <stdint.h>
#include "APIExport.h"
typedef int32_t EntityId;
typedef struct TCamera TCamera;
typedef struct TEngine TEngine;
typedef struct TEntityManager TEntityManager;
typedef struct TViewer TViewer;
typedef struct TSceneManager TSceneManager;
typedef struct TLightManager TLightManager;
typedef struct TRenderTarget TRenderTarget;
typedef struct TSwapChain TSwapChain;
typedef struct TView TView;
@@ -91,6 +94,7 @@ extern "C"
} ;
typedef struct TMaterialKey TMaterialKey;
typedef struct {
double x;
double y;

View File

@@ -0,0 +1,17 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "APIExport.h"
#include "TMaterialInstance.h"
#ifdef __cplusplus
extern "C"
{
#endif
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);
#ifdef __cplusplus
}
#endif

View File

@@ -2,6 +2,7 @@
#pragma once
#include <utils/Entity.h>
#include "APIExport.h"
#include "APIBoundaryTypes.h"

View File

@@ -51,13 +51,35 @@ extern "C"
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGlbFromBuffer(TSceneManager *tSceneManager, const uint8_t *const, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGlb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_addLight(
TSceneManager *tSceneManager,
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 SceneManager_removeLight(TSceneManager *tSceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyLights(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAssets(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAll(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE TAnimationManager *SceneManager_getAnimationManager(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAll(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE TNameComponentManager *SceneManager_getNameComponentManager(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGrid(TSceneManager *tSceneManager, TMaterial *tMaterial);
EMSCRIPTEN_KEEPALIVE bool SceneManager_isGridEntity(TSceneManager *tSceneManager, EntityId entityId);

View File

@@ -48,6 +48,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId);
EMSCRIPTEN_KEEPALIVE TTransformManager *Engine_getTransformManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE TRenderableManager *Engine_getRenderableManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE TLightManager *Engine_getLightManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
@@ -65,28 +66,6 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void rotate_ibl(TViewer *viewer, float *rotationMatrix);
EMSCRIPTEN_KEEPALIVE void remove_skybox(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void remove_ibl(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE EntityId add_light(
TViewer *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(TViewer *viewer, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void clear_lights(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, EntityId light, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, EntityId light, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);

View File

@@ -6,8 +6,11 @@
#include <map>
#include <set>
#include <filament/Scene.h>
#include <filament/Camera.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include <filament/LightManager.h>
#include <filament/Scene.h>
#include <filament/View.h>
#include <gltfio/AssetLoader.h>
@@ -15,8 +18,6 @@
#include <gltfio/FilamentInstance.h>
#include <gltfio/ResourceLoader.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include <utils/NameComponentManager.h>
#include "tsl/robin_map.h"
@@ -92,6 +93,30 @@ namespace thermion
/// @return
SceneAsset* loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false, bool addToScene = true);
/// @brief Destroys all assets and instances.
///
utils::Entity addLight(
filament::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);
/// @brief Removes/destroys the light.
///
void removeLight(utils::Entity entity);
///
/// Creates an instance of the given entity.
/// This may return an instance from a pool of inactive instances; see [remove] for more information.
@@ -106,10 +131,18 @@ namespace thermion
/// @param entity
void destroy(SceneAsset* entity);
/// @brief Destroys all assets, scenes, materials, etc.
/// @brief Destroys all lights.
///
void destroyAll();
void destroyLights();
/// @brief Destroys all assets and instances.
///
void destroyAssets();
/// @brief Destroys all assets/instances, scenes, materials, etc.
///
void destroyAll();
/// @brief
/// @param entityId
void transformToUnitCube(EntityId entityId);
@@ -336,6 +369,7 @@ namespace thermion
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
std::set<Texture *> _textures;
std::vector<Camera *> _cameras;
std::vector<utils::Entity> _lights;
std::vector<std::unique_ptr<SceneAsset>> _sceneAssets;
std::vector<std::unique_ptr<Gizmo>> _gizmos;

View File

@@ -52,7 +52,6 @@
#include <filament/Viewport.h>
#include <filament/RenderableManager.h>
#include <filament/LightManager.h>
#include <gltfio/Animator.h>
#include <gltfio/AssetLoader.h>
@@ -99,12 +98,6 @@
#include "TimeIt.hpp"
#include "UnprojectTexture.hpp"
namespace filament
{
class IndirectLight;
class LightManager;
} // namespace filament
namespace thermion
{
@@ -191,107 +184,6 @@ namespace thermion
_renderer->setFrameRateOptions(fro);
}
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 result = LightManager::Builder(t)
.color(Color::cct(colour))
.intensity(intensity)
.falloff(falloffRadius)
.spotLightCone(spotLightConeInner, spotLightConeOuter)
.sunAngularRadius(sunAngularRadius)
.sunHaloSize(sunHaloSize)
.sunHaloFalloff(sunHaloFallof)
.position(filament::math::float3(posX, posY, posZ))
.direction(filament::math::float3(dirX, dirY, dirZ))
.castShadows(shadows)
.build(*_engine, light);
if (result != LightManager::Builder::Result::Success)
{
Log("ERROR : failed to create light");
}
else
{
_scene->addEntity(light);
_lights.push_back(light);
}
return Entity::smuggle(light);
}
void FilamentViewer::setLightPosition(EntityId entityId, float x, float y, float z)
{
auto light = Entity::import(entityId);
if (light.isNull())
{
Log("Light not found for entity %d", entityId);
return;
}
auto &lm = _engine->getLightManager();
auto instance = lm.getInstance(light);
lm.setPosition(instance, filament::math::float3{x, y, z});
}
void FilamentViewer::setLightDirection(EntityId entityId, float x, float y, float z)
{
auto light = Entity::import(entityId);
if (light.isNull())
{
Log("Light not found for entity %d", entityId);
return;
}
auto &lm = _engine->getLightManager();
auto instance = lm.getInstance(light);
lm.setDirection(instance, filament::math::float3{x, y, z});
}
void FilamentViewer::removeLight(EntityId entityId)
{
auto entity = utils::Entity::import(entityId);
if (entity.isNull())
{
Log("Error: light entity not found under ID %d", entityId);
}
else
{
auto removed = remove(_lights.begin(), _lights.end(), entity);
_scene->remove(entity);
EntityManager::get().destroy(1, &entity);
}
}
void FilamentViewer::clearLights()
{
_scene->removeEntities(_lights.data(), _lights.size());
EntityManager::get().destroy(_lights.size(), _lights.data());
_lights.clear();
}
static bool endsWith(std::string path, std::string ending)
{
return path.compare(path.length() - ending.length(), ending.length(), ending) == 0;
@@ -630,7 +522,8 @@ namespace thermion
FilamentViewer::~FilamentViewer()
{
clearLights();
_sceneManager->destroyAll();
for (auto view : _views)
{
@@ -952,7 +845,7 @@ namespace thermion
_iblTexture->setImage(*_engine, 0, std::move(pbd));
_indirectLight = IndirectLight::Builder()
_indirectLight = filament::IndirectLight::Builder()
.reflections(_iblTexture)
.intensity(intensity)
.build(*_engine);
@@ -995,7 +888,7 @@ namespace thermion
delete rb;
delete vec; },
callbackData);
_indirectLight = IndirectLight::Builder()
_indirectLight = filament::IndirectLight::Builder()
.reflections(_iblTexture)
.irradiance(3, harmonics)
.intensity(intensity)

View File

@@ -0,0 +1,33 @@
#include <filament/LightManager.h>
#include <utils/Entity.h>
#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<filament::LightManager*>(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 });
}
EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z) {
auto lightManager = reinterpret_cast<filament::LightManager*>(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 });
}
}

View File

@@ -12,22 +12,24 @@ extern "C"
#include "c_api/TSceneManager.h"
EMSCRIPTEN_KEEPALIVE TScene *SceneManager_getScene(TSceneManager *tSceneManager) {
EMSCRIPTEN_KEEPALIVE TScene *SceneManager_getScene(TSceneManager *tSceneManager)
{
auto sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return reinterpret_cast<TScene*>(sceneManager->getScene());
return reinterpret_cast<TScene *>(sceneManager->getScene());
}
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUnlitMaterialProvider(TSceneManager *tSceneManager) {
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUnlitMaterialProvider(TSceneManager *tSceneManager)
{
auto sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto provider = sceneManager->getUnlitMaterialProvider();
return reinterpret_cast<TMaterialProvider*>(provider);
return reinterpret_cast<TMaterialProvider *>(provider);
}
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUbershaderMaterialProvider(TSceneManager *tSceneManager) {
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUbershaderMaterialProvider(TSceneManager *tSceneManager)
{
auto sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto provider = sceneManager->getUbershaderMaterialProvider();
return reinterpret_cast<TMaterialProvider*>(provider);
return reinterpret_cast<TMaterialProvider *>(provider);
}
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene, TGizmoType tGizmoType)
@@ -46,7 +48,7 @@ extern "C"
return reinterpret_cast<TSceneAsset *>(asset);
}
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGltf(TSceneManager *tSceneManager,
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGltf(TSceneManager *tSceneManager,
const char *assetPath,
const char *relativeResourcePath,
bool keepData)
@@ -56,7 +58,6 @@ extern "C"
return reinterpret_cast<TSceneAsset *>(asset);
}
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGlbFromBuffer(TSceneManager *tSceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
@@ -164,7 +165,6 @@ extern "C"
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance *>(instance));
}
EMSCRIPTEN_KEEPALIVE int SceneManager_removeFromScene(TSceneManager *sceneManager, EntityId entityId)
{
return ((SceneManager *)sceneManager)->removeFromScene(entityId);
@@ -187,36 +187,78 @@ extern "C"
return reinterpret_cast<TAnimationManager *>(animationManager);
}
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAll(TSceneManager *tSceneManager)
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_addLight(
TSceneManager *tSceneManager,
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)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto entity = sceneManager->addLight(
(LightManager::Type)type, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, falloffRadius, spotLightConeInner, spotLightConeOuter, sunAngularRadius, sunHaloSize, sunHaloFallof, shadows);
}
EMSCRIPTEN_KEEPALIVE void SceneManager_removeLight(TSceneManager *tSceneManager, EntityId entityId)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
sceneManager->removeLight(utils::Entity::import(entityId));
}
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAll(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
sceneManager->destroyAll();
return nullptr;
}
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *tSceneAsset)
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *tSceneAsset)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto *sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
sceneManager->destroy(sceneAsset);
return nullptr;
}
EMSCRIPTEN_KEEPALIVE TNameComponentManager *SceneManager_getNameComponentManager(TSceneManager *tSceneManager) {
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyLights(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return reinterpret_cast<TNameComponentManager*>(sceneManager->getNameComponentManager());
sceneManager->destroyLights();
}
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGrid(TSceneManager *tSceneManager, TMaterial *tMaterial) {
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyAssets(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
sceneManager->destroyAssets();
}
EMSCRIPTEN_KEEPALIVE TNameComponentManager *SceneManager_getNameComponentManager(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return reinterpret_cast<TNameComponentManager *>(sceneManager->getNameComponentManager());
}
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGrid(TSceneManager *tSceneManager, TMaterial *tMaterial)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto *material = reinterpret_cast<Material *>(tMaterial);
auto *grid = sceneManager->createGrid(material);
return reinterpret_cast<TSceneAsset*>(grid);
return reinterpret_cast<TSceneAsset *>(grid);
}
EMSCRIPTEN_KEEPALIVE bool SceneManager_isGridEntity(TSceneManager *tSceneManager, EntityId entityId) {
EMSCRIPTEN_KEEPALIVE bool SceneManager_isGridEntity(TSceneManager *tSceneManager, EntityId entityId)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return sceneManager->isGridEntity(utils::Entity::import(entityId));
}
}

View File

@@ -113,48 +113,6 @@ extern "C"
((FilamentViewer *)viewer)->removeIbl();
}
EMSCRIPTEN_KEEPALIVE EntityId add_light(
TViewer *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, falloffRadius, spotLightConeInner, spotLightConeOuter, sunAngularRadius, sunHaloSize, sunHaloFallof, shadows);
}
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, int32_t entityId, float x, float y, float z)
{
((FilamentViewer *)viewer)->setLightPosition(entityId, x, y, z);
}
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, int32_t entityId, float x, float y, float z)
{
((FilamentViewer *)viewer)->setLightDirection(entityId, x, y, z);
}
EMSCRIPTEN_KEEPALIVE void remove_light(TViewer *viewer, int32_t entityId)
{
((FilamentViewer *)viewer)->removeLight(entityId);
}
EMSCRIPTEN_KEEPALIVE void clear_lights(TViewer *viewer)
{
((FilamentViewer *)viewer)->clearLights();
}
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId)
{
return ((SceneManager *)sceneManager)->getInstanceCount(entityId);
@@ -489,6 +447,12 @@ extern "C"
return reinterpret_cast<TRenderableManager *>(&renderableManager);
}
EMSCRIPTEN_KEEPALIVE TLightManager *Engine_getLightManager(TEngine *tEngine) {
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto &lightManager = engine->getLightManager();
return reinterpret_cast<TLightManager *>(&lightManager);
}
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);

View File

@@ -465,15 +465,11 @@ namespace thermion
void SceneManager::destroyAll()
{
destroyLights();
destroyAssets();
std::lock_guard lock(_mutex);
for (auto &asset : _sceneAssets)
{
asset->removeAllEntities(_scene);
}
_sceneAssets.clear();
for (auto *texture : _textures)
{
_engine->destroy(texture);
@@ -515,6 +511,83 @@ namespace thermion
}
}
utils::Entity SceneManager::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 result = LightManager::Builder(t)
.color(Color::cct(colour))
.intensity(intensity)
.falloff(falloffRadius)
.spotLightCone(spotLightConeInner, spotLightConeOuter)
.sunAngularRadius(sunAngularRadius)
.sunHaloSize(sunHaloSize)
.sunHaloFalloff(sunHaloFallof)
.position(filament::math::float3(posX, posY, posZ))
.direction(filament::math::float3(dirX, dirY, dirZ))
.castShadows(shadows)
.build(*_engine, light);
if (result != LightManager::Builder::Result::Success)
{
Log("ERROR : failed to create light");
}
else
{
_scene->addEntity(light);
_lights.push_back(light);
TRACE("Created light");
}
return light;
}
void SceneManager::removeLight(utils::Entity entity)
{
auto removed = remove(_lights.begin(), _lights.end(), entity);
_scene->remove(entity);
EntityManager::get().destroy(1, &entity);
}
void SceneManager::destroyLights()
{
std::lock_guard lock(_mutex);
_scene->removeEntities(_lights.data(), _lights.size());
EntityManager::get().destroy(_lights.size(), _lights.data());
_lights.clear();
}
void SceneManager::destroyAssets()
{
std::lock_guard lock(_mutex);
for (auto &asset : _sceneAssets)
{
asset->removeAllEntities(_scene);
for(int i = 0; i < asset->getInstanceCount(); i++) {
asset->getInstanceAt(i)->removeAllEntities(_scene);
}
}
_sceneAssets.clear();
}
Texture *SceneManager::createTexture(const uint8_t *data, size_t length, const char *name)
{

View File

@@ -0,0 +1,18 @@
import 'package:thermion_dart/thermion_dart.dart';
import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart';
import 'helpers.dart';
void main() async {
final testHelper = TestHelper("lights");
group("assets", () {
test('add/clear asset', () async {
await testHelper.withViewer((viewer) async {
var asset = await viewer.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
await testHelper.capture(viewer, "asset_loaded");
await viewer.destroyAssets();
await testHelper.capture(viewer, "assets_cleared");
}, bg: kRed);
});
});
}

View File

@@ -0,0 +1,22 @@
import 'package:thermion_dart/thermion_dart.dart';
import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart';
import 'helpers.dart';
void main() async {
final testHelper = TestHelper("lights");
group("lights", () {
test('add/clear point lights', () async {
await testHelper.withViewer((viewer) async {
await viewer.loadGlb("file://${testHelper.testDir}/assets/cube.glb");
var light = await viewer.addDirectLight(
DirectLight.point(intensity: 10000000000, falloffRadius: 10));
await viewer.setLightPosition(light, 0, 10, 0);
await testHelper.capture(viewer, "add_point_light");
await viewer.destroyLights();
await testHelper.capture(viewer, "remove_lights");
});
});
});
}

View File

@@ -31,7 +31,7 @@
// }
// Future _set() async {
// await widget.controller.clearLights();
// await widget.controller.destroyLights();
// if (widget.options.iblPath != null) {
// _light = await widget.controller.loadIbl(widget.options.iblPath!,