From a30e2f295f6ef3853491a4596857df68ef2ef6cb Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 29 Jul 2024 16:13:45 +0800 Subject: [PATCH] feat: add startOffset parameter to gltf playAnimation --- .../compatibility/native/thermion_dart.g.dart | 16 ++-------------- .../web/ffi/thermion_dart.g.dart | 19 ------------------- .../interop/thermion_viewer_dart_bridge.dart | 4 +++- .../web/interop/thermion_viewer_js.dart | 5 +++-- .../web/interop/thermion_viewer_js_shim.dart | 1 + .../web/interop/thermion_viewer_wasm.dart | 4 +++- .../lib/thermion_dart/thermion_viewer.dart | 3 ++- .../thermion_dart/thermion_viewer_ffi.dart | 5 +++-- .../thermion_dart/thermion_viewer_stub.dart | 3 ++- thermion_dart/native/include/SceneManager.hpp | 2 +- .../native/include/ThermionDartApi.h | 2 +- .../native/include/ThermionDartFFIApi.h | 2 -- .../components/AnimationComponentManager.hpp | 3 ++- thermion_dart/native/src/SceneManager.cpp | 5 +++-- thermion_dart/native/src/ThermionDartApi.cpp | 5 +++-- .../native/src/ThermionDartFFIApi.cpp | 12 ------------ 16 files changed, 29 insertions(+), 62 deletions(-) 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 b3e31df0..596a37e4 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 @@ -456,7 +456,7 @@ external bool set_bone_transform( @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Int, ffi.Int, ffi.Bool, - ffi.Bool, ffi.Bool, ffi.Float)>() + ffi.Bool, ffi.Bool, ffi.Float, ffi.Float)>() external void play_animation( ffi.Pointer sceneManager, int entity, @@ -465,6 +465,7 @@ external void play_animation( bool reverse, bool replaceActive, double crossfade, + double startOffset, ); @ffi.Native< @@ -1301,19 +1302,6 @@ external void apply_weights_ffi( int count, ); -@ffi.Native< - ffi.Void Function(ffi.Pointer, EntityId, ffi.Int, ffi.Bool, - ffi.Bool, ffi.Bool, ffi.Float)>() -external void play_animation_ffi( - ffi.Pointer sceneManager, - int asset, - int index, - bool loop, - bool reverse, - bool replaceActive, - double crossfade, -); - @ffi.Native< ffi.Void Function(ffi.Pointer, EntityId, ffi.Int, ffi.Int)>() external void set_animation_frame_ffi( diff --git a/thermion_dart/lib/thermion_dart/compatibility/web/ffi/thermion_dart.g.dart b/thermion_dart/lib/thermion_dart/compatibility/web/ffi/thermion_dart.g.dart index 898a00b2..c1bf6de3 100644 --- a/thermion_dart/lib/thermion_dart/compatibility/web/ffi/thermion_dart.g.dart +++ b/thermion_dart/lib/thermion_dart/compatibility/web/ffi/thermion_dart.g.dart @@ -1592,25 +1592,6 @@ external void apply_weights_ffi( int count, ); -@ffi.Native< - ffi.Void Function( - ffi.Pointer, - EntityId, - ffi.Int, - ffi.Bool, - ffi.Bool, - ffi.Bool, - ffi.Float)>(symbol: '_play_animation_ffi', assetId: 'thermion_dart') -external void play_animation_ffi( - ffi.Pointer sceneManager, - int asset, - int index, - bool loop, - bool reverse, - bool replaceActive, - double crossfade, -); - @ffi.Native< ffi.Void Function(ffi.Pointer, EntityId, ffi.Int, ffi.Int)>( symbol: '_set_animation_frame_ffi', assetId: 'thermion_dart') 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 1e61f578..7d294280 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 @@ -339,7 +339,8 @@ class ThermionViewerJSDartBridge { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}) => + double crossfade = 0.0, + double startOffset = 0.0}) => viewer .playAnimation( entity, @@ -348,6 +349,7 @@ class ThermionViewerJSDartBridge { reverse: reverse, replaceActive: replaceActive, crossfade: crossfade, + startOffset: startOffset ) .toJS; 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 f9326926..11f5269f 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 @@ -368,9 +368,10 @@ class ThermionViewerJS implements ThermionViewer { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}) async { + double crossfade = 0.0, + double startOffset = 0.0}) async { await _shim - .playAnimation(entity, index, loop, reverse, replaceActive, crossfade) + .playAnimation(entity, index, loop, reverse, replaceActive, crossfade, startOffset) .toDart; } 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 b6d5e2ad..50f0e44e 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 @@ -184,6 +184,7 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject { bool reverse, bool replaceActive, double crossfade, + double startOffset, ); @JS('playAnimationByName') 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 50edbd25..f436545c 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 @@ -698,7 +698,8 @@ class ThermionViewerWasm implements ThermionViewer { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}) async { + double crossfade = 0.0, + double startOffset = 0.0}) async { _module.ccall( "play_animation", "void", @@ -709,6 +710,7 @@ class ThermionViewerWasm implements ThermionViewer { "bool".toJS, "bool".toJS, "bool".toJS, + "float".toJS, "float".toJS ].toJS, [ diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer.dart b/thermion_dart/lib/thermion_dart/thermion_viewer.dart index 8643c8b9..1d93ba75 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer.dart @@ -386,7 +386,8 @@ abstract class ThermionViewer { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}); + double crossfade = 0.0, + double startOffset = 0.0}); /// /// Schedules the glTF animation at [index] in [entity] to start playing on the next frame. diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart index 200d2495..a0792d36 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_ffi.dart @@ -980,9 +980,10 @@ class ThermionViewerFFI extends ThermionViewer { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}) async { + double crossfade = 0.0, + double startOffset = 0.0}) async { play_animation( - _sceneManager!, entity, index, loop, reverse, replaceActive, crossfade); + _sceneManager!, entity, index, loop, reverse, replaceActive, crossfade, startOffset); } /// diff --git a/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart b/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart index 754d1f93..d62f5ec9 100644 --- a/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart +++ b/thermion_dart/lib/thermion_dart/thermion_viewer_stub.dart @@ -333,7 +333,8 @@ class ThermionViewerStub extends ThermionViewer { {bool loop = false, bool reverse = false, bool replaceActive = true, - double crossfade = 0.0}) { + double crossfade = 0.0, + double startOffset=0.0}) { // TODO: implement playAnimation throw UnimplementedError(); } diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index 81a366ed..4a5bdf41 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -129,7 +129,7 @@ namespace thermion_filament void resetBones(EntityId entityId); bool setTransform(EntityId entityId, math::mat4f transform); bool updateBoneMatrices(EntityId entityId); - void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f); + void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f, float startOffset = 0.0f); void stopAnimation(EntityId e, int index); void setMorphTargetWeights(const char *const entityName, float *weights, int count); void loadTexture(EntityId entity, const char *resourcePath, int renderableIndex); diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 66ed4ea5..01286c8e 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -168,7 +168,7 @@ extern "C" int skinIndex, int boneIndex, const float *const transform); - EMSCRIPTEN_KEEPALIVE void play_animation(void *sceneManager, EntityId entity, int index, bool loop, bool reverse, bool replaceActive, float crossfade); + EMSCRIPTEN_KEEPALIVE void play_animation(void *sceneManager, EntityId entity, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset); EMSCRIPTEN_KEEPALIVE void set_animation_frame(void *sceneManager, EntityId entity, int animationIndex, int animationFrame); EMSCRIPTEN_KEEPALIVE void stop_animation(void *sceneManager, EntityId entity, int index); EMSCRIPTEN_KEEPALIVE int get_animation_count(void *sceneManager, EntityId asset); diff --git a/thermion_dart/native/include/ThermionDartFFIApi.h b/thermion_dart/native/include/ThermionDartFFIApi.h index fa99f621..8e7bdbae 100644 --- a/thermion_dart/native/include/ThermionDartFFIApi.h +++ b/thermion_dart/native/include/ThermionDartFFIApi.h @@ -78,8 +78,6 @@ extern "C" const char *const entityName, float *const weights, int count); - - EMSCRIPTEN_KEEPALIVE void play_animation_ffi(void *const sceneManager, EntityId asset, int index, bool loop, bool reverse, bool replaceActive, float crossfade); EMSCRIPTEN_KEEPALIVE void set_animation_frame_ffi(void *const sceneManager, EntityId asset, int animationIndex, int animationFrame); EMSCRIPTEN_KEEPALIVE void stop_animation_ffi(void *const sceneManager, EntityId asset, int index); EMSCRIPTEN_KEEPALIVE void get_animation_count_ffi(void *const sceneManager, EntityId asset, void (*callback)(int)); diff --git a/thermion_dart/native/include/components/AnimationComponentManager.hpp b/thermion_dart/native/include/components/AnimationComponentManager.hpp index c182ef85..40b18219 100644 --- a/thermion_dart/native/include/components/AnimationComponentManager.hpp +++ b/thermion_dart/native/include/components/AnimationComponentManager.hpp @@ -43,6 +43,7 @@ namespace thermion_filament struct AnimationStatus { time_point_t start = time_point_t::max(); + float startOffset; bool loop = false; bool reverse = false; float durationInSecs = 0; @@ -182,7 +183,7 @@ namespace thermion_filament auto animationStatus = animationComponent.gltfAnimations[i]; - auto elapsedInSecs = float(std::chrono::duration_cast(now - animationStatus.start).count()) / 1000.0f; + auto elapsedInSecs = animationStatus.startOffset + float(std::chrono::duration_cast(now - animationStatus.start).count()) / 1000.0f; if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs) { diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 8165e204..7fe0eeea 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -1135,8 +1135,8 @@ namespace thermion_filament return true; } - - void SceneManager::playAnimation(EntityId entityId, int index, bool loop, bool reverse, bool replaceActive, float crossfade) + + void SceneManager::playAnimation(EntityId entityId, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset) { std::lock_guard lock(_mutex); @@ -1200,6 +1200,7 @@ namespace thermion_filament } GltfAnimation animation; + animation.startOffset = startOffset; animation.index = index; animation.start = std::chrono::high_resolution_clock::now(); animation.loop = loop; diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index a1c50ccd..52d0a97f 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -586,9 +586,10 @@ extern "C" bool loop, bool reverse, bool replaceActive, - float crossfade) + float crossfade, + float startOffset) { - ((SceneManager *)sceneManager)->playAnimation(asset, index, loop, reverse, replaceActive, crossfade); + ((SceneManager *)sceneManager)->playAnimation(asset, index, loop, reverse, replaceActive, crossfade, startOffset); } EMSCRIPTEN_KEEPALIVE void set_animation_frame( diff --git a/thermion_dart/native/src/ThermionDartFFIApi.cpp b/thermion_dart/native/src/ThermionDartFFIApi.cpp index 35d8d2e9..dadb0c36 100644 --- a/thermion_dart/native/src/ThermionDartFFIApi.cpp +++ b/thermion_dart/native/src/ThermionDartFFIApi.cpp @@ -677,18 +677,6 @@ extern "C" auto fut = _rl->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void play_animation_ffi(void *const sceneManager, - EntityId asset, int index, - bool loop, bool reverse, - bool replaceActive, - float crossfade) - { - std::packaged_task lambda([=] - { play_animation(sceneManager, asset, index, loop, reverse, replaceActive, - crossfade); }); - auto fut = _rl->add_task(lambda); - } - EMSCRIPTEN_KEEPALIVE void set_animation_frame_ffi(void *const sceneManager, EntityId asset, int animationIndex,