diff --git a/thermion_dart/lib/thermion_dart/compatibility/native/thermion_dart.g.dart b/thermion_dart/lib/thermion_dart/compatibility/native/thermion_dart.g.dart index b2822241..b3e31df0 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/native/thermion_dart.g.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/native/thermion_dart.g.dart @@ -368,6 +368,12 @@ external bool set_morph_animation( double frameLengthInMs, ); +@ffi.Native, ffi.Int)>() +external void clear_morph_animation( + ffi.Pointer sceneManager, + int entity, +); + @ffi.Native, ffi.Int)>() external void reset_to_rest_pose( ffi.Pointer sceneManager, diff --git a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_dart_bridge.dart b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_dart_bridge.dart index c0687c52..1e61f578 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_dart_bridge.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_dart_bridge.dart @@ -226,6 +226,11 @@ class ThermionViewerJSDartBridge { .then((v) => v.toJS) .toJS; + @JSExport() + void clearMorphAnimationData(ThermionEntity entity) { + viewer.clearMorphAnimationData(entity); + } + @JSExport() JSPromise setMorphAnimationData( ThermionEntity entity, diff --git a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js.dart b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js.dart index 83919eb4..f9326926 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js.dart @@ -263,6 +263,11 @@ class ThermionViewerJS implements ThermionViewer { .toDartDouble; } + @override + Future clearMorphAnimationData(ThermionEntity entity) async { + _shim.clearMorphAnimationData(entity); + } + @override Future setMorphAnimationData( ThermionEntity entity, MorphAnimationData animation, diff --git a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart index 3b4fadfd..b6d5e2ad 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart @@ -6,11 +6,10 @@ import 'dart:js_interop'; import 'package:thermion_dart/thermion_dart/thermion_viewer.dart'; /// -/// An extension type on [JSObject] that represents a +/// An extension type on [JSObject] that represents a /// Javascript shim implementation of the [ThermionViewer] interface. -/// +/// extension type ThermionViewerJSShim(JSObject _) implements JSObject { - @JS('initialized') external JSPromise get initialized; @@ -136,6 +135,9 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject { external JSPromise getAnimationDuration( ThermionEntity entity, int animationIndex); + @JS('clearMorphAnimationData') + external void clearMorphAnimationData(ThermionEntity entity); + @JS('setMorphAnimationData') external JSPromise setMorphAnimationData( ThermionEntity entity, @@ -403,19 +405,16 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject { ThermionEntity entity, JSArray transform); @JS('setBoneTransform') - external JSPromise setBoneTransform( - ThermionEntity entity, int boneIndex, JSArray transform, int skinIndex); - + external JSPromise setBoneTransform(ThermionEntity entity, int boneIndex, + JSArray transform, int skinIndex); + @JS('setShadowsEnabled') - external JSPromise setShadowsEnabled( - bool enabled); + external JSPromise setShadowsEnabled(bool enabled); @JS('setShadowType') - external JSPromise setShadowType( - int shadowType); + external JSPromise setShadowType(int shadowType); @JS('setSoftShadowOptions') external JSPromise setSoftShadowOptions( double penumbraScale, double penumbraRatioScale); } - diff --git a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart index c27d5e40..50edbd25 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart @@ -788,6 +788,27 @@ class ThermionViewerWasm implements ThermionViewer { null); } + @override + Future clearMorphAnimationData( + ThermionEntity entity) async { + var meshEntities = await getChildEntities(entity, false); + for(final childEntity in meshEntities) { + _module.ccall( + "clear_morph_animation", + "void", + [ + "void*".toJS, + "int".toJS, + ].toJS, + [ + _sceneManager!, + childEntity.toJS, + ].toJS, + null); + } + + } + @override Future setMorphAnimationData( ThermionEntity entity, MorphAnimationData animation, diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer.dart b/thermion_dart/lib/thermion_dart/thermion_viewer.dart index 6f622bd3..8643c8b9 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer.dart @@ -269,6 +269,12 @@ abstract class ThermionViewer { ThermionEntity entity, MorphAnimationData animation, {List? targetMeshNames}); + /// + /// Clear all current morph animations for [entity]. + /// + Future clearMorphAnimationData( + ThermionEntity entity); + /// /// Resets all bones in the given entity to their rest pose. /// This should be done before every call to addBoneAnimation. diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart index 8aecbc0c..200d2495 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart @@ -599,6 +599,18 @@ class ThermionViewerFFI extends ThermionViewer { return getAnimationDuration(entity, index); } + Future clearMorphAnimationData(ThermionEntity entity) async { + var meshEntities = await getChildEntities(entity, true); + + for(final childEntity in meshEntities) { + clear_morph_animation( + _sceneManager!, + childEntity); + } + + + } + /// /// /// diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart index cde3d073..754d1f93 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart @@ -586,6 +586,11 @@ class ThermionViewerStub extends ThermionViewer { throw UnimplementedError(); } + @override + Future clearMorphAnimationData(ThermionEntity entity) { + throw UnimplementedError(); + } + @override Future setMorphAnimationData( ThermionEntity entity, MorphAnimationData animation, @@ -726,19 +731,19 @@ class ThermionViewerStub extends ThermionViewer { // TODO: implement zoomUpdate throw UnimplementedError(); } - + @override Future setShadowType(ShadowType shadowType) { // TODO: implement setShadowType throw UnimplementedError(); } - + @override Future setShadowsEnabled(bool enabled) { // TODO: implement setShadowsEnabled throw UnimplementedError(); } - + @override Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) { // TODO: implement setSoftShadowOptions diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index 484b75d2..81a366ed 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -87,6 +87,9 @@ namespace thermion_filament int numFrames, float frameLengthInMs); + void clearMorphAnimationBuffer( + EntityId entityId); + bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count); math::mat4f getLocalTransform(EntityId entityId); diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 041d342e..66ed4ea5 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -136,6 +136,9 @@ extern "C" int numMorphTargets, int numFrames, float frameLengthInMs); + EMSCRIPTEN_KEEPALIVE void clear_morph_animation( + void *sceneManager, + EntityId entity); EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose( void *sceneManager, diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 2329492f..8165e204 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -781,6 +781,27 @@ namespace thermion_filament return true; } + void SceneManager::clearMorphAnimationBuffer( + EntityId entityId) + { + std::lock_guard lock(_mutex); + + auto entity = Entity::import(entityId); + + if (entity.isNull()) + { + Log("ERROR: invalid entity %d.", entityId); + return; + } + + auto animationComponentInstance = _animationComponentManager->getInstance(entity); + auto &animationComponent = _animationComponentManager->elementAt<0>(animationComponentInstance); + auto &morphAnimations = animationComponent.morphAnimations; + + morphAnimations.clear(); + return; + } + bool SceneManager::setMaterialColor(EntityId entityId, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a) { diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index 349adfe2..a1c50ccd 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -405,7 +405,7 @@ extern "C" return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights); } - bool set_morph_animation( + EMSCRIPTEN_KEEPALIVE bool set_morph_animation( void *sceneManager, EntityId asset, const float *const morphData, @@ -418,6 +418,10 @@ extern "C" return result; } + EMSCRIPTEN_KEEPALIVE void clear_morph_animation(void* sceneManager, EntityId asset) { + ((SceneManager *)sceneManager)->clearMorphAnimationBuffer(asset); + } + EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(void *sceneManager, EntityId entityId) { ((SceneManager *)sceneManager)->resetBones(entityId);