From b48dd130be943909207ea6febdcd0444ff3d9c36 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Sun, 11 Sep 2022 18:55:29 +1000 Subject: [PATCH] add reverse animation and stopAnimation bindings for android --- .../app/polyvox/filament/FilamentInterop.kt | 3 +- .../polyvox/filament/PolyvoxFilamentPlugin.kt | 15 +++--- ios/src/PolyvoxFilamentApi.cpp | 4 +- ios/src/PolyvoxFilamentApi.hpp | 5 +- ios/src/SceneAsset.cpp | 47 ++++++++++++------- ios/src/SceneAsset.hpp | 2 +- ios/src/SceneResources.hpp | 12 ++--- 7 files changed, 53 insertions(+), 35 deletions(-) diff --git a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt index 5bce684b..db71d447 100644 --- a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt +++ b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt @@ -69,7 +69,8 @@ interface FilamentInterop : Library { fun get_animation_count(asset:Pointer) : Int; fun get_animation_name(asset:Pointer, outPtr:Pointer, index:Int); - fun play_animation(asset:Pointer, index:Int, loop:Boolean); + fun play_animation(asset:Pointer, index:Int, loop:Boolean, reverse:Boolean); + fun stop_animation(asset:Pointer, index:Int); fun free_pointer(ptr:Pointer, size:Int); diff --git a/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt b/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt index bdd79c9d..db43710c 100644 --- a/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt +++ b/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt @@ -172,19 +172,14 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { "initialize" -> { - print("Initializing") - val entry = flutterPluginBinding.textureRegistry.createSurfaceTexture(); executor.execute { if(_viewer != null) { - print("Deleting existing viewer") _lib.filament_viewer_delete(_viewer!!); - print("Deleted viewer") _viewer = null; } if(surfaceTexture != null) { - print("Releasing existing texture") surfaceTexture!!.release() surfaceTexture = null; } @@ -227,6 +222,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { } "setRendering" -> { _render = call.arguments as Boolean + Log.v(TAG, "Set rendering to ${_render}") result.success(null) } "setFrameInterval" -> { @@ -555,7 +551,14 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { "playAnimation" -> { executor.execute { val args = call.arguments as ArrayList - _lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean) + _lib.play_animation(Pointer(args[0] as Long), args[1] as Int, args[2] as Boolean, args[3] as Boolean) + result.success("OK") + } + } + "stopAnimation" -> { + executor.execute { + val args = call.arguments as ArrayList + _lib.stop_animation(Pointer(args[0] as Long), args[1] as Int) result.success("OK") } } diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index 96ee5135..b2dce241 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -143,8 +143,8 @@ extern "C" { ((SceneAsset*)asset)->animateWeights((float*)data, numWeights, numFrames, frameRate); } - void play_animation(void* asset, int index, bool loop) { - ((SceneAsset*)asset)->playAnimation(index, loop); + void play_animation(void* asset, int index, bool loop, bool reverse) { + ((SceneAsset*)asset)->playAnimation(index, loop, reverse); } int get_animation_count(void* asset) { diff --git a/ios/src/PolyvoxFilamentApi.hpp b/ios/src/PolyvoxFilamentApi.hpp index 1ee7e8f1..200182fc 100644 --- a/ios/src/PolyvoxFilamentApi.hpp +++ b/ios/src/PolyvoxFilamentApi.hpp @@ -40,7 +40,8 @@ void apply_weights(void* asset, float* const weights, int count); void animate_weights(void* asset, float* data, int numWeights, int numFrames, float frameRate); -void play_animation(void* asset, int index, bool loop); +void play_animation(void* asset, int index, bool loop, bool reverse); +void stop_animation(void* asset, int index); int get_animation_count(void* asset); @@ -63,8 +64,6 @@ void set_position(void* asset, float x, float y, float z); void set_rotation(void* asset, float rads, float x, float y, float z); -void stop_animation(void* asset, int index); - void set_camera_position(void* viewer, float x, float y, float z); void set_camera_rotation(void* viewer, float rads, float x, float y, float z); diff --git a/ios/src/SceneAsset.cpp b/ios/src/SceneAsset.cpp index 38176038..b8b29dd7 100644 --- a/ios/src/SceneAsset.cpp +++ b/ios/src/SceneAsset.cpp @@ -34,7 +34,7 @@ SceneAsset::SceneAsset(FilamentAsset *asset, Engine *engine, _animator = _asset->getAnimator(); for (int i = 0; i < _animator->getAnimationCount(); i++) { _embeddedAnimationStatus.push_back( - EmbeddedAnimationStatus(i, _animator->getAnimationDuration(i), false)); + EmbeddedAnimationStatus(false,false)); } Log("Created animation buffers for %d", _embeddedAnimationStatus.size()); } @@ -105,16 +105,20 @@ void SceneAsset::updateMorphAnimation() { } } -void SceneAsset::playAnimation(int index, bool loop) { - Log("Playing animation at index %d", index); +void SceneAsset::playAnimation(int index, bool loop, bool reverse) { if (index > _animator->getAnimationCount() - 1) { Log("Asset does not contain an animation at index %d", index); - } else if (_embeddedAnimationStatus[index].started) { - Log("Animation already playing, call stop first."); } else { - Log("Starting animation at index %d", index); - _embeddedAnimationStatus[index].play = true; - _embeddedAnimationStatus[index].loop = loop; + const char* name = _animator->getAnimationName(index); + Log("Playing animation %d : %s", index, name); + if (_embeddedAnimationStatus[index].started) { + Log("Animation already playing, call stop first."); + } else { + Log("Starting animation at index %d with loop : %d and reverse %d ", index, loop, reverse); + _embeddedAnimationStatus[index].play = true; + _embeddedAnimationStatus[index].loop = loop; + _embeddedAnimationStatus[index].reverse = reverse; + } } } @@ -194,37 +198,48 @@ void SceneAsset::setTexture() { void SceneAsset::updateEmbeddedAnimations() { auto now = high_resolution_clock::now(); + int animationIndex = 0; for (auto &status : _embeddedAnimationStatus) { if (!status.play) { - // Log("Skipping animation %d", status.animationIndex); + Log("Animation %d not playing", animationIndex); continue; } - duration dur = + + float animationLength = _animator->getAnimationDuration(animationIndex); + + duration elapsed = duration_cast>(now - status.startedAt); float animationTimeOffset = 0; - bool finished = false; + bool finished = false; if (!status.started) { + Log("Starting"); + status.started = true; status.startedAt = now; - } else if (dur.count() >= status.duration) { + } else if (elapsed.count() >= animationLength) { if (status.loop) { status.startedAt = now; } else { - animationTimeOffset = dur.count(); + animationTimeOffset = elapsed.count(); finished = true; } } else { - animationTimeOffset = dur.count(); + animationTimeOffset = elapsed.count(); + } + + if(status.reverse) { + animationTimeOffset = _animator->getAnimationDuration(animationIndex) - animationTimeOffset; } if (!finished) { - _animator->applyAnimation(status.animationIndex, animationTimeOffset); + _animator->applyAnimation(animationIndex, animationTimeOffset); } else { - Log("Animation %d finished", status.animationIndex); + Log("Animation %d finished", animationIndex); status.play = false; status.started = false; } + animationIndex++; } _animator->updateBoneMatrices(); diff --git a/ios/src/SceneAsset.hpp b/ios/src/SceneAsset.hpp index 4305a0be..5ef4b602 100644 --- a/ios/src/SceneAsset.hpp +++ b/ios/src/SceneAsset.hpp @@ -53,7 +53,7 @@ namespace polyvox { /// /// Play the embedded animation (i.e. animation node embedded in the GLTF asset) under the specified index. If [loop] is true, the animation will repeat indefinitely. /// - void playAnimation(int index, bool loop); + void playAnimation(int index, bool loop, bool reverse); /// /// Manually set the weights for all morph targets in the assets to the provided values. diff --git a/ios/src/SceneResources.hpp b/ios/src/SceneResources.hpp index 8ea1a95b..745254ba 100644 --- a/ios/src/SceneResources.hpp +++ b/ios/src/SceneResources.hpp @@ -24,7 +24,7 @@ namespace polyvox { // Currently, an instance will be constructed for every animation in an asset whenever a SceneAsset is created (and thus will persist for the lifetime of the SceneAsset). // struct EmbeddedAnimationStatus { - EmbeddedAnimationStatus(int animationIndex, float duration, bool loop) : animationIndex(animationIndex), duration(duration), loop(loop) {} + EmbeddedAnimationStatus(bool loop, bool reverse) : loop(loop), reverse(reverse) {} // // A flag that is checked each frame to determine whether or not the animation should play. @@ -35,6 +35,11 @@ namespace polyvox { // If [play] is true, this flag will be checked when the animation is complete. If true, the animation will restart. // bool loop; + + // + // If true, the animation will be played in reverse. + // + bool reverse; // // If [play] is true, this flag will be set to true when the animation is started. @@ -46,11 +51,6 @@ namespace polyvox { // int animationIndex; - // - // The duration of the animation (calculated from the GLTF animator). - // - float duration = 0; - // // The time point at which this animation was last started. // This is used to calculate the "animation time offset" that is passed to the Animator.