diff --git a/app/pages/PageEnigma/comps/PreviewEngineCamera/index.tsx b/app/pages/PageEnigma/comps/PreviewEngineCamera/index.tsx
index 8630ed50d9..58179c047e 100644
--- a/app/pages/PageEnigma/comps/PreviewEngineCamera/index.tsx
+++ b/app/pages/PageEnigma/comps/PreviewEngineCamera/index.tsx
@@ -23,11 +23,7 @@ export const PreviewEngineCamera = ()=>{
-

+
diff --git a/app/pages/PageEnigma/comps/ViewSideBySide/index.tsx b/app/pages/PageEnigma/comps/ViewSideBySide/index.tsx
index bcad3ada4c..2006974a60 100644
--- a/app/pages/PageEnigma/comps/ViewSideBySide/index.tsx
+++ b/app/pages/PageEnigma/comps/ViewSideBySide/index.tsx
@@ -1,11 +1,15 @@
-import { useEffect, useState, } from "react";
+import { useEffect, useState, useContext } from "react";
import { LoadingDotsBricks } from "~/components";
+import { EngineContext } from "../../contexts/EngineContext";
export const ViewSideBySide = ()=>{
const [showLoader, setShowLoader] = useState(true);
+ const editorEngine = useContext(EngineContext);
+
useEffect(()=>{
- setTimeout(()=>setShowLoader(false), 1000);
+ editorEngine?.generateFrame();
+ setTimeout(()=>setShowLoader(false), 200);
},[ ]);
return (
@@ -18,11 +22,7 @@ export const ViewSideBySide = ()=>{
-

+
@@ -31,11 +31,7 @@ export const ViewSideBySide = ()=>{
-

+
diff --git a/app/pages/PageEnigma/datastructures/clips/lipsync_clip.ts b/app/pages/PageEnigma/datastructures/clips/lipsync_clip.ts
index a06808e72c..6ad94b7fbf 100644
--- a/app/pages/PageEnigma/datastructures/clips/lipsync_clip.ts
+++ b/app/pages/PageEnigma/datastructures/clips/lipsync_clip.ts
@@ -113,6 +113,11 @@ step() {
}
reset() {
+ if (this.lipsync.face != undefined) {
+ this.lipsync.face.morphTargetInfluences[this.blendshape_helper.ee] = 0;
+ this.lipsync.face.morphTargetInfluences[this.blendshape_helper.ah] = 0
+ this.lipsync.face.morphTargetInfluences[this.blendshape_helper.oh] = 0;
+ }
this.lipsync = new LipSync();
}
diff --git a/app/pages/PageEnigma/js/editor.ts b/app/pages/PageEnigma/js/editor.ts
index b9508e2412..6d4f99bc37 100644
--- a/app/pages/PageEnigma/js/editor.ts
+++ b/app/pages/PageEnigma/js/editor.ts
@@ -45,8 +45,10 @@ class Editor {
camera: any;
render_camera: any;
renderer: THREE.WebGLRenderer | undefined;
+ rawRenderer: THREE.WebGLRenderer | undefined;
clock: THREE.Clock | undefined;
canvReference: any;
+ canvasRenderCamReference: any;
composer: EffectComposer | undefined;
effectFXAA: EffectComposer | undefined;
outlinePass: OutlinePass | undefined;
@@ -86,6 +88,7 @@ class Editor {
lockControls: PointerLockControls | undefined;
cam_obj: THREE.Object3D | undefined;
renderPass: RenderPass | undefined;
+ generating_preview: boolean;
camera_person_mode: boolean;
current_scene_media_token: string | null;
@@ -120,9 +123,11 @@ class Editor {
// Clock, scene and camera essentials.
this.activeScene = new Scene("" + this.version);
this.activeScene.initialize();
+ this.generating_preview = false;
this.camera;
this.render_camera;
this.renderer;
+ this.rawRenderer;
this.clock;
this.canvReference = null;
this.cam_obj;
@@ -168,6 +173,8 @@ class Editor {
this.render_width = 1280;
this.render_height = 720;
+ this.canvasRenderCamReference;
+
this.audio_engine = new AudioEngine();
this.transform_engine = new TransformEngine(this.version);
this.lipsync_engine = new LipSyncEngine();
@@ -215,16 +222,18 @@ class Editor {
// Gets the canvas.
this.canvReference = document.getElementById("video-scene");
+ this.canvasRenderCamReference = document.getElementById("camera-view");
+
// Base width and height.
let width = this.canvReference.width;
let height = this.canvReference.height;
// Sets up camera and base position.
- this.camera = new THREE.PerspectiveCamera(70, width / height, 0.1, 50);
+ this.camera = new THREE.PerspectiveCamera(70, width / height, 0.15, 30);
this.camera.position.z = 3;
this.camera.position.y = 3;
this.camera.position.x = -3;
- this.render_camera = new THREE.PerspectiveCamera(70, width / height, 0.1, 50);
+ this.render_camera = new THREE.PerspectiveCamera(70, width / height, 0.15, 30);
// Base WebGL render and clock for delta time.
this.renderer = new THREE.WebGLRenderer({
@@ -233,6 +242,12 @@ class Editor {
preserveDrawingBuffer: true,
});
+ this.rawRenderer = new THREE.WebGLRenderer({
+ antialias: false,
+ canvas: this.canvasRenderCamReference,
+ preserveDrawingBuffer: true,
+ });
+
this.renderer.shadowMap.enabled = true;
this.clock = new THREE.Clock();
// Resizes the renderer.
@@ -281,11 +296,6 @@ class Editor {
this.renderer.domElement.addEventListener("mouseup", this.onMouseUp.bind(this), false);
this.renderer.domElement.addEventListener("onContextMenu", this.onContextMenu.bind(this), false);
- this.cam_obj = this.activeScene.get_object_by_name("::CAM::");
- if (this.cam_obj) {
- this.addTransformClipBase("Camera Object", "camera", this.cam_obj, 0, 150)
- }
-
// saving state of the scene
this.current_scene_media_token = null;
this.current_scene_glb_media_token = null;
@@ -311,6 +321,8 @@ class Editor {
this.addTransformClipBase("Camera Object", "camera", this.cam_obj, 0, 150);
}
+ console.log(this.cam_obj);
+
this.dispatchAppUiState({
type: APPUI_ACTION_TYPES.UPDATE_EDITOR_LOADINGBAR,
payload: {
@@ -505,6 +517,7 @@ class Editor {
switchCameraView() {
this.camera_person_mode = !this.camera_person_mode;
+ console.log("camera")
if (this.cam_obj) {
if (this.camera_person_mode) {
this.last_cam_pos.copy(this.camera.position);
@@ -521,11 +534,12 @@ class Editor {
if (this.cameraViewControls) {
this.cameraViewControls.enabled = true;
}
-
+ this.cam_obj.scale.set(0,0,0);
if (this.activeScene.hot_items) {
this.activeScene.hot_items.forEach((element) => {
element.visible = false;
});
+
}
} else {
this.camera.position.copy(this.last_cam_pos);
@@ -539,6 +553,7 @@ class Editor {
if (this.cameraViewControls) {
this.cameraViewControls.enabled = false;
}
+ this.cam_obj.scale.set(1,1,1);
if (this.activeScene.hot_items) {
this.activeScene.hot_items.forEach((element) => {
element.visible = true;
@@ -745,6 +760,14 @@ class Editor {
// Basicly Unity 3D's update loop.
updateLoop(time: number) {
+
+ if (this.cam_obj == undefined) {
+ this.cam_obj = this.activeScene.get_object_by_name("::CAM::");
+ if (this.cam_obj) {
+ this.addTransformClipBase("Camera Object", "camera", this.cam_obj, 0, 150)
+ }
+ }
+
// Updates debug stats.
if (this.stats != null) {
this.stats.update();
@@ -907,7 +930,9 @@ class Editor {
}
async generateFrame() {
- if (this.renderer) {
+ if (this.renderer && !this.generating_preview) {
+ this.removeTransformControls();
+ this.generating_preview = true;
this.activeScene.renderMode(true);
if (this.activeScene.hot_items) {
this.activeScene.hot_items.forEach(element => {
@@ -925,32 +950,46 @@ class Editor {
let imgData = this.renderer.domElement.toDataURL();
this.activeScene.renderMode(false);
this.onWindowResize();
- let ffmpeg = createFFmpeg({ log: false });
- await ffmpeg.load();
- await ffmpeg.FS(
- "writeFile",
- `render.png`,
- await fetchFile(imgData),
- );
- await ffmpeg.run('-i', `render.png`, 'render.mp4');
- let output = await ffmpeg.FS("readFile", 'render.mp4');
- const blob = new Blob([output.buffer], { type: "video/mp4" });
- //const blob = new Blob([imgData], { type: "image/png" });
- let url = await this.api_manager.uploadMediaFrameGeneration(blob, "render.mp4", "anime_ghibli", "((masterpiece, best quality, 8K, detailed)), colorful, epic, fantasy, (fox, red fox:1.2), no humans, 1other, ((koi pond)), outdoors, pond, rocks, stones, koi fish, ((watercolor))), lilypad, fish swimming around.", "");
+ const rawPreview: HTMLVideoElement | null = document.getElementById("raw-preview") as HTMLVideoElement;
+ if (rawPreview) {
+ rawPreview.src = imgData;
- const downloadLink = document.createElement("a");
- downloadLink.href = url;
- downloadLink.download = "render.mp4";
- document.body.appendChild(downloadLink);
- downloadLink.click();
- // Clean up
- URL.revokeObjectURL(url);
- document.body.removeChild(downloadLink);
-
- return new Promise((resolve, reject) => {
- resolve(url);
- });
+
+ let ffmpeg = createFFmpeg({ log: false });
+ await ffmpeg.load();
+ await ffmpeg.FS(
+ "writeFile",
+ `render.png`,
+ await fetchFile(imgData),
+ );
+ await ffmpeg.run('-i', `render.png`, 'render.mp4');
+ let output = await ffmpeg.FS("readFile", 'render.mp4');
+ const blob = new Blob([output.buffer], { type: "video/mp4" });
+
+ let url = await this.api_manager.uploadMediaFrameGeneration(blob, "render.mp4", "anime_ghibli", "((masterpiece, best quality, 8K, detailed)), colorful, epic, fantasy, (fox, red fox:1.2), no humans, 1other, ((koi pond)), outdoors, pond, rocks, stones, koi fish, ((watercolor))), lilypad, fish swimming around.", "");
+ console.log(url);
+
+ const stylePreview: HTMLVideoElement | null = document.getElementById("stylized-preview") as HTMLVideoElement;
+ if (stylePreview) {
+ stylePreview.src = url;
+ stylePreview.width = rawPreview.width;
+ stylePreview.height = rawPreview.height;
+ }
+ else {
+ console.log("No style preview window.")
+ }
+
+ this.generating_preview = false;
+
+ return new Promise((resolve, reject) => {
+ resolve(url);
+ });
+ }
+ else {
+ console.log("No raw preview window.")
+ }
+ this.generating_preview = false;
}
}
@@ -999,8 +1038,9 @@ class Editor {
// Render the scene to the camera.
renderScene() {
- if (this.composer != null && !this.rendering) {
+ if (this.composer != null && !this.rendering && this.rawRenderer) {
this.composer.render();
+ this.rawRenderer.render(this.activeScene.scene, this.render_camera);
} else if (this.renderer && this.render_camera) {
this.renderer.setSize(this.render_width, this.render_height);
this.renderer.render(this.activeScene.scene, this.render_camera);
diff --git a/app/pages/PageEnigma/js/scene.ts b/app/pages/PageEnigma/js/scene.ts
index 8f620aad68..8d7d51fe9a 100644
--- a/app/pages/PageEnigma/js/scene.ts
+++ b/app/pages/PageEnigma/js/scene.ts
@@ -64,7 +64,7 @@ class Scene {
let obj = new THREE.Mesh(geometry, material);
obj.position.copy(pos);
obj.receiveShadow = visable;
- if(this.hot_items != undefined){
+ if (this.hot_items != undefined) {
this.hot_items.push(obj);
}
this.scene.add(obj);
@@ -75,15 +75,18 @@ class Scene {
}
_create_camera_obj() {
- let cam_obj: THREE.Object3D = new THREE.Object3D();
- cam_obj.userData["name"] = "::CAM::";
- cam_obj.name = "::CAM::";
- this.scene.add(cam_obj);
+ this.load_glb("/resources/models/camera/camera.glb", false).then((cam_obj) => {
+ cam_obj.userData["name"] = "::CAM::";
+ cam_obj.name = "::CAM::";
+ cam_obj.position.set(0, 0.6, 1.5);
+ this.scene.add(cam_obj);
+ });
}
- renderMode(enabled:boolean=true) {
- if(this.gridHelper == undefined) { return; }
- if(enabled) {
+
+ renderMode(enabled: boolean = true) {
+ if (this.gridHelper == undefined) { return; }
+ if (enabled) {
this._disable_skybox();
this.scene.remove(this.gridHelper);
} else {
@@ -92,7 +95,7 @@ class Scene {
}
}
- async load_glb(filepath: string) { //: Promise {
+ async load_glb(filepath: string, auto_add: boolean = true): Promise { //: Promise {
return new Promise((resolve) => {
let glbLoader = new GLTFLoader();
glbLoader.load(filepath, (glb) => {
@@ -106,7 +109,12 @@ class Scene {
c.material.transparent = false;
}
});
- this.scene.add(child);
+ if (child.type == "Group") {
+ if (auto_add) { this.scene.add(child.children[0]); }
+ resolve(child.children[0]);
+ return;
+ }
+ if (auto_add) { this.scene.add(child); }
resolve(child);
});
});
diff --git a/app/pages/PageEnigma/js/timeline.ts b/app/pages/PageEnigma/js/timeline.ts
index 6873675c84..d025ed5084 100644
--- a/app/pages/PageEnigma/js/timeline.ts
+++ b/app/pages/PageEnigma/js/timeline.ts
@@ -130,6 +130,7 @@ export class TimeLine {
this.audio_engine.loadClip(element.media_id);
}
else if (element.type == "animation") {
+ this.animation_engine.clips[element.object_uuid].stop();
}
else if (element.type == "lipsync") {
this.lipSync_engine.clips[element.object_uuid].reset();
@@ -199,6 +200,10 @@ export class TimeLine {
this.stop()
}
}
+
+ if (this.scrubber_frame_position >= this.timeline_limit) {
+ await this.resetScene();
+ }
}
private async stop(): Promise {
diff --git a/public/resources/models/camera/camera.glb b/public/resources/models/camera/camera.glb
new file mode 100644
index 0000000000..836cf9351d
Binary files /dev/null and b/public/resources/models/camera/camera.glb differ