diff --git a/app/pages/PageEnigma/PageEnigma.tsx b/app/pages/PageEnigma/PageEnigma.tsx index 0f02cf72fd..2645398601 100644 --- a/app/pages/PageEnigma/PageEnigma.tsx +++ b/app/pages/PageEnigma/PageEnigma.tsx @@ -41,7 +41,7 @@ export const PageEnigma = () => { editorRef.current?.save(); } const handleButtonLoad = ()=>{ - + document.getElementById("load-upload")?.click(); } const handleButtonRender = ()=>{ editorRef.current?.togglePlayback(); @@ -58,6 +58,7 @@ export const PageEnigma = () => { +
Timeline Panel
diff --git a/app/pages/PageEnigma/js/editor.js b/app/pages/PageEnigma/js/editor.js index 62c8813f98..6e962f2ffb 100644 --- a/app/pages/PageEnigma/js/editor.js +++ b/app/pages/PageEnigma/js/editor.js @@ -15,6 +15,7 @@ import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js'; import { SAOPass } from 'three/addons/postprocessing/SAOPass.js'; import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; import { BokehPass } from 'three/addons/postprocessing/BokehPass.js'; +import { FFmpeg } from '@ffmpeg/ffmpeg'; if (typeof window !== 'undefined') { import('ccapture.js').then(module => { @@ -66,7 +67,10 @@ class Editor { // Recording params. this.capturer = null; + this.frame_buffer = []; + this.render_timer = 0; this.cap_fps = 60; + this.ffmpeg = null; // Timeline settings. this.playback = false; @@ -94,7 +98,7 @@ class Editor { this.camera.position.x = 2; // Base WebGL render and clock for delta time. - this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvReference }); + this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvReference, preserveDrawingBuffer: true }); this.renderer.shadowMap.enabled = true; this.clock = new THREE.Clock(); @@ -106,7 +110,7 @@ class Editor { // Current scene for saving and loading. this.activeScene = new Scene(); - //this._configure_post_pro(); + this._configure_post_pro(); this.activeScene.initialize(); @@ -145,6 +149,8 @@ class Editor { this.renderer.setAnimationLoop(this.update_loop.bind(this)); //this.create_geometry("Box"); + + this.ffmpeg = new FFmpeg(); } // Configure post processing. @@ -191,6 +197,11 @@ class Editor { this.outputPass = new OutputPass(); this.composer.addPass(this.outputPass); + + + + + document.getElementById('load-upload').addEventListener('change', this.load.bind(this)); } _add_post_processing() { @@ -333,6 +344,9 @@ class Editor { this.capturer.stop(); this.capturer.save(); } + this.render_mode(); + this.ffmpeg.writeFile('input.webm', fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/Big_Buck_Bunny_180_10s.webm')); + this.ffmpeg.exec(['-i', 'input.webm', 'output.mp4']); } frameCounter() { @@ -376,16 +390,18 @@ class Editor { // Initializes CCapture for capturing the scene to send over to backend. _initialize_recording() { - this.capturer = new CCapture({ - verbose: false, - display: false, - framerate: this.cap_fps, - quality: 100, - format: 'webm-mediarecorder', - frameLimit: 0, - autoSaveTime: 0 - }); - this.capturer.start(); + this.frame_buffer = []; + this.render_timer = 0; + //this.capturer = new CCapture({ + // verbose: true, + // display: true, + // framerate: this.cap_fps, + // quality: 100, + // format: 'webm', + // frameLimit: 0, + // autoSaveTime: 0 + //}); + //this.capturer.start(); } // Debug stats using ThreJS built in FPS and MS counter. @@ -410,12 +426,43 @@ class Editor { // Render the scene to the camera. render_scene() { - if (this.composer != null && this.rendering == false) { + if (this.composer != null) { this.composer.render(); } else { this.renderer.render(this.activeScene.scene, this.camera); } + + if (this.rendering) { + let imgData = this.renderer.domElement.toDataURL(); + this.frame_buffer.push(imgData); + this.render_timer += this.clock.getDelta(); + + //const base64Data = imgData.split(',')[1]; + //const contentType = imgData.split(',')[0].split(':')[1].split(';')[0]; + //const byteCharacters = atob(base64Data); + //const byteArrays = []; + //for (let offset = 0; offset < byteCharacters.length; offset += 1024) { + // const slice = byteCharacters.slice(offset, offset + 1024); + // const byteNumbers = new Array(slice.length); + // for (let i = 0; i < slice.length; i++) { + // byteNumbers[i] = slice.charCodeAt(i); + // } + // const byteArray = new Uint8Array(byteNumbers); + // byteArrays.push(byteArray); + //} + //const blob = new Blob(byteArrays, {type: contentType}); + //const link = document.createElement('a'); + //link.href = URL.createObjectURL(blob); + //link.download = 'image.png'; // Set the file name for the download + //document.body.appendChild(link); + //link.click(); + //document.body.removeChild(link); + } + + if(this.render_timer >= this.fps_number) { + this.stopPlayback(); + } } update_properties() { diff --git a/app/pages/PageEnigma/js/serialization.js b/app/pages/PageEnigma/js/serialization.js index 3879c4845d..5fc32ee4d7 100644 --- a/app/pages/PageEnigma/js/serialization.js +++ b/app/pages/PageEnigma/js/serialization.js @@ -47,12 +47,22 @@ class SaveManager { } load(uploadedFile, load_callback) { - // I dont know if this works yet without a load file UI. - console.log(uploadedFile); - const loader = new GLTFLoader(); - loader.load(uploadedFile, function ( gltf ) { - load_callback(gltf.scene); - }); + const reader = new FileReader(); + reader.onload = function(e) { + const contents = e.target.result; + + const loader = new THREE.GLTFLoader(); + loader.parse(contents, '', function(gltf) { + scene.add(gltf.scene); + }); + }; + reader.readAsArrayBuffer(file); + + //const loader = new GLTFLoader(); + //loader.load(uploadedFile, function ( gltf ) { + // console.log(gltf); + // load_callback(gltf.scene); + //}); } download(data, filename, type) { diff --git a/app/routes/IdealEnigma.tsx b/app/routes/IdealEnigma.tsx index e5d7442632..9606f9fe14 100644 --- a/app/routes/IdealEnigma.tsx +++ b/app/routes/IdealEnigma.tsx @@ -4,18 +4,20 @@ import { PageEnigma } from "../pages/PageEnigma"; import { Button } from '~/components/Button'; export default function IdealEnigma(){ - const [riddle, setRiddle] = useState(""); - const [submitted, setSubmitted] = useState(false); + //const [riddle, setRiddle] = useState(""); + //const [submitted, setSubmitted] = useState(false); - const handleInput = (event:React.ChangeEvent)=>{ - setRiddle(event.target.value); - } + //const handleInput = (event:React.ChangeEvent)=>{ + // setRiddle(event.target.value); + //} - const handleSubmit = () => { - const state = riddle.length > 5 && riddle[riddle.length-1] === "!"; - setSubmitted(state); - } + //const handleSubmit = () => { + // const state = riddle.length > 5 && riddle[riddle.length-1] === "!"; + // setSubmitted(state); + //} + + return if(submitted){ return }else{ diff --git a/package-lock.json b/package-lock.json index 0c061b7ebe..dc68f11dea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,8 @@ "": { "name": "gottagofast_v0.0.0", "dependencies": { + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", @@ -1276,6 +1278,33 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ffmpeg/core": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", + "integrity": "sha512-PrjWBTfGn2WVn9T7wGnzfFwChbqWeZc7tM9vvJZVRadYFUDakfzy7W0LpYC0cvvK0xT82qlBsk38lQhJ/Hps5A==", + "engines": { + "node": ">=16.x" + } + }, + "node_modules/@ffmpeg/ffmpeg": { + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", + "dependencies": { + "@ffmpeg/types": "^0.12.2" + }, + "engines": { + "node": ">=18.x" + } + }, + "node_modules/@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", + "engines": { + "node": ">=16.x" + } + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", diff --git a/package.json b/package.json index 73b2d733f6..17d31ba3e7 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "typecheck": "tsc" }, "dependencies": { + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", diff --git a/public/resources/skybox/black.jpg b/public/resources/skybox/black.jpg new file mode 100644 index 0000000000..01e7d8a48d Binary files /dev/null and b/public/resources/skybox/black.jpg differ