feat: add clearMorphAnimationData function

This commit is contained in:
Nick Fisher
2024-07-23 09:37:08 +08:00
parent d745712650
commit 41bf9ededa
12 changed files with 105 additions and 15 deletions

View File

@@ -368,6 +368,12 @@ external bool set_morph_animation(
double frameLengthInMs, double frameLengthInMs,
); );
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
external void clear_morph_animation(
ffi.Pointer<ffi.Void> sceneManager,
int entity,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>() @ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
external void reset_to_rest_pose( external void reset_to_rest_pose(
ffi.Pointer<ffi.Void> sceneManager, ffi.Pointer<ffi.Void> sceneManager,

View File

@@ -226,6 +226,11 @@ class ThermionViewerJSDartBridge {
.then((v) => v.toJS) .then((v) => v.toJS)
.toJS; .toJS;
@JSExport()
void clearMorphAnimationData(ThermionEntity entity) {
viewer.clearMorphAnimationData(entity);
}
@JSExport() @JSExport()
JSPromise setMorphAnimationData( JSPromise setMorphAnimationData(
ThermionEntity entity, ThermionEntity entity,

View File

@@ -263,6 +263,11 @@ class ThermionViewerJS implements ThermionViewer {
.toDartDouble; .toDartDouble;
} }
@override
Future<void> clearMorphAnimationData(ThermionEntity entity) async {
_shim.clearMorphAnimationData(entity);
}
@override @override
Future<void> setMorphAnimationData( Future<void> setMorphAnimationData(
ThermionEntity entity, MorphAnimationData animation, ThermionEntity entity, MorphAnimationData animation,

View File

@@ -10,7 +10,6 @@ import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
/// Javascript shim implementation of the [ThermionViewer] interface. /// Javascript shim implementation of the [ThermionViewer] interface.
/// ///
extension type ThermionViewerJSShim(JSObject _) implements JSObject { extension type ThermionViewerJSShim(JSObject _) implements JSObject {
@JS('initialized') @JS('initialized')
external JSPromise<JSBoolean> get initialized; external JSPromise<JSBoolean> get initialized;
@@ -136,6 +135,9 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
external JSPromise<JSNumber> getAnimationDuration( external JSPromise<JSNumber> getAnimationDuration(
ThermionEntity entity, int animationIndex); ThermionEntity entity, int animationIndex);
@JS('clearMorphAnimationData')
external void clearMorphAnimationData(ThermionEntity entity);
@JS('setMorphAnimationData') @JS('setMorphAnimationData')
external JSPromise setMorphAnimationData( external JSPromise setMorphAnimationData(
ThermionEntity entity, ThermionEntity entity,
@@ -403,19 +405,16 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
ThermionEntity entity, JSArray<JSNumber> transform); ThermionEntity entity, JSArray<JSNumber> transform);
@JS('setBoneTransform') @JS('setBoneTransform')
external JSPromise setBoneTransform( external JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
ThermionEntity entity, int boneIndex, JSArray<JSNumber> transform, int skinIndex); JSArray<JSNumber> transform, int skinIndex);
@JS('setShadowsEnabled') @JS('setShadowsEnabled')
external JSPromise setShadowsEnabled( external JSPromise setShadowsEnabled(bool enabled);
bool enabled);
@JS('setShadowType') @JS('setShadowType')
external JSPromise setShadowType( external JSPromise setShadowType(int shadowType);
int shadowType);
@JS('setSoftShadowOptions') @JS('setSoftShadowOptions')
external JSPromise setSoftShadowOptions( external JSPromise setSoftShadowOptions(
double penumbraScale, double penumbraRatioScale); double penumbraScale, double penumbraRatioScale);
} }

View File

@@ -788,6 +788,27 @@ class ThermionViewerWasm implements ThermionViewer {
null); 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 @override
Future setMorphAnimationData( Future setMorphAnimationData(
ThermionEntity entity, MorphAnimationData animation, ThermionEntity entity, MorphAnimationData animation,

View File

@@ -269,6 +269,12 @@ abstract class ThermionViewer {
ThermionEntity entity, MorphAnimationData animation, ThermionEntity entity, MorphAnimationData animation,
{List<String>? targetMeshNames}); {List<String>? targetMeshNames});
///
/// Clear all current morph animations for [entity].
///
Future clearMorphAnimationData(
ThermionEntity entity);
/// ///
/// Resets all bones in the given entity to their rest pose. /// Resets all bones in the given entity to their rest pose.
/// This should be done before every call to addBoneAnimation. /// This should be done before every call to addBoneAnimation.

View File

@@ -599,6 +599,18 @@ class ThermionViewerFFI extends ThermionViewer {
return getAnimationDuration(entity, index); 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);
}
}
/// ///
/// ///
/// ///

View File

@@ -586,6 +586,11 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError(); throw UnimplementedError();
} }
@override
Future clearMorphAnimationData(ThermionEntity entity) {
throw UnimplementedError();
}
@override @override
Future setMorphAnimationData( Future setMorphAnimationData(
ThermionEntity entity, MorphAnimationData animation, ThermionEntity entity, MorphAnimationData animation,

View File

@@ -87,6 +87,9 @@ namespace thermion_filament
int numFrames, int numFrames,
float frameLengthInMs); float frameLengthInMs);
void clearMorphAnimationBuffer(
EntityId entityId);
bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count); bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count);
math::mat4f getLocalTransform(EntityId entityId); math::mat4f getLocalTransform(EntityId entityId);

View File

@@ -136,6 +136,9 @@ extern "C"
int numMorphTargets, int numMorphTargets,
int numFrames, int numFrames,
float frameLengthInMs); float frameLengthInMs);
EMSCRIPTEN_KEEPALIVE void clear_morph_animation(
void *sceneManager,
EntityId entity);
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose( EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(
void *sceneManager, void *sceneManager,

View File

@@ -781,6 +781,27 @@ namespace thermion_filament
return true; 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) bool SceneManager::setMaterialColor(EntityId entityId, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a)
{ {

View File

@@ -405,7 +405,7 @@ extern "C"
return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights); return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights);
} }
bool set_morph_animation( EMSCRIPTEN_KEEPALIVE bool set_morph_animation(
void *sceneManager, void *sceneManager,
EntityId asset, EntityId asset,
const float *const morphData, const float *const morphData,
@@ -418,6 +418,10 @@ extern "C"
return result; 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) EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(void *sceneManager, EntityId entityId)
{ {
((SceneManager *)sceneManager)->resetBones(entityId); ((SceneManager *)sceneManager)->resetBones(entityId);