Adding proxy

This commit is contained in:
Michael Chung committed 2024-04-04 19:04:34 -04:00
1 parent 114fb0bbfe
commit 8d0ff33176
2 files changed
+222

No files matched your search

@@ -0,0 +1,67 @@
import * as THREE from "three";
export class StoryTellerProxy3DObject {
version: number;
position: THREE.Vector3;
rotation: THREE.Euler;
scale: THREE.Vector3;
object_uuid: string;
object_name: string;
object_user_data_name: string; // changable name
media_file_token: string;
constructor(
version: number,
media_file_token: string,
) {
this.version = version;
this.media_file_token = media_file_token;
this.position = new THREE.Vector3(0.0, 0.0, 0.0);
this.rotation = new THREE.Euler(0.0, 0.0, 0.0);
this.scale = new THREE.Vector3(1.0, 1.0, 1.0);
this.object_name = "";
this.object_user_data_name = "";
this.object_uuid = "";
}
public async initialize(object: THREE.Object3D) {
this.position = object.position;
this.rotation = object.rotation;
this.scale = object.scale;
this.object_name = object.name;
this.object_user_data_name = object.userData.name;
this.object_uuid = object.uuid;
}
public async toJSON(): Promise<string> {
const json = {
version: this.version,
position: {
x: this.position.x,
y: this.position.y,
z: this.position.z,
},
rotation: {
x: this.rotation.x,
y: this.rotation.y,
z: this.rotation.z,
},
scale: {
x: this.scale.x,
y: this.scale.y,
z: this.scale.z,
},
object_name: this.object_name,
object_uuid: this.object_uuid,
object_user_data_name: this.object_user_data_name,
media_file_token: this.media_file_token,
};
const json_string = JSON.stringify(json);
return json_string;
}
}
@@ -0,0 +1,155 @@
import * as THREE from "three";
import { GLTFLoader, GLTF } from "three/addons/loaders/GLTFLoader.js";
import { StoryTellerProxy3DObject } from "./storyteller_proxy_3d_object"
interface LookUpDictionary {
[key: string]: StoryTellerProxy3DObject;
}
export class StoryTellerProxyScene {
sceneItemProxy: StoryTellerProxy3DObject[];
scene: THREE.Scene;
glbLoader: GLTFLoader;
lookUpDictionary: LookUpDictionary;
version: number;
constructor(version:number,scene: THREE.Scene) {
this.version = version
this.scene = scene;
this.glbLoader = new GLTFLoader();
this.lookUpDictionary = {}
this.sceneItemProxy = []
}
private async get_media_url(media_file_token: string): Promise<string> {
//This is for prod when we have the proper info on the url.
let api_base_url = "https://api.fakeyou.com";
let url = `${api_base_url}/v1/media_files/file/${media_file_token}`;
let responce = await fetch(url);
let json = await JSON.parse(await responce.text());
let bucketPath = json["media_file"]["public_bucket_path"];
let media_base_url = "https://storage.googleapis.com/vocodes-public";
let media_url = `${media_base_url}${bucketPath}`;
return media_url;
}
// TODO can you throw custom error from here?
private async loadGLB(bucket_path: string): Promise<GLTF> {
return new Promise((resolve, reject) => {
this.glbLoader.load(bucket_path, (glb) => {
if (glb != null) {
resolve(glb);
} else {
reject(new Error("No GLB Data was Loaded."));
}
});
});
}
/**
* This is to load a scene from the json format from the server
* @param proxyObjects3D
*/
public async load(proxyObjects3D: StoryTellerProxy3DObject[]) {
// So first scene loading from scratch and everytime | create empty 3js scene
proxyObjects3D.forEach(async (element) => {
// construct the bucket path media_file_token
try {
const bucket_path = await this.get_media_url(element.media_file_token);
const glb = await this.loadGLB(bucket_path);
// extract children from scene any save glb and add it into the scene.
glb.scene.children.forEach((child) => {
// needs to be modified before adding to the scene.
child.traverse((c: THREE.Object3D) => {
if (c instanceof THREE.Mesh) {
c.material.metalness = 0.0;
c.material.specular = 0.5;
c.castShadow = true;
c.receiveShadow = true;
c.material.transparent = false;
}
});
child.parent = this.scene;
this.scene.add(child);
this.sceneItemProxy.push(element)
// for easy lookup later
this.lookUpDictionary[element.object_uuid] = element
});
} catch (error) {
console.log(error)
throw error
}
});
}
public async saveToScene():Promise<string> {
// retrieve all elements in 3js scene update the proxy objects 3D and turn into json.
let result:string[] = []
if (this.scene != null) {
this.scene.children.forEach(async (child) => {
const proxyObject3D:StoryTellerProxy3DObject = this.lookUpDictionary[child.uuid]
proxyObject3D.position = child.position
proxyObject3D.rotation = child.rotation
proxyObject3D.scale = child.scale
proxyObject3D.object_user_data_name = child.userData.name;
proxyObject3D.object_name = child.name
proxyObject3D.object_uuid = child.uuid
const json_data = await proxyObject3D.toJSON()
result.push(json_data)
});
} else {
console.log("Scene doesn't exist needs to be assigned")
}
const json_string = JSON.stringify(result)
return json_string
}
/**
* This will add to and load into scene StoryTellerProxy3DObject
* @param media_file_token
*/
public async loadFromMediaFileToken(media_file_token: string) {
// load it from the db
// Everything you load is a scene | objects are a scene as well.
try {
const bucket_path = await this.get_media_url(media_file_token);
const glb = await this.loadGLB(bucket_path);
// extract children from scene any save glb and add it into the scene.
glb.scene.children.forEach((child) => {
// needs to be modified before adding to the scene.
child.traverse((c: THREE.Object3D) => {
if (c instanceof THREE.Mesh) {
c.material.metalness = 0.0;
c.material.specular = 0.5;
c.castShadow = true;
c.receiveShadow = true;
c.material.transparent = false;
}
});
child.parent = this.scene;
if (this.scene != null) {
this.scene.add(child);
// now add the record
const result = new StoryTellerProxy3DObject(this.version,media_file_token)
result.initialize(child)
this.sceneItemProxy.push(result)
this.lookUpDictionary[child.uuid] = result
} else {
console.log("Scene doesn't exist needs to be assigned")
}
});
} catch (error) {
console.log(error)
}
}
public async deleteWithUUID(uuid:String) {
}
};