diff --git a/app/pages/PageEnigma/Queue/Queue.ts b/app/pages/PageEnigma/Queue/Queue.ts index d793335c08..2fbfcd789e 100644 --- a/app/pages/PageEnigma/Queue/Queue.ts +++ b/app/pages/PageEnigma/Queue/Queue.ts @@ -7,19 +7,20 @@ import { } from "~/pages/PageEnigma/models"; import { toTimelineActions } from "./toTimelineActions"; import { ClipUI } from "../datastructures/clips/clip_ui"; +import { MediaItem } from "~/pages/PageEnigma/models"; class Queue { private _queue: Record< string, { action: fromEngineActions | toEngineActions | toTimelineActions; - data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[]; + data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem; }[] > = {}; private _subscribers: Record< string, (entry: { action: fromEngineActions | toEngineActions | toTimelineActions; - data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[]; + data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem; }) => void > = {}; @@ -30,7 +31,7 @@ class Queue { }: { queueName: string; action: fromEngineActions | toEngineActions | toTimelineActions; - data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] ; + data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem ; }) { if (!this._queue[queueName]) { this._queue[queueName] = []; @@ -47,7 +48,7 @@ class Queue { queueName: string, onMessage: (entry: { action: fromEngineActions | toEngineActions | toTimelineActions; - data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[]; + data: QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem; }) => void, ) { this._subscribers[queueName] = onMessage; diff --git a/app/pages/PageEnigma/Queue/fromEngineActions.ts b/app/pages/PageEnigma/Queue/fromEngineActions.ts index 2e647b32bc..484eaaa6d3 100644 --- a/app/pages/PageEnigma/Queue/fromEngineActions.ts +++ b/app/pages/PageEnigma/Queue/fromEngineActions.ts @@ -1,5 +1,6 @@ export enum fromEngineActions { UPDATE_TIME = "update_time", UPDATE_TIME_LINE = "update_timeline", + UPDATE_CHARACTER_ID = "update_character_id", // data={currentTime: number} } diff --git a/app/pages/PageEnigma/Queue/toEngineActions.ts b/app/pages/PageEnigma/Queue/toEngineActions.ts index 9a601aa64f..4be8244918 100644 --- a/app/pages/PageEnigma/Queue/toEngineActions.ts +++ b/app/pages/PageEnigma/Queue/toEngineActions.ts @@ -2,6 +2,11 @@ export enum toEngineActions { ADD_CLIP = "add_clip", // data=QueueClip ADD_KEYFRAME = "add_keyframe", + + ADD_CHARACTER = "add_character", + + ADD_OBJECT = "add_object", + // data= QueueKeyframe DELETE_CLIP = "delete_clip", // data=QueueClip diff --git a/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts b/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts index 5329d91bc5..710e7d02f8 100644 --- a/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts +++ b/app/pages/PageEnigma/comps/Timeline/utils/useQueueHandler.ts @@ -1,13 +1,21 @@ import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions"; import { useSignals } from "@preact/signals-react/runtime"; import { useCallback, useContext, useEffect } from "react"; -import { characterGroups, currentTime } from "~/pages/PageEnigma/store"; +import { + addCharacterAnimation, + addCharacterKeyframe, + characterGroups, + currentTime, +} from "~/pages/PageEnigma/store"; import Queue from "~/pages/PageEnigma/Queue/Queue"; import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; import { + AssetType, CharacterGroup, ClipGroup, + ClipType, + MediaItem, QueueClip, QueueKeyframe, UpdateTime, @@ -32,6 +40,7 @@ function addCharacter(item: ClipUI) { const newCharacter = { id: item.object_uuid, + name: item.object_name, muted: false, animationClips: [], positionKeyframes: [], @@ -58,11 +67,38 @@ export function useQueueHandler() { break; case fromEngineActions.UPDATE_TIME_LINE: console.log(data); - // (data as ClipUI[]).forEach((item) => { - // addCharacter(item); - // if (item.group === ClipGroup.CHARACTER) { - // } - // }); + (data as ClipUI[]).forEach((item) => { + addCharacter(item); + if (item.group === ClipGroup.CHARACTER) { + if (item.type === ClipType.ANIMATION) { + const newItem = { + version: item.version, + type: item.type as string as AssetType, + group: item.group, + object_uuid: item.object_uuid, + media_id: item.media_id, + name: item.name, + length: item.length, + } as MediaItem; + addCharacterAnimation({ + dragItem: newItem, + characterId: item.object_uuid, + offset: item.offset, + }); + } + if (item.type === ClipType.TRANSFORM) { + // newItem.length = item.length; + // addCharacterKeyframe({ + // dragItem: newItem, + // characterId: item.object_uuid, + // offset: item.offset, + // }); + } + } + }); + break; + case fromEngineActions.UPDATE_CHARACTER_ID: + console.log(action); break; default: throw new Error(`Unknown action ${action}`); diff --git a/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx b/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx index 2544eb5075..747896cef7 100644 --- a/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx +++ b/app/pages/PageEnigma/contexts/TrackContext/TrackProvider.tsx @@ -6,10 +6,12 @@ import { addCharacterAnimation, addCharacterAudio, addGlobalAudio, + addCharacter, canDrop, dragItem, dropId, dropOffset, + addObject, } from "~/pages/PageEnigma/store"; import useUpdateKeyframe from "~/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe"; @@ -25,7 +27,26 @@ export const TrackProvider = ({ children }: Props) => { // cross group functions const dropClip = useCallback(() => { - console.log(`${canDrop.value} ${dragItem.value} ${dragItem.value.type}`) + + console.log(`${JSON.stringify(dragItem)}`) + + if (dragItem.value != null && dragItem != null) { + // should be able to drag into the timeline ... TODO FIX? + + if (dragItem.value.type === AssetType.CHARACTER) { + addCharacter(dragItem.value) + } + // if (dragItem.value.type === AssetType.CAMERA) { + // console.log("Dragged In Camera Type") + // } + if (dragItem.value.type === AssetType.OBJECT) { + addObject(dragItem.value) + } + } + // if (dragItem.value.type === AssetType.SHAPE) { + // console.log("Dragged In Shape Type") + // } + if (canDrop.value && dragItem.value) { if (dragItem.value.type === AssetType.ANIMATION) { addCharacterAnimation({ @@ -46,18 +67,6 @@ export const TrackProvider = ({ children }: Props) => { offset: dropOffset.value, }); } - if (dragItem.value.type === AssetType.CHARACTER) { - console.log("Dragged In Character Type") - } - if (dragItem.value.type === AssetType.CAMERA) { - console.log("Dragged In Camera Type") - } - if (dragItem.value.type === AssetType.OBJECT) { - console.log("Dragged In Object Type") - } - if (dragItem.value.type === AssetType.SHAPE) { - console.log("Dragged In Shape Type") - } } endDrag(); }, [endDrag]); diff --git a/app/pages/PageEnigma/datastructures/clips/clip_ui.ts b/app/pages/PageEnigma/datastructures/clips/clip_ui.ts index f771f9910c..ed8c279265 100644 --- a/app/pages/PageEnigma/datastructures/clips/clip_ui.ts +++ b/app/pages/PageEnigma/datastructures/clips/clip_ui.ts @@ -9,6 +9,7 @@ export class ClipUI { name: string; media_id: string; object_uuid: string; + object_name: string; offset: number; // in frames length: number; // in frames should_play: boolean; @@ -20,6 +21,7 @@ export class ClipUI { name: string, media_id: string, object_uuid: string, + object_name: string, offset: number, length: number, ) { @@ -30,6 +32,7 @@ export class ClipUI { this.type = type; // UI and Animation / Audio / Lipsync / : Engine this.object_uuid = object_uuid; // Animation / Audio / Lipsync / : Engine + this.object_name = object_name; this.media_id = media_id; // Animation / Audio / Lipsync / : Engine this.offset = offset; this.length = length; @@ -43,6 +46,7 @@ export class ClipUI { name: this.name, type: this.type, object_uuid: this.object_uuid, + object_name: this.object_name, media_id: this.media_id, start_offset: this.offset, ending_offset: this.length, diff --git a/app/pages/PageEnigma/js/timeline.ts b/app/pages/PageEnigma/js/timeline.ts index e1090d081e..96188daefe 100644 --- a/app/pages/PageEnigma/js/timeline.ts +++ b/app/pages/PageEnigma/js/timeline.ts @@ -124,11 +124,43 @@ export class TimeLine { case toEngineActions.UNMUTE: await this.mute(data, true); break; + case toEngineActions.ADD_CHARACTER: + await this.addCharacter(data); + break; + case toEngineActions.ADD_OBJECT: + await this.addObject(data); + break; default: console.log("Action Not Wired", action); } } + public async addCharacter(data: any) { + let media_id = data.data['media_id']; + let name = data.data['name']; + let type = data.data['type']; + + let obj = await this.scene.load_glb(media_id); + obj.userData['name'] = name; + obj.name = name; + let object_uuid = obj.uuid; + + data.data['object_uuid'] = object_uuid; + Queue.publish({ + queueName: QueueNames.FROM_ENGINE, + action: fromEngineActions.UPDATE_CHARACTER_ID, + data: data.data, + }); + } + + public async addObject(data: any) { + let media_id = data.data['media_id']; + let name = data.data['name']; + let obj = await this.scene.load_glb(media_id); + obj.userData['name'] = name; + obj.name = name; + } + public async addKeyFrame(data: any) { // KeyFrame Object // version: number; @@ -163,6 +195,7 @@ export class TimeLine { object_name, "", uuid, + object_name, 0, this.absolute_end)) } @@ -184,6 +217,7 @@ export class TimeLine { const type = data["data"]["type"]; const offset = data["data"]["offset"]; const end_offset = data["data"]["length"] + offset; + const object_name = data["data"]["object_name"]; switch (type) { case "animation": @@ -204,6 +238,7 @@ export class TimeLine { name, media_id, object_uuid, + object_name, offset, end_offset)); return; @@ -222,6 +257,7 @@ export class TimeLine { name, media_id, object_uuid, + object_name, offset, end_offset, ), @@ -449,96 +485,3 @@ export class TimeLine { } } -// How much timeline precision we have -//const percision = 100 // using a fake update loop mock -// -//class AudioEngineMock { -// async play(media_id:string) { -// console.log("Audio Playing {media_id}") -// } -//} -// -//// Visual verification tests. -//function CheckIfBasicAudioClipWorks() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI(1.0,'audio',1,0)) -// timeline.play() -//} -// -//function CheckIfBasicTransformClipWorks() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI(1.0,'transform',2,0)) -// timeline.play() -//} -// -//function CheckIfBasicClipWorks() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI(1.0,'animation',3,0)) -// timeline.play() -//} - -// function CheckIfBasicClipWorks3SecondsAfterTimelineStops() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip1", 0, 10000)) -// timeline.play() -// } - -// function CheckIfTwoClipsAtTheSameTimeWorks() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip1", 0, 1000)) -// timeline.play() -// } - -// function CheckIfTwoClipsOneAfterAnotherWorks() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip1", 0, 1000)) -// timeline.addPlayableClip(new ClipUI("clip2", 0, 2000)) -// timeline.play() -// } - -// function CheckIfTimeLineStopBeforeClipPlays() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip3",0,1000)) -// timeline.play() -// setInterval(async ()=> { -// timeline.stop() -// },1100) -// console.log("Stopped") -// } - -// function CheckIfTimeLineStartAfterClipPlays() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip3",0,1000)) -// timeline.play() -// setInterval(async ()=> { -// timeline.stop() -// },500) -// console.log("Stopped") -// } - -// function CheckIfClipsPlayAllTogetherConcurrently() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new ClipUI("clip1",0,1000)) -// timeline.addPlayableClip(new ClipUI("clip2",0,1000)) -// timeline.addPlayableClip(new ClipUI("clip3",0,1000)) -// timeline.addPlayableClip(new ClipUI("clip4",0,1000)) -// timeline.play() -// } - -// function CheckIfClipsPlayAllTogether() { -// const timeline = new TimeLine() -// timeline.addPlayableClip(new TrackClip("clip1",0,1000)) -// timeline.addPlayableClip(new TrackClip("clip2",0,1000)) -// timeline.addPlayableClip(new TrackClip("clip3",0,1000)) -// timeline.addPlayableClip(new TrackClip("clip4",0,1000)) -// timeline.play() -// } - -//CheckIfBasicClipWorks() -//CheckIfTwoClipsAtTheSameTimeWorks() -// CheckIfTwoClipsOneAfterAnotherWorks() -// CheckIfTimeLineStopBeforeClipPlays() -// CheckIfTimeLineStartAfterClipPlays() -// CheckIfClipsPlayAllTogetherConcurrently() - -// CheckIfClipsPlayAllTogether() diff --git a/app/pages/PageEnigma/models/assets.ts b/app/pages/PageEnigma/models/assets.ts index c6e4539759..c3a9a66d3b 100644 --- a/app/pages/PageEnigma/models/assets.ts +++ b/app/pages/PageEnigma/models/assets.ts @@ -4,7 +4,7 @@ export interface MediaItem { media_id: string; name: string; length?: number; - thumbnail: string; + thumbnail?: string; isMine?: boolean; isBookmarked?: boolean; } @@ -16,7 +16,7 @@ export enum AssetType { ANIMATION = "animation", CAMERA = "camera", SHAPE = "shape", - STYLE = "style" // TODO Remove + STYLE = "style", // TODO Remove } export enum AssetFilterOption { diff --git a/app/pages/PageEnigma/models/track.ts b/app/pages/PageEnigma/models/track.ts index 931e2e65a4..006d3c9226 100644 --- a/app/pages/PageEnigma/models/track.ts +++ b/app/pages/PageEnigma/models/track.ts @@ -17,7 +17,7 @@ export enum ClipType { TRANSFORM = "transform", AUDIO = "audio", ANIMATION = "animation", - LIPSYNC = "lipsync" + LIPSYNC = "lipsync", } export enum ClipGroup { @@ -41,6 +41,7 @@ export interface Keyframe { export interface CharacterGroup { id: string; + name: string; muted: boolean; animationClips: Clip[]; positionKeyframes: Keyframe[]; diff --git a/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts b/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts index e5cb72ff2a..2133951979 100644 --- a/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts +++ b/app/pages/PageEnigma/proxy/storyteller_proxy_timeline.ts @@ -65,6 +65,7 @@ export class StoryTellerProxyTimeline { element.version, element.type, element.group, element.name, element.media_id, element.object_uuid, + element.object_name, element.start_offset, element.ending_offset); new_clips.push(clip); } diff --git a/app/pages/PageEnigma/store/characterGroups.ts b/app/pages/PageEnigma/store/characterGroups.ts index ef9ed151d7..7ee8a5e2b6 100644 --- a/app/pages/PageEnigma/store/characterGroups.ts +++ b/app/pages/PageEnigma/store/characterGroups.ts @@ -325,3 +325,25 @@ export function deleteCharacterKeyframe(keyframe: Keyframe) { }), })); } + +// probably not to much to send imo +export function addCharacter(character:MediaItem) { + //{"version":1,"media_id":"m_r7w1tmkx2jg8nznr3hyzj4k6zhfh7d ", + // "type":"character","name":"Female Doll", + // "thumbnail":"resources/characters/img03.png"} + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.ADD_CHARACTER, + data: character, + }); +} +export function addObject(object:MediaItem) { + //{"version":1,"media_id":"m_r7w1tmkx2jg8nznr3hyzj4k6zhfh7d ", + // "type":"character","name":"Female Doll", + // "thumbnail":"resources/characters/img03.png"} + Queue.publish({ + queueName: QueueNames.TO_ENGINE, + action: toEngineActions.ADD_OBJECT, + data: object, + }); +} \ No newline at end of file diff --git a/app/pages/PageEnigma/store/media.ts b/app/pages/PageEnigma/store/media.ts index f1579cd77b..a920f7f686 100644 --- a/app/pages/PageEnigma/store/media.ts +++ b/app/pages/PageEnigma/store/media.ts @@ -132,9 +132,9 @@ export const characterItems = signal([ export const objectItems = signal([ { version: 1, - media_id: "m_w5nn3kjh1fbkmjrdac5b2qaba0pmyt", + media_id: "m_0xfrmekc56satjxn66wt6c9dkw7dxe", type: AssetType.OBJECT, - name: "Item ( Place Holder D.N.W )", + name: "Pikachu Statue", thumbnail: "resources/placeholders/placeholder.png", }, ]);