From fef48940fc5c8a6d603ecd7f40b79ef91c2dbed7 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 9 Jun 2025 18:28:33 +0800 Subject: [PATCH] add implementation methods for getPrimitiveCount, setMaterialInstancesFromMap, getMaterialInstancesAsMap and setMaterialInstanceForAll --- .../src/implementation/ffi_asset.dart | 93 ++++++++++++++++--- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/thermion_dart/lib/src/filament/src/implementation/ffi_asset.dart b/thermion_dart/lib/src/filament/src/implementation/ffi_asset.dart index acc2460d..45b689c9 100644 --- a/thermion_dart/lib/src/filament/src/implementation/ffi_asset.dart +++ b/thermion_dart/lib/src/filament/src/implementation/ffi_asset.dart @@ -478,14 +478,76 @@ class FFIAsset extends ThermionAsset { return FFIMaterialInstance(ptr, app); } + /// + /// + /// + Future setMaterialInstanceForAll(FFIMaterialInstance instance) async { + for (int i = 0; i < await getPrimitiveCount(entity: entity); i++) { + if (RenderableManager_isRenderable(app.renderableManager, entity)) { + await setMaterialInstanceAt(instance, + entity: entity, primitiveIndex: i); + } + } + for (final entity in await getChildEntities()) { + if (!RenderableManager_isRenderable(app.renderableManager, entity)) { + continue; + } + for (int i = 0; i < await getPrimitiveCount(entity: entity); i++) { + await setMaterialInstanceAt(instance, + entity: entity, primitiveIndex: i); + } + } + } + + /// + /// + /// + Future>> + getMaterialInstancesAsMap() async { + final result = >{}; + var entities = [entity, ...await getChildEntities()]; + + for (final entity in entities) { + if (RenderableManager_isRenderable(app.renderableManager, entity)) { + result[entity] = []; + for (int i = 0; i < await getPrimitiveCount(entity: entity); i++) { + result[entity]! + .add(await getMaterialInstanceAt(entity: entity, index: i)); + } + } + } + return result; + } + + /// + /// + /// + Future setMaterialInstancesFromMap( + Map> materialInstances) async { + for (final entity in materialInstances.keys) { + if (RenderableManager_isRenderable(app.renderableManager, entity)) { + for (int i = 0; i < materialInstances[entity]!.length; i++) { + final mi = materialInstances[entity]![i]; + await setMaterialInstanceAt(mi as FFIMaterialInstance, + entity: entity, primitiveIndex: i); + } + } + } + } + /// /// /// @override Future setMaterialInstanceAt(FFIMaterialInstance instance, {int? entity = null, int primitiveIndex = 0}) async { - - if (entity == null) { + if (entity != null && + !RenderableManager_isRenderable(app.renderableManager, entity)) { + _logger.warning("Provided entity is not renderable"); + return; + } + + if (entity == null) { if (RenderableManager_isRenderable(app.renderableManager, this.entity)) { entity ??= this.entity; } else { @@ -501,15 +563,14 @@ class FFIAsset extends ThermionAsset { if (entity == null) { throw Exception("Failed to find renderable entity"); } - + if (!RenderableManager_setMaterialInstanceAt( - Engine_getRenderableManager(app.engine), - entity, - primitiveIndex, - instance.pointer)) { - _logger.warning( - "Failed to set material instance for entity $entity at primitive index ${primitiveIndex}"); - + Engine_getRenderableManager(app.engine), + entity, + primitiveIndex, + instance.pointer)) { + _logger.warning( + "Failed to set material instance for entity $entity at primitive index ${primitiveIndex}"); } } @@ -907,8 +968,7 @@ class FFIAsset extends ThermionAsset { /// /// Future setTransform(Matrix4 transform, {ThermionEntity? entity}) async { - await FilamentApp.instance!.setTransform( - entity ?? this.entity, transform); + await FilamentApp.instance!.setTransform(entity ?? this.entity, transform); } /// @@ -987,7 +1047,9 @@ class FFIAsset extends ThermionAsset { /// @override Future resetBones() async { - await withVoidCallback((requestId, cb) => AnimationManager_resetToRestPoseRenderThread(animationManager, asset, requestId, cb)); + await withVoidCallback((requestId, cb) => + AnimationManager_resetToRestPoseRenderThread( + animationManager, asset, requestId, cb)); } /// @@ -1084,4 +1146,9 @@ class FFIAsset extends ThermionAsset { AnimationManager_removeMorphAnimationComponent(animationManager, child); } } + + Future getPrimitiveCount({ThermionEntity? entity}) async { + entity ??= this.entity; + return RenderableManager_getPrimitiveCount(app.renderableManager, entity); + } }