separate Gltf/Morph/BoneAnimationComponentManager definitions
move gltf animation instantiation to GltfAnimationComponentManager (this helps ensure we are creating the component on the correct entity)
This commit is contained in:
@@ -51,24 +51,25 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
await _thermionViewer!.destroyAsset(_asset!);
|
||||
_asset = null;
|
||||
}
|
||||
if (uri == null) {
|
||||
return;
|
||||
}
|
||||
_asset = await _thermionViewer!.loadGltf(uri);
|
||||
await _asset!.transformToUnitCube();
|
||||
final animations = await _asset!.getGltfAnimationNames();
|
||||
final durations = await Future.wait(List.generate(
|
||||
animations.length, (i) => _asset!.getGltfAnimationDuration(i)));
|
||||
|
||||
final labels = animations
|
||||
.asMap()
|
||||
.map((index, animation) =>
|
||||
MapEntry(index, "$animation (${durations[index]}s"))
|
||||
.values;
|
||||
gltfAnimations.clear();
|
||||
gltfAnimations.addAll(labels);
|
||||
selectedGltfAnimation = 0;
|
||||
_loaded = uri;
|
||||
if (uri != null) {
|
||||
_asset = await _thermionViewer!.loadGltf(uri);
|
||||
await _asset!.transformToUnitCube();
|
||||
final animations = await _asset!.getGltfAnimationNames();
|
||||
final durations = await Future.wait(List.generate(
|
||||
animations.length, (i) => _asset!.getGltfAnimationDuration(i)));
|
||||
|
||||
final labels = animations
|
||||
.asMap()
|
||||
.map((index, animation) =>
|
||||
MapEntry(index, "$animation (${durations[index]}s"))
|
||||
.values;
|
||||
gltfAnimations.clear();
|
||||
gltfAnimations.addAll(labels);
|
||||
selectedGltfAnimation = 0;
|
||||
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@@ -123,19 +124,19 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
child: Row(children: [
|
||||
Text("Asset: "),
|
||||
DropdownButton<String>(
|
||||
const Text("Asset: "),
|
||||
DropdownButton<String?>(
|
||||
value: _loaded,
|
||||
items: [_droneUri, _cubeUri]
|
||||
.map((uri) => DropdownMenuItem<String>(
|
||||
items: [_droneUri, _cubeUri, null]
|
||||
.map((uri) => DropdownMenuItem<String?>(
|
||||
value: uri,
|
||||
child: Text(
|
||||
uri,
|
||||
style: TextStyle(fontSize: 12),
|
||||
uri ?? "None",
|
||||
style: const TextStyle(fontSize: 12),
|
||||
)))
|
||||
.toList(),
|
||||
onChanged: _load),
|
||||
Text("Animation: "),
|
||||
const Text("Animation: "),
|
||||
DropdownButton<String>(
|
||||
value: selectedGltfAnimation == -1
|
||||
? null
|
||||
@@ -143,9 +144,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
items: gltfAnimations
|
||||
.map((animation) => DropdownMenuItem<String>(
|
||||
value: animation,
|
||||
child: Text(
|
||||
child: Text(
|
||||
animation,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: const TextStyle(fontSize: 12),
|
||||
)))
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
@@ -160,7 +161,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
icon: const Icon(Icons.play_arrow)),
|
||||
IconButton(
|
||||
onPressed: _stopGltfAnimation, icon: const Icon(Icons.stop))
|
||||
])))
|
||||
]))),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,19 +19,23 @@
|
||||
|
||||
<title>quickstart</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<script>
|
||||
// The value below is injected by flutter build, do not touch.
|
||||
const serviceWorkerVersion = null;
|
||||
</script>
|
||||
<script src="flutter.js" defer></script>
|
||||
|
||||
<script type="text/javascript" src="./thermion_dart.js"></script>
|
||||
<script type="module">
|
||||
<script type="module">
|
||||
try {
|
||||
window.thermion_dart = await thermion_dart();
|
||||
console.log("set thermion_dart");
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// The value below is injected by flutter build, do not touch.
|
||||
const serviceWorkerVersion = null;
|
||||
</script>
|
||||
|
||||
<script src="flutter.js" defer></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -3394,9 +3394,9 @@ external bool AnimationManager_setMorphTargetWeights(
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TAnimationManager>, ffi.Pointer<TSceneAsset>,
|
||||
ffi.Bool Function(ffi.Pointer<TAnimationManager>, ffi.Pointer<TSceneAsset>,
|
||||
ffi.Int, ffi.Int)>(isLeaf: true)
|
||||
external void AnimationManager_setGltfAnimationFrame(
|
||||
external bool AnimationManager_setGltfAnimationFrame(
|
||||
ffi.Pointer<TAnimationManager> tAnimationManager,
|
||||
ffi.Pointer<TSceneAsset> tSceneAsset,
|
||||
int animationIndex,
|
||||
|
||||
@@ -255,7 +255,7 @@ sealed class Struct extends NativeType {
|
||||
Struct(this._address);
|
||||
|
||||
static create<T extends Struct>() {
|
||||
switch (T) {
|
||||
switch (T) {
|
||||
case double4x4:
|
||||
final ptr = double4x4.stackAlloc();
|
||||
final arr1 =
|
||||
@@ -267,7 +267,7 @@ sealed class Struct extends NativeType {
|
||||
final arr4 =
|
||||
Array<Float64>._((numElements: 4, addr: ptr.cast<Float64>() + 96));
|
||||
return double4x4(arr1, arr2, arr3, arr4, ptr) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1831,7 +1831,6 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
);
|
||||
external void _GltfResourceLoader_createRenderThread(
|
||||
Pointer<TEngine> tEngine,
|
||||
Pointer<Char> relativeResourcePath,
|
||||
Pointer<
|
||||
self
|
||||
.NativeFunction<void Function(PointerClass<TGltfResourceLoader>)>>
|
||||
@@ -1895,7 +1894,6 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
);
|
||||
external Pointer<TGltfResourceLoader> _GltfResourceLoader_create(
|
||||
Pointer<TEngine> tEngine,
|
||||
Pointer<Char> relativeResourcePath,
|
||||
);
|
||||
external void _GltfResourceLoader_destroy(
|
||||
Pointer<TEngine> tEngine,
|
||||
@@ -2069,14 +2067,30 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
JSBigInt frameTimeInNanos,
|
||||
);
|
||||
external void _AnimationManager_addAnimationComponent(
|
||||
external bool _AnimationManager_addGltfAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
);
|
||||
external bool _AnimationManager_removeGltfAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
);
|
||||
external void _AnimationManager_addMorphAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
EntityId entityId,
|
||||
);
|
||||
external void _AnimationManager_removeAnimationComponent(
|
||||
external void _AnimationManager_removeMorphAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
EntityId entityId,
|
||||
);
|
||||
external bool _AnimationManager_addBoneAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
);
|
||||
external bool _AnimationManager_removeBoneAnimationComponent(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
);
|
||||
external bool _AnimationManager_setMorphAnimation(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
EntityId entityId,
|
||||
@@ -2094,7 +2108,7 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
);
|
||||
external void _AnimationManager_addBoneAnimation(
|
||||
external bool _AnimationManager_addBoneAnimation(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
int skinIndex,
|
||||
@@ -2126,9 +2140,9 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
int boneIndex,
|
||||
Pointer<Float32> out,
|
||||
);
|
||||
external void _AnimationManager_playAnimation(
|
||||
external bool _AnimationManager_playGltfAnimation(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
int index,
|
||||
bool loop,
|
||||
bool reverse,
|
||||
@@ -2136,21 +2150,21 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
double crossfade,
|
||||
double startOffset,
|
||||
);
|
||||
external void _AnimationManager_stopAnimation(
|
||||
external bool _AnimationManager_stopGltfAnimation(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
int index,
|
||||
);
|
||||
external double _AnimationManager_getAnimationDuration(
|
||||
external double _AnimationManager_getGltfAnimationDuration(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
int animationIndex,
|
||||
);
|
||||
external int _AnimationManager_getAnimationCount(
|
||||
external int _AnimationManager_getGltfAnimationCount(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
);
|
||||
external void _AnimationManager_getAnimationName(
|
||||
external void _AnimationManager_getGltfAnimationName(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> sceneAsset,
|
||||
Pointer<Char> outPtr,
|
||||
@@ -2189,7 +2203,7 @@ extension type NativeLibrary(JSObject _) implements JSObject {
|
||||
Pointer<Float32> morphData,
|
||||
int numWeights,
|
||||
);
|
||||
external void _AnimationManager_setGltfAnimationFrame(
|
||||
external bool _AnimationManager_setGltfAnimationFrame(
|
||||
Pointer<TAnimationManager> tAnimationManager,
|
||||
Pointer<TSceneAsset> tSceneAsset,
|
||||
int animationIndex,
|
||||
@@ -5133,12 +5147,11 @@ void GltfAssetLoader_createRenderThread(
|
||||
|
||||
void GltfResourceLoader_createRenderThread(
|
||||
self.Pointer<TEngine> tEngine,
|
||||
self.Pointer<Char> relativeResourcePath,
|
||||
self.Pointer<self.NativeFunction<void Function(Pointer<TGltfResourceLoader>)>>
|
||||
callback,
|
||||
) {
|
||||
final result = _lib._GltfResourceLoader_createRenderThread(
|
||||
tEngine.cast(), relativeResourcePath, callback.cast());
|
||||
tEngine.cast(), callback.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5263,10 +5276,8 @@ void Gizmo_createRenderThread(
|
||||
|
||||
self.Pointer<TGltfResourceLoader> GltfResourceLoader_create(
|
||||
self.Pointer<TEngine> tEngine,
|
||||
self.Pointer<Char> relativeResourcePath,
|
||||
) {
|
||||
final result =
|
||||
_lib._GltfResourceLoader_create(tEngine.cast(), relativeResourcePath);
|
||||
final result = _lib._GltfResourceLoader_create(tEngine.cast());
|
||||
return self.Pointer<TGltfResourceLoader>(result);
|
||||
}
|
||||
|
||||
@@ -5641,24 +5652,60 @@ void AnimationManager_update(
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_addAnimationComponent(
|
||||
bool AnimationManager_addGltfAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_addGltfAnimationComponent(
|
||||
tAnimationManager.cast(), tSceneAsset.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AnimationManager_removeGltfAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_removeGltfAnimationComponent(
|
||||
tAnimationManager.cast(), tSceneAsset.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_addMorphAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
DartEntityId entityId,
|
||||
) {
|
||||
final result = _lib._AnimationManager_addAnimationComponent(
|
||||
final result = _lib._AnimationManager_addMorphAnimationComponent(
|
||||
tAnimationManager.cast(), entityId);
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_removeAnimationComponent(
|
||||
void AnimationManager_removeMorphAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
DartEntityId entityId,
|
||||
) {
|
||||
final result = _lib._AnimationManager_removeAnimationComponent(
|
||||
final result = _lib._AnimationManager_removeMorphAnimationComponent(
|
||||
tAnimationManager.cast(), entityId);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AnimationManager_addBoneAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_addBoneAnimationComponent(
|
||||
tAnimationManager.cast(), tSceneAsset.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AnimationManager_removeBoneAnimationComponent(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_removeBoneAnimationComponent(
|
||||
tAnimationManager.cast(), tSceneAsset.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AnimationManager_setMorphAnimation(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
DartEntityId entityId,
|
||||
@@ -5697,7 +5744,7 @@ void AnimationManager_resetToRestPose(
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_addBoneAnimation(
|
||||
bool AnimationManager_addBoneAnimation(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
int skinIndex,
|
||||
@@ -5758,9 +5805,9 @@ void AnimationManager_getInverseBindMatrix(
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_playAnimation(
|
||||
bool AnimationManager_playGltfAnimation(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> sceneAsset,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
int index,
|
||||
bool loop,
|
||||
bool reverse,
|
||||
@@ -5768,9 +5815,9 @@ void AnimationManager_playAnimation(
|
||||
double crossfade,
|
||||
double startOffset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_playAnimation(
|
||||
final result = _lib._AnimationManager_playGltfAnimation(
|
||||
tAnimationManager.cast(),
|
||||
sceneAsset.cast(),
|
||||
tSceneAsset.cast(),
|
||||
index,
|
||||
loop,
|
||||
reverse,
|
||||
@@ -5780,42 +5827,42 @@ void AnimationManager_playAnimation(
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_stopAnimation(
|
||||
bool AnimationManager_stopGltfAnimation(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> sceneAsset,
|
||||
int index,
|
||||
) {
|
||||
final result = _lib._AnimationManager_stopAnimation(
|
||||
final result = _lib._AnimationManager_stopGltfAnimation(
|
||||
tAnimationManager.cast(), sceneAsset.cast(), index);
|
||||
return result;
|
||||
}
|
||||
|
||||
double AnimationManager_getAnimationDuration(
|
||||
double AnimationManager_getGltfAnimationDuration(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> sceneAsset,
|
||||
int animationIndex,
|
||||
) {
|
||||
final result = _lib._AnimationManager_getAnimationDuration(
|
||||
final result = _lib._AnimationManager_getGltfAnimationDuration(
|
||||
tAnimationManager.cast(), sceneAsset.cast(), animationIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
int AnimationManager_getAnimationCount(
|
||||
int AnimationManager_getGltfAnimationCount(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> sceneAsset,
|
||||
) {
|
||||
final result = _lib._AnimationManager_getAnimationCount(
|
||||
final result = _lib._AnimationManager_getGltfAnimationCount(
|
||||
tAnimationManager.cast(), sceneAsset.cast());
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_getAnimationName(
|
||||
void AnimationManager_getGltfAnimationName(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> sceneAsset,
|
||||
self.Pointer<Char> outPtr,
|
||||
int index,
|
||||
) {
|
||||
final result = _lib._AnimationManager_getAnimationName(
|
||||
final result = _lib._AnimationManager_getGltfAnimationName(
|
||||
tAnimationManager.cast(), sceneAsset.cast(), outPtr, index);
|
||||
return result;
|
||||
}
|
||||
@@ -5883,7 +5930,7 @@ bool AnimationManager_setMorphTargetWeights(
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnimationManager_setGltfAnimationFrame(
|
||||
bool AnimationManager_setGltfAnimationFrame(
|
||||
self.Pointer<TAnimationManager> tAnimationManager,
|
||||
self.Pointer<TSceneAsset> tSceneAsset,
|
||||
int animationIndex,
|
||||
|
||||
@@ -621,8 +621,12 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
@override
|
||||
Future<double> getGltfAnimationDuration(int animationIndex) async {
|
||||
return AnimationManager_getGltfAnimationDuration(
|
||||
final duration = AnimationManager_getGltfAnimationDuration(
|
||||
animationManager, asset, animationIndex);
|
||||
if (duration < 0) {
|
||||
throw Exception("Failed to get glTF animation duration");
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1030,6 +1034,18 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
///
|
||||
Future removeAnimationComponent() async {
|
||||
AnimationManager_removeGltfAnimationComponent(animationManager, this.asset);
|
||||
if (!AnimationManager_removeGltfAnimationComponent(
|
||||
animationManager, asset)) {
|
||||
throw Exception("Failed to remove glTF animation component");
|
||||
}
|
||||
if (!AnimationManager_removeBoneAnimationComponent(
|
||||
animationManager, asset)) {
|
||||
throw Exception("Failed to remove bone animation component");
|
||||
}
|
||||
AnimationManager_removeMorphAnimationComponent(animationManager, entity);
|
||||
|
||||
for (final child in await getChildEntities()) {
|
||||
AnimationManager_removeMorphAnimationComponent(animationManager, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,14 +116,14 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future render() async {
|
||||
await withVoidCallback((requestId,cb) =>
|
||||
RenderTicker_renderRenderThread(app.renderTicker, 0.toBigInt, requestId,cb));
|
||||
await withVoidCallback((requestId, cb) => RenderTicker_renderRenderThread(
|
||||
app.renderTicker, 0.toBigInt, requestId, cb));
|
||||
if (FILAMENT_SINGLE_THREADED) {
|
||||
await withVoidCallback(
|
||||
(requestId,cb) => Engine_executeRenderThread(app.engine, requestId,cb));
|
||||
await withVoidCallback((requestId, cb) =>
|
||||
Engine_executeRenderThread(app.engine, requestId, cb));
|
||||
} else {
|
||||
await withVoidCallback(
|
||||
(requestId,cb) => Engine_flushAndWaitRenderThread(app.engine, requestId,cb));
|
||||
await withVoidCallback((requestId, cb) =>
|
||||
Engine_flushAndWaitRenderThread(app.engine, requestId, cb));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,8 +300,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
}
|
||||
|
||||
if (skybox != null) {
|
||||
await withVoidCallback(
|
||||
(requestId,cb) => Engine_destroySkyboxRenderThread(app.engine, skybox!, requestId,cb));
|
||||
await withVoidCallback((requestId, cb) =>
|
||||
Engine_destroySkyboxRenderThread(app.engine, skybox!, requestId, cb));
|
||||
skybox = null;
|
||||
}
|
||||
}
|
||||
@@ -313,8 +313,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
Future removeIbl() async {
|
||||
if (indirectLight != null) {
|
||||
Scene_setIndirectLight(scene.scene, nullptr);
|
||||
await withVoidCallback((requestId,cb) => Engine_destroyIndirectLightRenderThread(
|
||||
app.engine, indirectLight!, requestId,cb));
|
||||
await withVoidCallback((requestId, cb) =>
|
||||
Engine_destroyIndirectLightRenderThread(
|
||||
app.engine, indirectLight!, requestId, cb));
|
||||
indirectLight = null;
|
||||
}
|
||||
}
|
||||
@@ -439,7 +440,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future destroyAsset(covariant FFIAsset asset) async {
|
||||
await asset.removeAnimationComponent();
|
||||
await scene.remove(asset);
|
||||
|
||||
if (asset.boundingBoxAsset != null) {
|
||||
await scene.remove(asset.boundingBoxAsset! as FFIAsset);
|
||||
await FilamentApp.instance!.destroyAsset(asset.boundingBoxAsset!);
|
||||
|
||||
@@ -129,7 +129,7 @@ extern "C"
|
||||
const float *const morphData,
|
||||
int numWeights);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setGltfAnimationFrame(
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_setGltfAnimationFrame(
|
||||
TAnimationManager *tAnimationManager,
|
||||
TSceneAsset *tSceneAsset,
|
||||
int animationIndex,
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace thermion
|
||||
void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, uint32_t requestId, VoidCallback onComplete);
|
||||
|
||||
void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
|
||||
void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
|
||||
void GltfResourceLoader_createRenderThread(TEngine *tEngine, void (*callback)(TGltfResourceLoader *));
|
||||
void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, uint32_t requestId, VoidCallback onComplete);
|
||||
void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||
void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, uint32_t requestId, VoidCallback onComplete);
|
||||
|
||||
19
thermion_dart/native/include/components/Animation.hpp
Normal file
19
thermion_dart/native/include/components/Animation.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
||||
|
||||
struct Animation
|
||||
{
|
||||
time_point_t start = time_point_t::max();
|
||||
float startOffset;
|
||||
bool loop = false;
|
||||
bool reverse = false;
|
||||
float durationInSecs = 0;
|
||||
};
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TransformManager.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/norm.h>
|
||||
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include <utils/SingleInstanceComponentManager.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
template class std::vector<float>;
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
using namespace std::chrono;
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
||||
|
||||
struct Animation
|
||||
{
|
||||
time_point_t start = time_point_t::max();
|
||||
float startOffset;
|
||||
bool loop = false;
|
||||
bool reverse = false;
|
||||
float durationInSecs = 0;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
/// The status of an animation embedded in a glTF object.
|
||||
/// @param index refers to the index of the animation in the animations property of the underlying object.
|
||||
///
|
||||
struct GltfAnimation : Animation
|
||||
{
|
||||
int index = -1;
|
||||
};
|
||||
|
||||
//
|
||||
// The status of a morph target animation created dynamically at runtime (not glTF embedded).
|
||||
//
|
||||
struct MorphAnimation : Animation
|
||||
{
|
||||
int lengthInFrames;
|
||||
float frameLengthInMs = 0;
|
||||
std::vector<float> frameData;
|
||||
std::vector<int> morphIndices;
|
||||
};
|
||||
|
||||
struct BoneAnimation : Animation {
|
||||
int lengthInFrames;
|
||||
size_t boneIndex;
|
||||
size_t skinIndex = 0;
|
||||
float frameLengthInMs = 0;
|
||||
std::vector<math::mat4f> frameData;
|
||||
float fadeOutInSecs = 0;
|
||||
float fadeInInSecs = 0;
|
||||
float maxDelta = 1.0f;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct BoneAnimationComponent
|
||||
{
|
||||
FilamentInstance * target;
|
||||
std::vector<BoneAnimation> animations;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct MorphAnimationComponent
|
||||
{
|
||||
std::vector<MorphAnimation> animations;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct GltfAnimationComponent
|
||||
{
|
||||
FilamentInstance * target;
|
||||
// the index of the last active glTF animation,
|
||||
// used to cross-fade
|
||||
int fadeGltfAnimationIndex = -1;
|
||||
float fadeDuration = 0.0f;
|
||||
float fadeOutAnimationStart = 0.0f;
|
||||
std::vector<GltfAnimation> animations;
|
||||
};
|
||||
|
||||
|
||||
class GltfAnimationComponentManager : public utils::SingleInstanceComponentManager<GltfAnimationComponent> {
|
||||
public:
|
||||
GltfAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~GltfAnimationComponentManager() = default;
|
||||
void addAnimationComponent(FilamentInstance *target);
|
||||
void removeAnimationComponent(FilamentInstance *target);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
|
||||
class BoneAnimationComponentManager : public utils::SingleInstanceComponentManager<BoneAnimationComponent> {
|
||||
public:
|
||||
BoneAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~BoneAnimationComponentManager() {};
|
||||
|
||||
void addAnimationComponent(FilamentInstance *target);
|
||||
void removeAnimationComponent(FilamentInstance *target);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
|
||||
class MorphAnimationComponentManager : public utils::SingleInstanceComponentManager<MorphAnimationComponent> {
|
||||
public:
|
||||
MorphAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~MorphAnimationComponentManager() {};
|
||||
|
||||
void addAnimationComponent(Entity entity);
|
||||
void removeAnimationComponent(Entity entity);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#include <gltfio/FilamentInstance.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/norm.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace std::chrono;
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
||||
|
||||
struct Animation
|
||||
{
|
||||
time_point_t start = time_point_t::max();
|
||||
float startOffset;
|
||||
bool loop = false;
|
||||
bool reverse = false;
|
||||
float durationInSecs = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TransformManager.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/norm.h>
|
||||
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include <utils/SingleInstanceComponentManager.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "components/Animation.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
struct BoneAnimation : Animation {
|
||||
int lengthInFrames;
|
||||
size_t boneIndex;
|
||||
size_t skinIndex = 0;
|
||||
float frameLengthInMs = 0;
|
||||
std::vector<math::mat4f> frameData;
|
||||
float fadeOutInSecs = 0;
|
||||
float fadeInInSecs = 0;
|
||||
float maxDelta = 1.0f;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct BoneAnimationComponent
|
||||
{
|
||||
filament::gltfio::FilamentInstance * target;
|
||||
std::vector<BoneAnimation> animations;
|
||||
};
|
||||
|
||||
class BoneAnimationComponentManager : public utils::SingleInstanceComponentManager<BoneAnimationComponent> {
|
||||
public:
|
||||
BoneAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~BoneAnimationComponentManager() {};
|
||||
|
||||
void addAnimationComponent(FilamentInstance *target);
|
||||
void removeAnimationComponent(FilamentInstance *target);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TransformManager.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/norm.h>
|
||||
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include <utils/SingleInstanceComponentManager.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "components/Animation.hpp"
|
||||
|
||||
template class std::vector<float>;
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
using namespace std::chrono;
|
||||
|
||||
/// @brief
|
||||
/// The status of an animation embedded in a glTF object.
|
||||
/// @param index refers to the index of the animation in the animations property of the underlying object.
|
||||
///
|
||||
struct GltfAnimation : Animation
|
||||
{
|
||||
int index = -1;
|
||||
};
|
||||
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct GltfAnimationComponent
|
||||
{
|
||||
filament::gltfio::FilamentInstance * target;
|
||||
// the index of the last active glTF animation,
|
||||
// used to cross-fade
|
||||
int fadeGltfAnimationIndex = -1;
|
||||
float fadeDuration = 0.0f;
|
||||
float fadeOutAnimationStart = 0.0f;
|
||||
std::vector<GltfAnimation> animations;
|
||||
};
|
||||
|
||||
class GltfAnimationComponentManager : public utils::SingleInstanceComponentManager<GltfAnimationComponent> {
|
||||
public:
|
||||
GltfAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~GltfAnimationComponentManager() = default;
|
||||
void addAnimationComponent(FilamentInstance *target);
|
||||
void removeAnimationComponent(FilamentInstance *target);
|
||||
|
||||
bool addGltfAnimation(FilamentInstance *target, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset);
|
||||
// GltfAnimationComponent getAnimationComponentInstance(FilamentInstance *target);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TransformManager.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/norm.h>
|
||||
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include <utils/SingleInstanceComponentManager.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "components/Animation.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
using namespace std::chrono;
|
||||
|
||||
//
|
||||
// The status of a morph target animation created dynamically at runtime (not glTF embedded).
|
||||
//
|
||||
struct MorphAnimation : Animation
|
||||
{
|
||||
int lengthInFrames;
|
||||
float frameLengthInMs = 0;
|
||||
std::vector<float> frameData;
|
||||
std::vector<int> morphIndices;
|
||||
};
|
||||
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
struct MorphAnimationComponent
|
||||
{
|
||||
std::vector<MorphAnimation> animations;
|
||||
};
|
||||
|
||||
class MorphAnimationComponentManager : public utils::SingleInstanceComponentManager<MorphAnimationComponent> {
|
||||
public:
|
||||
MorphAnimationComponentManager(
|
||||
filament::TransformManager &transformManager,
|
||||
filament::RenderableManager &renderableManager) :
|
||||
mTransformManager(transformManager), mRenderableManager(renderableManager) {};
|
||||
~MorphAnimationComponentManager() {};
|
||||
|
||||
void addAnimationComponent(Entity entity);
|
||||
void removeAnimationComponent(Entity entity);
|
||||
void update();
|
||||
|
||||
private:
|
||||
filament::TransformManager &mTransformManager;
|
||||
filament::RenderableManager &mRenderableManager;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -9,10 +9,12 @@
|
||||
#include "c_api/APIBoundaryTypes.h"
|
||||
|
||||
#include "components/CollisionComponentManager.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "GltfSceneAssetInstance.hpp"
|
||||
#include "GltfSceneAsset.hpp"
|
||||
#include "SceneAsset.hpp"
|
||||
#include "components/GltfAnimationComponentManager.hpp"
|
||||
#include "components/MorphAnimationComponentManager.hpp"
|
||||
#include "components/BoneAnimationComponentManager.hpp"
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "scene/GltfSceneAsset.hpp"
|
||||
#include "scene/SceneAsset.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/CollisionComponentManager.hpp"
|
||||
|
||||
#include "scene/SceneAsset.hpp"
|
||||
|
||||
@@ -31,49 +31,93 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addGltfAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
animationManager->addGltfAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->addGltfAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_removeGltfAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
animationManager->removeGltfAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->removeGltfAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addBoneAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
animationManager->addBoneAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->addBoneAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_removeBoneAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
animationManager->removeBoneAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->removeBoneAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,15 +168,27 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPose(TAnimationManager *tAnimationManager, TSceneAsset *sceneAsset)
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPose(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto *animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
auto asset = reinterpret_cast<SceneAsset *>(sceneAsset);
|
||||
if (asset->getType() == SceneAsset::SceneAssetType::Gltf && asset->isInstance())
|
||||
{
|
||||
auto *instance = reinterpret_cast<GltfSceneAssetInstance *>(asset);
|
||||
animationManager->resetToRestPose(instance);
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
Log("Error - incorrect asset type, cannot reset to reset pose");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
animationManager->resetToRestPose(instance);
|
||||
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addBoneAnimation(
|
||||
@@ -297,19 +353,31 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setGltfAnimationFrame(
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_setGltfAnimationFrame(
|
||||
TAnimationManager *tAnimationManager,
|
||||
TSceneAsset *tSceneAsset,
|
||||
int animationIndex,
|
||||
int frame)
|
||||
{
|
||||
auto *animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
auto asset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (asset->getType() == SceneAsset::SceneAssetType::Gltf && asset->isInstance())
|
||||
{
|
||||
auto *instance = reinterpret_cast<GltfSceneAssetInstance *>(asset);
|
||||
animationManager->setGltfAnimationFrame(instance, animationIndex, frame);
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
animationManager->setGltfAnimationFrame(instance, animationIndex, frame);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE float AnimationManager_getGltfAnimationDuration(
|
||||
@@ -320,7 +388,7 @@ extern "C"
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/BoneAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/GltfAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
@@ -15,9 +15,75 @@ namespace thermion
|
||||
}
|
||||
}
|
||||
|
||||
bool GltfAnimationComponentManager::addGltfAnimation(FilamentInstance *target, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset) {
|
||||
|
||||
EntityInstanceBase::Type componentInstance = getInstance(target->getRoot());
|
||||
|
||||
auto &animationComponent = this->elementAt<0>(componentInstance);
|
||||
|
||||
animationComponent.target = target;
|
||||
|
||||
if (replaceActive)
|
||||
{
|
||||
if (animationComponent.animations.size() > 0)
|
||||
{
|
||||
auto &last = animationComponent.animations.back();
|
||||
animationComponent.fadeGltfAnimationIndex = last.index;
|
||||
animationComponent.fadeDuration = crossfade;
|
||||
auto now = high_resolution_clock::now();
|
||||
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last.start).count()) / 1000.0f;
|
||||
animationComponent.fadeOutAnimationStart = elapsedInSecs;
|
||||
animationComponent.animations.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (crossfade > 0)
|
||||
{
|
||||
Log("ERROR: crossfade only supported when replaceActive is true.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
|
||||
GltfAnimation animation;
|
||||
animation.startOffset = startOffset;
|
||||
animation.index = index;
|
||||
animation.start = std::chrono::high_resolution_clock::now();
|
||||
animation.loop = loop;
|
||||
animation.reverse = reverse;
|
||||
animation.durationInSecs = target->getAnimator()->getAnimationDuration(index);
|
||||
|
||||
bool found = false;
|
||||
|
||||
// don't play the animation if it's already running
|
||||
for (int i = 0; i < animationComponent.animations.size(); i++)
|
||||
{
|
||||
if (animationComponent.animations[i].index == index)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
animationComponent.animations.push_back(animation);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GltfAnimationComponentManager::removeAnimationComponent(FilamentInstance *target) {
|
||||
if(hasComponent(target->getRoot())) {
|
||||
removeComponent(target->getRoot());
|
||||
TRACE("Found component, component removed");
|
||||
} else {
|
||||
TRACE("Component not found, skipping removal");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/MorphAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "scene/AnimationManager.hpp"
|
||||
#include "scene/SceneAsset.hpp"
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
@@ -334,71 +332,7 @@ namespace thermion
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_gltfAnimationComponentManager->hasComponent(instance->getEntity()))
|
||||
{
|
||||
_gltfAnimationComponentManager->addComponent(instance->getEntity());
|
||||
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
||||
return;
|
||||
}
|
||||
|
||||
auto animationComponentInstance = _gltfAnimationComponentManager->getInstance(instance->getEntity());
|
||||
|
||||
auto &animationComponent = _gltfAnimationComponentManager->elementAt<0>(animationComponentInstance);
|
||||
|
||||
animationComponent.target = instance->getInstance();
|
||||
|
||||
if (replaceActive)
|
||||
{
|
||||
if (animationComponent.animations.size() > 0)
|
||||
{
|
||||
auto &last = animationComponent.animations.back();
|
||||
animationComponent.fadeGltfAnimationIndex = last.index;
|
||||
animationComponent.fadeDuration = crossfade;
|
||||
auto now = high_resolution_clock::now();
|
||||
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last.start).count()) / 1000.0f;
|
||||
animationComponent.fadeOutAnimationStart = elapsedInSecs;
|
||||
animationComponent.animations.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (crossfade > 0)
|
||||
{
|
||||
Log("ERROR: crossfade only supported when replaceActive is true.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
|
||||
GltfAnimation animation;
|
||||
animation.startOffset = startOffset;
|
||||
animation.index = index;
|
||||
animation.start = std::chrono::high_resolution_clock::now();
|
||||
animation.loop = loop;
|
||||
animation.reverse = reverse;
|
||||
animation.durationInSecs = instance->getInstance()->getAnimator()->getAnimationDuration(index);
|
||||
|
||||
bool found = false;
|
||||
|
||||
// don't play the animation if it's already running
|
||||
for (int i = 0; i < animationComponent.animations.size(); i++)
|
||||
{
|
||||
if (animationComponent.animations[i].index == index)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
animationComponent.animations.push_back(animation);
|
||||
}
|
||||
_gltfAnimationComponentManager->addGltfAnimation(instance->getInstance(), index, loop, reverse, replaceActive, crossfade, startOffset);
|
||||
}
|
||||
|
||||
void AnimationManager::stopGltfAnimation(GltfSceneAssetInstance *instance, int index)
|
||||
@@ -515,35 +449,47 @@ namespace thermion
|
||||
|
||||
bool AnimationManager::addGltfAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_gltfAnimationComponentManager->addAnimationComponent(instance->getInstance());
|
||||
TRACE("Added glTF animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeGltfAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_gltfAnimationComponentManager->removeAnimationComponent(instance->getInstance());
|
||||
TRACE("Removed glTF animation component");
|
||||
}
|
||||
|
||||
bool AnimationManager::addBoneAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_boneAnimationComponentManager->addAnimationComponent(instance->getInstance());
|
||||
TRACE("Added bone animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeBoneAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_boneAnimationComponentManager->removeAnimationComponent(instance->getInstance());
|
||||
TRACE("Removed bone animation component");
|
||||
}
|
||||
|
||||
bool AnimationManager::addMorphAnimationComponent(utils::Entity entity)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_morphAnimationComponentManager->addAnimationComponent(entity);
|
||||
TRACE("Added morph animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeMorphAnimationComponent(utils::Entity entity)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_morphAnimationComponentManager->removeAnimationComponent(entity);
|
||||
TRACE("Removed morph animation component");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,19 +12,18 @@
|
||||
#include <filament/VertexBuffer.h>
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <gltfio/AssetLoader.h>
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/FilamentAsset.h>
|
||||
#include <gltfio/FilamentInstance.h>
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/CollisionComponentManager.hpp"
|
||||
|
||||
#include "scene/SceneAsset.hpp"
|
||||
|
||||
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
|
||||
@@ -38,52 +38,69 @@ void main() async {
|
||||
|
||||
test('set morph target weights', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
final cube = await viewer.loadGltf(
|
||||
"${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
final cube = await viewer
|
||||
.loadGltf("${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
|
||||
await viewer.addToScene(cube);
|
||||
|
||||
await testHelper.capture(viewer.view, "cube_no_morph");
|
||||
|
||||
await cube.setMorphTargetWeights((await cube.getChildEntities()).first, [1.0]);
|
||||
await cube
|
||||
.setMorphTargetWeights((await cube.getChildEntities()).first, [1.0]);
|
||||
await testHelper.capture(viewer.view, "cube_with_morph");
|
||||
|
||||
}, bg:kRed, cameraPosition: Vector3(3, 2, 6));
|
||||
}, bg: kRed, cameraPosition: Vector3(3, 2, 6));
|
||||
});
|
||||
|
||||
test('set morph target animation', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
final cube = await viewer.loadGltf(
|
||||
"${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
final cube = await viewer
|
||||
.loadGltf("${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
|
||||
await viewer.addToScene(cube);
|
||||
|
||||
await testHelper.capture(viewer.view, "cube_morph_animation_reset");
|
||||
|
||||
var morphData = MorphAnimationData(Float32List.fromList([1.0]), ["Key 1"],
|
||||
frameLengthInMs: 1000.0 / 60.0);
|
||||
|
||||
await cube.setMorphAnimationData(morphData);
|
||||
await viewer.render();
|
||||
await testHelper.capture(viewer.view, "cube_with_morph_animation");
|
||||
|
||||
}, bg:kRed, cameraPosition: Vector3(3, 2, -6));
|
||||
await testHelper.capture(viewer.view, "cube_morph_animation_playing");
|
||||
}, bg: kRed, cameraPosition: Vector3(3, 2, -6));
|
||||
});
|
||||
|
||||
test('get gltf animation names', () async {
|
||||
test('play/stop gltf animation', () async {
|
||||
await testHelper.withViewer((viewer) async {
|
||||
final cube = await viewer
|
||||
.loadGltf("${testHelper.testDir}/assets/cube_with_morph_targets.glb");
|
||||
|
||||
await viewer.addToScene(cube);
|
||||
await testHelper.capture(viewer.view, "gltf_animation_stopped");
|
||||
|
||||
final animationNames = await cube.getGltfAnimationNames();
|
||||
|
||||
expect(animationNames.first, "CubeAction");
|
||||
|
||||
await testHelper.capture(viewer.view, "gltf_animation_rest");
|
||||
|
||||
await viewer.render();
|
||||
|
||||
await cube.playGltfAnimation(0);
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 750));
|
||||
await viewer.render();
|
||||
await testHelper.capture(viewer.view, "gltf_animation_started");
|
||||
await viewer.render();
|
||||
await Future.delayed(Duration(milliseconds: 1000));
|
||||
await viewer.render();
|
||||
await cube.stopGltfAnimation(0);
|
||||
await viewer.render();
|
||||
await testHelper.capture(viewer.view, "gltf_animation_stopped");
|
||||
|
||||
await viewer.destroyAsset(cube);
|
||||
|
||||
await viewer.render();
|
||||
|
||||
await testHelper.capture(viewer.view, "gltf_asset_destroyed");
|
||||
}, bg: kRed);
|
||||
});
|
||||
}
|
||||
|
||||
1
thermion_dart/test/assets/BusterDrone
Symbolic link
1
thermion_dart/test/assets/BusterDrone
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../examples/assets/BusterDrone
|
||||
Reference in New Issue
Block a user