Adding api manager + upload scene call works, need to serialize the timeline.

This commit is contained in:
Michael Chung committed 2024-03-25 19:50:02 -04:00
1 parent 8621f2ae3e
commit 2d00e0055a
4 files changed
+86 -39

No files matched your search

-2
View File
@@ -6,7 +6,6 @@ import {
import { EngineContext } from "./EngineContext";
import Editor from "~/pages/PageEnigma/js/editor";
interface Props{
children:ReactNode;
}
@@ -14,7 +13,6 @@ interface Props{
export const EngineProvider = ({ children }: Props)=>{
const editorRef = useRef<Editor | null>(null);
useEffect(() => {
//componentDidMount
if (editorRef.current !== null ) {
@@ -27,7 +27,9 @@ export const ControlsTopButtons = () => {
document.getElementById("load-upload")?.click();
};
const handleButtonRender = () => {
editorEngine?.togglePlayback();
console.log("Saving GLB to server for reference")
editorEngine._upload_for_testing()
//editorEngine?.togglePlayback();
};
const handleButtonPlay = () => {};
+57 -30
View File
@@ -1,21 +1,39 @@
import { v4 as uuidv4 } from 'uuid';
import { Scene } from '../datastructures/scene/scene_object';
import { v4 as uuidv4 } from 'uuid'
import { Scene } from '../datastructures/scene/scene_object'
import * as THREE from 'three'
import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { TimelineCurrentReactState } from './timeline'
// Basically the data will exist on the database
class MediaUploadManager {
class APIManager {
baseUrl:String
constructor() {
this.baseUrl = "https://api.fakeyou.com";
this.baseUrl = "https://api.fakeyou.com"
//this.baseUrl = "http://localhost:12345"
}
async saveScene(scene:Scene):Promise<string> {
// we want to upload the glb first then use the engine asset idea from there
// Function to save or update the scene
async saveSceneState(scene:THREE.Scene,
timeLine:TimelineCurrentReactState,
scene_id:string | null =null):Promise<string> {
if (scene_id == null) {
// create new scene.
let file = await this.gltfExport(scene)
let response = await this.uploadGLB(file)
console.log(response)
} else {
// update scene or overwrite glb scene.
}
return ""
}
async _saveSceneAndTimelineToJSONSpec() {
}
async loadScene(scene_token:[]):Promise<string> {
return ""
@@ -26,16 +44,24 @@ class MediaUploadManager {
return ""
}
async gltfExport(scene:THREE.Scene) {
let gltfExporter = new GLTFExporter()
let uuid = uuidv4()
// save the scene to keep ids positions etc
let result = await gltfExporter.parseAsync(scene)
const file = new File([JSON.stringify(result)], `${uuid}.glb`, {type: 'application/json'})
return file
}
// two core functions to upload things to the server and get id's
async uploadMedia(blob:any, fileName:string):Promise<string> {
const url = `${this.baseUrl}/v1/media_uploads/upload`;
let uuid = uuidv4();
const formData = new FormData();
formData.append('uuid_idempotency_token', uuid);
formData.append('file', blob, fileName);
formData.append('source', 'file');
formData.append('type', 'video');
formData.append('source', 'file');
const url = `${this.baseUrl}/v1/media_uploads/upload`
let uuid = uuidv4()
const formData = new FormData()
formData.append('uuid_idempotency_token', uuid)
formData.append('file', blob, fileName)
formData.append('source', 'file')
formData.append('type', 'video')
formData.append('source', 'file')
const response = await fetch(url, {
method: 'POST',
credentials: "include",
@@ -43,24 +69,25 @@ class MediaUploadManager {
"Accept": "application/json",
},
body: formData,
});
})
if (!response.ok) {
throw new Error('Failed to Send Data');
throw new Error('Failed to Send Data')
}
return response.json(); // or handle the response as appropriate
return response.json() // or handle the response as appropriate
}
// to save to a file then upload the scene.
async uploadGLB(file:File):Promise<string> {
const url = `${this.baseUrl}/v1/media_files/upload/engine_asset`;
let uuid = uuidv4();
const formData = new FormData();
formData.append('uuid_idempotency_token', uuid);
formData.append('file', file);
formData.append('source','file');
formData.append('media_file_subtype', 'scene_import');
formData.append('media_file_class', 'scene');
const url = `${this.baseUrl}/v1/media_files/upload/engine_asset`
let uuid = uuidv4()
const formData = new FormData()
formData.append('uuid_idempotency_token', uuid)
formData.append('file', file)
formData.append('source','file')
formData.append('media_file_subtype', 'scene_import')
formData.append('media_file_class', 'scene')
const response = await fetch(url, {
method: 'POST',
credentials: "include",
@@ -68,13 +95,13 @@ class MediaUploadManager {
"Accept": "application/json",
},
body: formData,
});
})
if (!response.ok) {
throw new Error('Failed to Send Data');
throw new Error('Failed to Send Data')
}
return response.json(); // or handle the response as appropriate
return response.json() // or handle the response as appropriate
}
}
export default MediaUploadManager;
export default APIManager
+26 -6
View File
@@ -3,7 +3,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js';
import Scene from './scene.js';
import SaveManager from './serialization.js';
import MediaUploadManager from './api_manager.ts';
import APIManager from './api_manager.ts';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js';
@@ -23,6 +23,7 @@ import { LipSync } from './lipsync.js';
import { LipSyncEngine } from "./lip_sync_engine.ts";
import { AnimationEngine} from "./animation_engine.ts";
import { faL } from '@fortawesome/pro-solid-svg-icons';
if (typeof window !== 'undefined') {
import('ccapture.js').then(module => {
const CCapture = module.CCapture;
@@ -79,7 +80,7 @@ class Editor {
this.transform_interaction;
this.rendering = false;
// API.
this.api_manager = new MediaUploadManager();
this.api_manager = new APIManager();
// Debug & Movement.
this.stats = null;
this.orbit = null;
@@ -158,14 +159,33 @@ class Editor {
this._test_demo()
}
// uploading some objects for testing to get their media ids from my account.
async _upload_for_testing() {
// have to upload as a file first
// This is the default scene.
// "m_189p8hj0eyypbg74kkhcpehwpjhnkz" scene with the fox.
let result = await this.api_manager.saveSceneState(this.activeScene.scene)
console.log(result)
}
async _test_demo() {
// note the database from the server is the source of truth for all the data.
// Test code here
let object = await this.activeScene.load_glb("./resources/models/fox/fox.glb")
// load object into the engine for lip syncing
this.lipsync_engine.load_object(object.uuid, "m_f1jxx4zwy4da2zn0cvdqhha7kqkj72");
// create the clip with the same id for a reference to the media
this.timeline.addPlayableClip(new ClipUI(1.0, "lipsync", "clip1", "m_f1jxx4zwy4da2zn0cvdqhha7kqkj72", object.uuid, 150, 400));
// media id for this is up in the air but when a path is created you should be able to store and delete it
this.timeline.addPlayableClip(new ClipUI(1.0, "transform", "clip2", object.uuid, object.uuid, 0, 150));
this.animation_engine.load_object(object.uuid, "/resources/models/fox/fox_idle.glb", "clip3");
// media id for this as well it can be downloaded
this.timeline.addPlayableClip(new ClipUI(1.0, "animation", "clip3", "/resources/models/fox/fox_idle.glb", object.uuid, 0, 400));
this.animation_engine.load_object(object.uuid, "/resources/models/fox/fox_idle.glb", "clip3");
}
// Configure post processing.
@@ -287,9 +307,9 @@ class Editor {
this.timeline.isPlaying = true;
}
_save_to_cloud(blob) {
this.api_manager.uploadGLB(blob, "test.glb");
}
// _save_to_cloud(blob) {
// this.api_manager.uploadGLB(blob, "test.glb");
// }
change_mode(type) {
this.control.mode = type;