feat: add startOffset parameter to gltf playAnimation

This commit is contained in:
Nick Fisher
2024-07-29 16:13:45 +08:00
parent 96ad9dee18
commit a30e2f295f
16 changed files with 29 additions and 62 deletions

View File

@@ -456,7 +456,7 @@ external bool set_bone_transform(
@ffi.Native< @ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Bool, ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Bool,
ffi.Bool, ffi.Bool, ffi.Float)>() ffi.Bool, ffi.Bool, ffi.Float, ffi.Float)>()
external void play_animation( external void play_animation(
ffi.Pointer<ffi.Void> sceneManager, ffi.Pointer<ffi.Void> sceneManager,
int entity, int entity,
@@ -465,6 +465,7 @@ external void play_animation(
bool reverse, bool reverse,
bool replaceActive, bool replaceActive,
double crossfade, double crossfade,
double startOffset,
); );
@ffi.Native< @ffi.Native<
@@ -1301,19 +1302,6 @@ external void apply_weights_ffi(
int count, int count,
); );
@ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Bool,
ffi.Bool, ffi.Bool, ffi.Float)>()
external void play_animation_ffi(
ffi.Pointer<ffi.Void> sceneManager,
int asset,
int index,
bool loop,
bool reverse,
bool replaceActive,
double crossfade,
);
@ffi.Native< @ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>() ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>()
external void set_animation_frame_ffi( external void set_animation_frame_ffi(

View File

@@ -1592,25 +1592,6 @@ external void apply_weights_ffi(
int count, int count,
); );
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.Void>,
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<ffi.Void> sceneManager,
int asset,
int index,
bool loop,
bool reverse,
bool replaceActive,
double crossfade,
);
@ffi.Native< @ffi.Native<
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>( ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>(
symbol: '_set_animation_frame_ffi', assetId: 'thermion_dart') symbol: '_set_animation_frame_ffi', assetId: 'thermion_dart')

View File

@@ -339,7 +339,8 @@ class ThermionViewerJSDartBridge {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, bool replaceActive = true,
double crossfade = 0.0}) => double crossfade = 0.0,
double startOffset = 0.0}) =>
viewer viewer
.playAnimation( .playAnimation(
entity, entity,
@@ -348,6 +349,7 @@ class ThermionViewerJSDartBridge {
reverse: reverse, reverse: reverse,
replaceActive: replaceActive, replaceActive: replaceActive,
crossfade: crossfade, crossfade: crossfade,
startOffset: startOffset
) )
.toJS; .toJS;

View File

@@ -368,9 +368,10 @@ class ThermionViewerJS implements ThermionViewer {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, bool replaceActive = true,
double crossfade = 0.0}) async { double crossfade = 0.0,
double startOffset = 0.0}) async {
await _shim await _shim
.playAnimation(entity, index, loop, reverse, replaceActive, crossfade) .playAnimation(entity, index, loop, reverse, replaceActive, crossfade, startOffset)
.toDart; .toDart;
} }

View File

@@ -184,6 +184,7 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
bool reverse, bool reverse,
bool replaceActive, bool replaceActive,
double crossfade, double crossfade,
double startOffset,
); );
@JS('playAnimationByName') @JS('playAnimationByName')

View File

@@ -698,7 +698,8 @@ class ThermionViewerWasm implements ThermionViewer {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, bool replaceActive = true,
double crossfade = 0.0}) async { double crossfade = 0.0,
double startOffset = 0.0}) async {
_module.ccall( _module.ccall(
"play_animation", "play_animation",
"void", "void",
@@ -709,6 +710,7 @@ class ThermionViewerWasm implements ThermionViewer {
"bool".toJS, "bool".toJS,
"bool".toJS, "bool".toJS,
"bool".toJS, "bool".toJS,
"float".toJS,
"float".toJS "float".toJS
].toJS, ].toJS,
[ [

View File

@@ -386,7 +386,8 @@ abstract class ThermionViewer {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, 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. /// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.

View File

@@ -980,9 +980,10 @@ class ThermionViewerFFI extends ThermionViewer {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, bool replaceActive = true,
double crossfade = 0.0}) async { double crossfade = 0.0,
double startOffset = 0.0}) async {
play_animation( play_animation(
_sceneManager!, entity, index, loop, reverse, replaceActive, crossfade); _sceneManager!, entity, index, loop, reverse, replaceActive, crossfade, startOffset);
} }
/// ///

View File

@@ -333,7 +333,8 @@ class ThermionViewerStub extends ThermionViewer {
{bool loop = false, {bool loop = false,
bool reverse = false, bool reverse = false,
bool replaceActive = true, bool replaceActive = true,
double crossfade = 0.0}) { double crossfade = 0.0,
double startOffset=0.0}) {
// TODO: implement playAnimation // TODO: implement playAnimation
throw UnimplementedError(); throw UnimplementedError();
} }

View File

@@ -129,7 +129,7 @@ namespace thermion_filament
void resetBones(EntityId entityId); void resetBones(EntityId entityId);
bool setTransform(EntityId entityId, math::mat4f transform); bool setTransform(EntityId entityId, math::mat4f transform);
bool updateBoneMatrices(EntityId entityId); 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 stopAnimation(EntityId e, int index);
void setMorphTargetWeights(const char *const entityName, float *weights, int count); void setMorphTargetWeights(const char *const entityName, float *weights, int count);
void loadTexture(EntityId entity, const char *resourcePath, int renderableIndex); void loadTexture(EntityId entity, const char *resourcePath, int renderableIndex);

View File

@@ -168,7 +168,7 @@ extern "C"
int skinIndex, int skinIndex,
int boneIndex, int boneIndex,
const float *const transform); 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 set_animation_frame(void *sceneManager, EntityId entity, int animationIndex, int animationFrame);
EMSCRIPTEN_KEEPALIVE void stop_animation(void *sceneManager, EntityId entity, int index); EMSCRIPTEN_KEEPALIVE void stop_animation(void *sceneManager, EntityId entity, int index);
EMSCRIPTEN_KEEPALIVE int get_animation_count(void *sceneManager, EntityId asset); EMSCRIPTEN_KEEPALIVE int get_animation_count(void *sceneManager, EntityId asset);

View File

@@ -78,8 +78,6 @@ extern "C"
const char *const entityName, const char *const entityName,
float *const weights, float *const weights,
int count); 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 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 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)); EMSCRIPTEN_KEEPALIVE void get_animation_count_ffi(void *const sceneManager, EntityId asset, void (*callback)(int));

View File

@@ -43,6 +43,7 @@ namespace thermion_filament
struct AnimationStatus struct AnimationStatus
{ {
time_point_t start = time_point_t::max(); time_point_t start = time_point_t::max();
float startOffset;
bool loop = false; bool loop = false;
bool reverse = false; bool reverse = false;
float durationInSecs = 0; float durationInSecs = 0;
@@ -182,7 +183,7 @@ namespace thermion_filament
auto animationStatus = animationComponent.gltfAnimations[i]; auto animationStatus = animationComponent.gltfAnimations[i];
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - animationStatus.start).count()) / 1000.0f; auto elapsedInSecs = animationStatus.startOffset + float(std::chrono::duration_cast<std::chrono::milliseconds>(now - animationStatus.start).count()) / 1000.0f;
if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs) if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
{ {

View File

@@ -1135,8 +1135,8 @@ namespace thermion_filament
return true; 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); std::lock_guard lock(_mutex);
@@ -1200,6 +1200,7 @@ namespace thermion_filament
} }
GltfAnimation animation; GltfAnimation animation;
animation.startOffset = startOffset;
animation.index = index; animation.index = index;
animation.start = std::chrono::high_resolution_clock::now(); animation.start = std::chrono::high_resolution_clock::now();
animation.loop = loop; animation.loop = loop;

View File

@@ -586,9 +586,10 @@ extern "C"
bool loop, bool loop,
bool reverse, bool reverse,
bool replaceActive, 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( EMSCRIPTEN_KEEPALIVE void set_animation_frame(

View File

@@ -677,18 +677,6 @@ extern "C"
auto fut = _rl->add_task(lambda); 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<void()> 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, EMSCRIPTEN_KEEPALIVE void set_animation_frame_ffi(void *const sceneManager,
EntityId asset, EntityId asset,
int animationIndex, int animationIndex,