diff --git a/package-lock.json b/package-lock.json index f0c6b27..638ceb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,6 @@ "requires": true, "packages": { "": { - "name": "hackweek-avatar-maker", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.34", "@fortawesome/free-solid-svg-icons": "^5.15.2", @@ -13,7 +12,7 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "simplebar-react": "^2.3.0", - "three": "^0.125.2" + "three": "^0.141.0" }, "devDependencies": { "@babel/core": "^7.12.10", @@ -4514,9 +4513,9 @@ } }, "node_modules/three": { - "version": "0.125.2", - "resolved": "https://registry.npmjs.org/three/-/three-0.125.2.tgz", - "integrity": "sha512-7rIRO23jVKWcAPFdW/HREU2NZMGWPBZ4XwEMt0Ak0jwLUKVJhcKM55eCBWyGZq/KiQbeo1IeuAoo/9l2dzhTXA==" + "version": "0.141.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", + "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" }, "node_modules/thunky": { "version": "1.1.0", @@ -8809,9 +8808,9 @@ } }, "three": { - "version": "0.125.2", - "resolved": "https://registry.npmjs.org/three/-/three-0.125.2.tgz", - "integrity": "sha512-7rIRO23jVKWcAPFdW/HREU2NZMGWPBZ4XwEMt0Ak0jwLUKVJhcKM55eCBWyGZq/KiQbeo1IeuAoo/9l2dzhTXA==" + "version": "0.141.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", + "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" }, "thunky": { "version": "1.1.0", diff --git a/package.json b/package.json index e5942c8..691e5ec 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,6 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "simplebar-react": "^2.3.0", - "three": "^0.125.2" + "three": "^0.141.0" } } diff --git a/src/create-texture-atlas.js b/src/create-texture-atlas.js index c693dec..67718ab 100644 --- a/src/create-texture-atlas.js +++ b/src/create-texture-atlas.js @@ -84,7 +84,7 @@ export const createTextureAtlas = (function () { context.globalCompositeOperation = image ? "multiply" : "source-over"; const colorClone = mesh.material.color.clone(); - colorClone.convertLinearToGamma(); + colorClone.convertLinearToSRGB(); context.fillStyle = `#${colorClone.getHexString()}`; context.fillRect(min.x * ATLAS_SIZE_PX, min.y * ATLAS_SIZE_PX, tileSize, tileSize); diff --git a/src/export.js b/src/export.js index d4d1971..ae4ea86 100644 --- a/src/export.js +++ b/src/export.js @@ -53,8 +53,16 @@ export function combineHubsComponents(a, b) { export const exportGLTF = (function () { const exporter = new GLTFExporter(); return function exportGLTF(object3D, { binary, animations }) { - return new Promise((resolve) => { - exporter.parse(object3D, (gltf) => resolve({ gltf }), { binary, animations }); + return new Promise((resolve, reject) => { + exporter.parse( + object3D, + (gltf) => resolve({ gltf }), + (error) => { + console.error(error); + reject("Error exporting the avatar"); + }, + { binary, animations } + ); }); }; })(); diff --git a/src/game.js b/src/game.js index d2c7832..21199e2 100644 --- a/src/game.js +++ b/src/game.js @@ -57,9 +57,9 @@ const state = { }; window.gameState = state; -window.onresize = () => { +window.addEventListener("resize", () => { state.shouldResize = true; -}; +}); document.addEventListener(constants.reactIsLoaded, () => { state.reactIsLoaded = true; }); @@ -126,8 +126,9 @@ function init() { // TODO: Square this with react const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("scene"), antialias: true }); + renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.physicallyCorrectLights = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; state.renderer = renderer; state.clock = new THREE.Clock(); diff --git a/src/merge-geometry.js b/src/merge-geometry.js index 817da36..33d5ec1 100644 --- a/src/merge-geometry.js +++ b/src/merge-geometry.js @@ -1,5 +1,5 @@ import * as THREE from "three"; -import { BufferGeometryUtils } from "three/examples/jsm/utils/BufferGeometryUtils"; +import { mergeBufferAttributes } from "three/examples/jsm/utils/BufferGeometryUtils"; import constants from "./constants"; import { GLTFCubicSplineInterpolant } from "./gltf-cubic-spline-interpolant"; @@ -39,7 +39,7 @@ function mergeSourceAttributes({ sourceAttributes }) { const destAttributes = {}; Array.from(propertyNames.keys()).map((name) => { - destAttributes[name] = BufferGeometryUtils.mergeBufferAttributes( + destAttributes[name] = mergeBufferAttributes( allSourceAttributes.map((sourceAttributes) => sourceAttributes[name]).flat() ); }); @@ -103,7 +103,7 @@ function mergeSourceMorphAttributes({ propertyNames.forEach((propName) => { merged[propName] = []; Object.entries(destMorphTargetDictionary).forEach(([morphName, destMorphIndex]) => { - merged[propName][destMorphIndex] = BufferGeometryUtils.mergeBufferAttributes(unmerged[propName][destMorphIndex]); + merged[propName][destMorphIndex] = mergeBufferAttributes(unmerged[propName][destMorphIndex]); }); }); diff --git a/src/mesh-combination.js b/src/mesh-combination.js index 2459d47..81d16d9 100644 --- a/src/mesh-combination.js +++ b/src/mesh-combination.js @@ -73,6 +73,21 @@ export async function combine({ avatar }) { delete geometry.attributes[`morphTarget${i}`]; delete geometry.attributes[`morphNormal${i}`]; } + // Computing tangents that was done in GLTFLoader in threejs 0.125.2 was removed in threejs r126 (https://github.com/mrdoob/three.js/pull/21186) + // The mergeSourceAttributes function will crash because it can't find the tangent attribute on some geometry. + // So putting back here the code that was executed in GLTFLoader 0.125.2: + const material = mesh.material; + if ( + material.isMeshStandardMaterial === true && + material.side === THREE.DoubleSide && + geometry.getIndex() !== null && + geometry.hasAttribute("position") === true && + geometry.hasAttribute("normal") === true && + geometry.hasAttribute("uv") === true && + geometry.hasAttribute("tangent") === false + ) { + geometry.computeTangents(); + } }); const { source, dest } = mergeGeometry({ meshes }); diff --git a/src/react-components/AvatarEditorContainer.js b/src/react-components/AvatarEditorContainer.js index 8fae5f9..fbac7de 100644 --- a/src/react-components/AvatarEditorContainer.js +++ b/src/react-components/AvatarEditorContainer.js @@ -33,10 +33,13 @@ export function AvatarEditorContainer() { }); // TODO: Save the wave to a static image, or actually do some interesting animation with it. - useEffect(async () => { - if (canvasUrl === null) { - setCanvasUrl(await generateWave()); + useEffect(() => { + async function init() { + if (canvasUrl === null) { + setCanvasUrl(await generateWave()); + } } + init(); }); function updateAvatarConfig(newConfig) { diff --git a/src/react-components/ToolbarContainer.js b/src/react-components/ToolbarContainer.js index 275433e..766d1d0 100644 --- a/src/react-components/ToolbarContainer.js +++ b/src/react-components/ToolbarContainer.js @@ -35,8 +35,8 @@ export function ToolbarContainer({ onGLBUploaded, randomizeConfig }) {
- The 3D models used in this app are ©2020-2022 by individual mozilla.org contributors. - Content available under a Creative Commons license. + The 3D models used in this app are ©2020-2022 by individual mozilla.org contributors. + Content available under a Creative Commons license.
);