Timeline animation clips (#122)

This is a super initial version of animation clips in timeline.


https://github.com/storytold/storyteller-bevy/assets/10376144/b649162b-8758-4662-bfb9-6a492563b9f7


https://github.com/storytold/storyteller-bevy/assets/10376144/a5815685-bf52-4413-8828-d86051bf850a

---------

Co-authored-by: Danny McGee <dannymcgee@gmail.com>
This commit is contained in:
Lee-Orr
2024-04-05 02:17:06 -04:00
committed by GitHub
parent 0f4eda3e82
commit d2ae2f5744
8 changed files with 620 additions and 62 deletions
@@ -147,6 +147,7 @@ export class MediaLibraryDialogElement extends DialogBaseElement {
MediaFileType.Glb,
MediaFileType.Gltf,
MediaFileType.ScnRon,
MediaFileType.Mocap
],
});
@@ -198,11 +199,11 @@ export class MediaLibraryDialogElement extends DialogBaseElement {
this.#transientFileInput = document.createElement("input");
this.#transientFileInput.type = "file";
this.#transientFileInput.accept = match (this._activeCategory.mediaClass, {
[MediaFileClass.Animation]: () => ".bvh,.fbx,.gltf",
[MediaFileClass.Animation]: () => ".bvh,.fbx,.gltf,.glb",
[MediaFileClass.Audio]: () => ".wav,.mp3",
[MediaFileClass.Character]: () => ".fbx,.gltf",
[MediaFileClass.Prop]: () => ".fbx,.gltf",
[MediaFileClass.Scene]: () => ".fbx,.gltf,.scn.ron",
[MediaFileClass.Character]: () => ".fbx,.gltf,.glb",
[MediaFileClass.Prop]: () => ".fbx,.gltf,.glb",
[MediaFileClass.Scene]: () => ".fbx,.gltf,.glb,.scn.ron",
_: () => "",
});
this.#transientFileInput.multiple = false;
@@ -267,8 +268,48 @@ export class MediaLibraryDialogElement extends DialogBaseElement {
}
#addAnimation(): void {
// TODO: Make this actually work
console.warn("Adding animations not yet implemented!");
const token = this._selected[0];
if (!this._mediaFiles) {
console.error("Expected `_mediaFiles` map to be present when spawning assets");
this.dispatchEvent(new CustomEvent("close"));
return;
}
const mediaFile = this._mediaFiles.get(token);
if (!mediaFile) {
console.error(`Attempted to spawn an invalid token: "${token}"`);
this.dispatchEvent(new CustomEvent("close"));
return;
}
const ext = mediaFile.extension;
if (!ext) {
console.error("Expected media file to have a non-null `extension` field");
this.dispatchEvent(new CustomEvent("close"));
return;
}
const asset = {
path: `remote://${token}${ext}`,
name: mediaFile.displayName,
};
const skeletonSelected = this._sceneData.selectedObject?.["id"];
if (!skeletonSelected) {
console.error(`Attempted to an animation without a selected skeleton`);
this.dispatchEvent(new CustomEvent("close"));
return;
}
let retargetingType = studio.ClipRetargeting.UseOrigin;
if (mediaFile.subtype === MediaFileSubtype.Mixamo) {
retargetingType = studio.ClipRetargeting.Mixamo;
} else if (mediaFile.subtype === MediaFileSubtype.MocapNet) {
retargetingType = studio.ClipRetargeting.MocapNet
}
console.log(`Inserting Animation ${asset.name} for skeleton ${skeletonSelected}`)
studio.insertClip(skeletonSelected, asset.path, asset.name, retargetingType);
this.dispatchEvent(new CustomEvent("close"));
}