mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-18 07:35:19 +00:00
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:
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user