From 4f177bcb8a50411d01276c7acd07caad4d2a7d91 Mon Sep 17 00:00:00 2001 From: Tanish Manku Date: Fri, 31 Jan 2025 15:51:03 -0800 Subject: [PATCH] Save manager userdata field support --- app/pages/PageEnigma/Editor/editor.ts | 2 +- app/pages/PageEnigma/Editor/save_manager.ts | 4 +- .../proxy/storyteller_proxy_3d_object.ts | 11 ++-- .../proxy/storyteller_proxy_scene.ts | 6 +-- .../proxy/storyteller_proxy_timeline.ts | 50 +++++++------------ 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/app/pages/PageEnigma/Editor/editor.ts b/app/pages/PageEnigma/Editor/editor.ts index 8f4c136c2b..ea2eceb0ce 100644 --- a/app/pages/PageEnigma/Editor/editor.ts +++ b/app/pages/PageEnigma/Editor/editor.ts @@ -213,7 +213,7 @@ class Editor { // life cycle fix // Version and name. - this.version = 1.1; + this.version = 1.2; // Clock, scene and camera essentials. // global names this.camera_name = "::CAM::"; diff --git a/app/pages/PageEnigma/Editor/save_manager.ts b/app/pages/PageEnigma/Editor/save_manager.ts index 7ec0b5715f..819feeb609 100644 --- a/app/pages/PageEnigma/Editor/save_manager.ts +++ b/app/pages/PageEnigma/Editor/save_manager.ts @@ -181,6 +181,7 @@ export class SaveManager { this.editor.generating_preview = false; // FIX THIS LATER WITH VICCCCCCCCCCCCCCCTORRRRRRRR + console.debug("Save Scene Result: ", result); return result; // if this is an empty string it is an error. need to migrate to api manager. } @@ -260,8 +261,9 @@ export class SaveManager { this.editor.lipsync_engine, this.editor.emotion_engine, ); + console.debug("Loading Timeline", scene_json["timeline"]); await proxyTimeline.loadFromJson(scene_json["timeline"]); - + this.editor.timeline.checkEditorCanPlay(); hideEditorLoader(); diff --git a/app/pages/PageEnigma/proxy/storyteller_proxy_3d_object.ts b/app/pages/PageEnigma/proxy/storyteller_proxy_3d_object.ts index 285fa61847..fb99c0ecb1 100644 --- a/app/pages/PageEnigma/proxy/storyteller_proxy_3d_object.ts +++ b/app/pages/PageEnigma/proxy/storyteller_proxy_3d_object.ts @@ -28,7 +28,8 @@ export interface ObjectJSON { specular: number; locked: boolean; visible: boolean | undefined; - media_file_type: MediaFileType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + user_data: Record; } export class StoryTellerProxy3DObject { @@ -48,7 +49,8 @@ export class StoryTellerProxy3DObject { specular: number; locked: boolean; visible: boolean; - media_file_type: MediaFileType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + userData: Record; constructor(version: number, media_file_token: string) { this.version = version; @@ -69,7 +71,8 @@ export class StoryTellerProxy3DObject { this.specular = 0.5; this.locked = false; this.visible = true; - this.media_file_type = MediaFileType.None; + this.userData = {}; + this.userData.media_file_type = MediaFileType.None; } getColorAsHexString(object: THREE.Object3D): string { @@ -125,7 +128,7 @@ export class StoryTellerProxy3DObject { specular: this.specular, locked: this.locked, visible: this.visible, - media_file_type: this.media_file_type, + user_data: this.userData, }; return json; } diff --git a/app/pages/PageEnigma/proxy/storyteller_proxy_scene.ts b/app/pages/PageEnigma/proxy/storyteller_proxy_scene.ts index c4ba45b629..b4f8d351b7 100644 --- a/app/pages/PageEnigma/proxy/storyteller_proxy_scene.ts +++ b/app/pages/PageEnigma/proxy/storyteller_proxy_scene.ts @@ -48,9 +48,7 @@ export class StoryTellerProxyScene { proxyObject3D.specular = child.userData["specular"]; proxyObject3D.locked = child.userData["locked"]; proxyObject3D.visible = child.visible; - if (child.userData["media_file_type"] !== undefined) { - proxyObject3D.media_file_type = child.userData["media_file_type"]; - } + proxyObject3D.userData = child.userData; const json_data = await proxyObject3D.toJSON(); return json_data; } @@ -98,6 +96,7 @@ export class StoryTellerProxyScene { for (const pchild of this.scene.scene.children) { if (this.version >= 1.0) { if (pchild.userData["media_id"] != undefined) { + console.debug("Object JSON:", pchild.toJSON()) results.push(await this.getChildren(pchild)); } } else { @@ -108,6 +107,7 @@ export class StoryTellerProxyScene { } else { console.log("Scene doesn't exist needs to be assigned"); } + console.debug("Scene saved.", results); return results; } diff --git a/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts b/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts index 5af843f04d..c99a3a6d99 100644 --- a/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts +++ b/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts @@ -10,6 +10,8 @@ import EmotionEngine from "../Editor/Engines/emotion_engine"; import LipSyncEngine from "../Editor/Engines/lip_sync_engine"; import { TimeLine } from "../Editor/timeline"; import TransformEngine from "../Editor/Engines/transform_engine"; +import Ijson from "~/interfaces/Ijson"; +import { ClipGroup, ClipType } from "~/enums"; export class StoryTellerProxyTimeline { timeline: TimeLine; @@ -36,7 +38,7 @@ export class StoryTellerProxyTimeline { this.emotion_engine = emotion_engine; } - private async getItemsToJson(items: unknown[]): Promise { + private async getItemsToJson(items: Ijson[]): Promise { const timeline_items_data: unknown[] = []; items.forEach((element) => { timeline_items_data.push(element.toJSON()); }); @@ -44,11 +46,11 @@ export class StoryTellerProxyTimeline { } private async getItemsDict(items: { - [key: string]: any; - }): Promise<{ [key: string]: any }> { - const timeline_items_data: { [key: string]: any } = {}; + [key: string]: Ijson; + }): Promise<{ [key: string]: unknown }> { + const timeline_items_data: { [key: string]: unknown } = {}; for (const key in items) { - if (items.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(items, key)) { const element = items[key]; timeline_items_data[key] = element.toJSON(); } @@ -60,7 +62,7 @@ export class StoryTellerProxyTimeline { const timeline_json = { timeline: await this.getItemsToJson(this.timeline.timeline_items), transform: await this.getItemsDict(this.transform_engine.clips), - animation: await this.getItemsDict(this.animation_engine.clips), + animation: this.animation_engine.toJSON(), audio: await this.getItemsDict(this.audio_engine.clips), lipsync: await this.getItemsDict(this.lipsync_engine.clips), emotion: await this.getItemsDict(this.emotion_engine.clips), @@ -131,27 +133,6 @@ export class StoryTellerProxyTimeline { return timeline_items_data; } - private async loadAnimationClips(items: { - [key: string]: any; - }): Promise<{ [key: string]: any }> { - const timeline_items_data: { [key: string]: any } = {}; - for (const key in items) { - if (items.hasOwnProperty(key)) { - const element = items[key]; - timeline_items_data[key] = new AnimationClip( - element.version, - element.media_id, - "remote", - element.object_uuid, - element.speed, - element.length, - element.clip_name, - ); - } - } - return timeline_items_data; - } - private async loadLipsyncClips(items: { [key: string]: any; }): Promise<{ [key: string]: any }> { @@ -196,14 +177,21 @@ export class StoryTellerProxyTimeline { this.lipsync_engine.clips = await this.loadLipsyncClips( timeline["lipsync"], ); - this.animation_engine.clips = await this.loadAnimationClips( - timeline["animation"], - ); this.emotion_engine.clips = await this.loadEmotionClips( timeline["emotion"], ); - console.log(this.timeline.timeline_items); + // Add characters and their animations + const animationClips = this.timeline.timeline_items.filter((clip) => { clip.group === ClipGroup.CHARACTER && clip.type === ClipType.ANIMATION }) + animationClips.forEach((clip) => { + const characterObject = this.timeline.scene.get_object_by_uuid(clip.object_uuid); + + if (!characterObject) { + return + } + + this.animation_engine.addCharacterAnimationMedia(characterObject, clip.media_id, clip); + }); this.timeline.updateUI(); }