Fix missing animation texture

This commit is contained in:
Brian Beck 2024-08-26 11:39:36 -07:00
parent f8ede74f55
commit b41d6b1841
18 changed files with 57 additions and 31 deletions

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/78e521c3-3739cc27b3254d35.js","static/chunks/95b64a6e-a0ff77d56afeed48.js","static/chunks/31664189-69d752d1129a4958.js","static/chunks/545f34e4-3e66c340444ca8b2.js","static/chunks/1bfc9850-b4ceccea4b74407c.js","static/chunks/d7eeaac4-d223ea230e13423c.js","static/chunks/f580fadb-2911e2fbf64aae5a.js","static/chunks/50-a8a6240a880bd3e0.js","static/chunks/pages/index-e39e2d2e87d2a207.js"],"/_error":["static/chunks/pages/_error-54b9fcf45cb5bc62.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/78e521c3-3739cc27b3254d35.js","static/chunks/95b64a6e-a0ff77d56afeed48.js","static/chunks/31664189-69d752d1129a4958.js","static/chunks/545f34e4-3e66c340444ca8b2.js","static/chunks/1bfc9850-b4ceccea4b74407c.js","static/chunks/d7eeaac4-d223ea230e13423c.js","static/chunks/f580fadb-2911e2fbf64aae5a.js","static/chunks/50-a8a6240a880bd3e0.js","static/chunks/pages/index-357b9e2337384293.js"],"/_error":["static/chunks/pages/_error-54b9fcf45cb5bc62.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"static/chunks/767.5a1b83173dac696e.js","mappings":"+QAGO,SAASA,cACdC,CAAiD,EAEjD,IAAMC,EAAM,GAAIC,CAAAA,GAAAA,EAChB,IAAK,IAAMC,KAAQH,EACjBC,EAAIE,IAAI,CAAC,kBAA4BC,MAAA,CAAVD,EAAKE,IAAI,EAAIF,EAAKG,IAAI,EAEnD,OAAOL,CACT,CAEO,eAAeM,YAAYN,CAAU,CAAEI,CAAY,EACxD,IAAMG,EAAO,MAAMP,EAAIQ,aAAa,CAAC,CAAEC,KAAM,MAAO,GACpDC,CAAAA,EAAAA,EAAAA,MAAAA,EAAOH,EAAMH,EACf,CAEO,SAASO,YAAYC,CAAgB,CAAER,CAAY,EACxDM,CAAAA,EAAAA,EAAAA,MAAAA,EAAOE,EAAUR,EACnB","sources":["webpack://_N_E/./src/exportUtils.ts","webpack://_N_E/<anon>"],"sourcesContent":["import JSZip from \"jszip\";\r\nimport { saveAs } from \"file-saver\";\r\n\r\nexport function createZipFile(\r\n files: Array<{ name: string; data: ArrayBuffer }>\r\n) {\r\n const zip = new JSZip();\r\n for (const file of files) {\r\n zip.file(`textures/skins/${file.name}`, file.data);\r\n }\r\n return zip;\r\n}\r\n\r\nexport async function saveZipFile(zip: JSZip, name: string) {\r\n const blob = await zip.generateAsync({ type: \"blob\" });\r\n saveAs(blob, name);\r\n}\r\n\r\nexport function savePngFile(imageUrl: string, name: string) {\r\n saveAs(imageUrl, name);\r\n}\r\n"],"names":["createZipFile","files","zip","JSZip","file","concat","name","data","saveZipFile","blob","generateAsync","type","saveAs","savePngFile","imageUrl"],"sourceRoot":""}
{"version":3,"file":"static/chunks/767.5a1b83173dac696e.js","mappings":"+QAGO,SAASA,cACdC,CAAiD,EAEjD,IAAMC,EAAM,GAAIC,CAAAA,GAAAA,EAChB,IAAK,IAAMC,KAAQH,EACjBC,EAAIE,IAAI,CAAC,kBAA4BC,MAAA,CAAVD,EAAKE,IAAI,EAAIF,EAAKG,IAAI,EAEnD,OAAOL,CACT,CAEO,eAAeM,YAAYN,CAAU,CAAEI,CAAY,EACxD,IAAMG,EAAO,MAAMP,EAAIQ,aAAa,CAAC,CAAEC,KAAM,MAAO,GACpDC,CAAAA,EAAAA,EAAAA,MAAAA,EAAOH,EAAMH,EACf,CAEO,SAASO,YAAYC,CAAgB,CAAER,CAAY,EACxDM,CAAAA,EAAAA,EAAAA,MAAAA,EAAOE,EAAUR,EACnB","sources":["webpack://_N_E/./src/exportUtils.ts","webpack://_N_E/<anon>"],"sourcesContent":["import JSZip from \"jszip\";\nimport { saveAs } from \"file-saver\";\n\nexport function createZipFile(\n files: Array<{ name: string; data: ArrayBuffer }>\n) {\n const zip = new JSZip();\n for (const file of files) {\n zip.file(`textures/skins/${file.name}`, file.data);\n }\n return zip;\n}\n\nexport async function saveZipFile(zip: JSZip, name: string) {\n const blob = await zip.generateAsync({ type: \"blob\" });\n saveAs(blob, name);\n}\n\nexport function savePngFile(imageUrl: string, name: string) {\n saveAs(imageUrl, name);\n}\n"],"names":["createZipFile","files","zip","JSZip","file","concat","name","data","saveZipFile","blob","generateAsync","type","saveAs","savePngFile","imageUrl"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"static/chunks/pages/_app-3fa88258652f2cb2.js","mappings":"oFAAAA,EAAAC,OAAA,CAAAC,EAAA,4BCCA,CAAAC,OAAAC,QAAA,CAAAD,OAAAC,QAAA,MAAAC,IAAA,EACA,QACA,WACA,OAAeH,EAAQ,IACvB,EACA,kFCFAI,EAAA,QAAeC","sources":["webpack://_N_E/./node_modules/next/app.js","webpack://_N_E/?b089","webpack://_N_E/./src/pages/_app.ts","webpack://_N_E/./node_modules/rc-slider/assets/index.css","webpack://_N_E/./src/styles/global.css","webpack://_N_E/<anon>"],"sourcesContent":["module.exports = require('./dist/pages/_app')\n","\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_app\",\n function () {\n return require(\"private-next-pages/_app.ts\");\n }\n ]);\n if(module.hot) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_app\"])\n });\n }\n ","import App from \"next/app\";\r\nimport \"../styles/global.css\";\r\nimport \"rc-slider/assets/index.css\";\r\n\r\nexport default App;\r\n","// extracted by mini-css-extract-plugin","// extracted by mini-css-extract-plugin"],"names":["module","exports","__webpack_require__","window","__NEXT_P","push","__webpack_exports__","App"],"sourceRoot":""}
{"version":3,"file":"static/chunks/pages/_app-3fa88258652f2cb2.js","mappings":"oFAAAA,EAAAC,OAAA,CAAAC,EAAA,4BCCA,CAAAC,OAAAC,QAAA,CAAAD,OAAAC,QAAA,MAAAC,IAAA,EACA,QACA,WACA,OAAeH,EAAQ,IACvB,EACA,kFCFAI,EAAA,QAAeC","sources":["webpack://_N_E/./node_modules/next/app.js","webpack://_N_E/?b089","webpack://_N_E/./src/pages/_app.ts","webpack://_N_E/./node_modules/rc-slider/assets/index.css","webpack://_N_E/./src/styles/global.css","webpack://_N_E/<anon>"],"sourcesContent":["module.exports = require('./dist/pages/_app')\n","\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/_app\",\n function () {\n return require(\"private-next-pages/_app.ts\");\n }\n ]);\n if(module.hot) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/_app\"])\n });\n }\n ","import App from \"next/app\";\nimport \"../styles/global.css\";\nimport \"rc-slider/assets/index.css\";\n\nexport default App;\n","// extracted by mini-css-extract-plugin","// extracted by mini-css-extract-plugin"],"names":["module","exports","__webpack_require__","window","__NEXT_P","push","__webpack_exports__","App"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
!function(){"use strict";var e,r,_,t,n,i,u,c={},o={};function __webpack_require__(e){var r=o[e];if(void 0!==r)return r.exports;var _=o[e]={exports:{}},t=!0;try{c[e].call(_.exports,_,_.exports,__webpack_require__),t=!1}finally{t&&delete o[e]}return _.exports}__webpack_require__.m=c,e=[],__webpack_require__.O=function(r,_,t,n){if(_){n=n||0;for(var i=e.length;i>0&&e[i-1][2]>n;i--)e[i]=e[i-1];e[i]=[_,t,n];return}for(var u=1/0,i=0;i<e.length;i++){for(var _=e[i][0],t=e[i][1],n=e[i][2],c=!0,o=0;o<_.length;o++)u>=n&&Object.keys(__webpack_require__.O).every(function(e){return __webpack_require__.O[e](_[o])})?_.splice(o--,1):(c=!1,n<u&&(u=n));if(c){e.splice(i--,1);var a=t()}}return a},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,{a:r}),r},__webpack_require__.d=function(e,r){for(var _ in r)__webpack_require__.o(r,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,get:r[_]})},__webpack_require__.f={},__webpack_require__.e=function(e){return Promise.all(Object.keys(__webpack_require__.f).reduce(function(r,_){return __webpack_require__.f[_](e,r),r},[]))},__webpack_require__.u=function(e){return"static/chunks/"+(737===e?"fb7d5399":e)+"."+({250:"a985869c089b2fd3",354:"c8f476539d33c65e",737:"bc4a70b34221e8c8",767:"5a1b83173dac696e",848:"fc0fe21cdc2e6431"})[e]+".js"},__webpack_require__.miniCssF=function(e){return"static/css/8f9c54e3d59c6be4.css"},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},r={},_="_N_E:",__webpack_require__.l=function(e,t,n,i){if(r[e]){r[e].push(t);return}if(void 0!==n)for(var u,c,o=document.getElementsByTagName("script"),a=0;a<o.length;a++){var p=o[a];if(p.getAttribute("src")==e||p.getAttribute("data-webpack")==_+n){u=p;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",u.timeout=120,__webpack_require__.nc&&u.setAttribute("nonce",__webpack_require__.nc),u.setAttribute("data-webpack",_+n),u.src=__webpack_require__.tu(e)),r[e]=[t];var onScriptComplete=function(_,t){u.onerror=u.onload=null,clearTimeout(f);var n=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),n&&n.forEach(function(e){return e(t)}),_)return _(t)},f=setTimeout(onScriptComplete.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=onScriptComplete.bind(null,u.onerror),u.onload=onScriptComplete.bind(null,u.onload),c&&document.head.appendChild(u)},__webpack_require__.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.tt=function(){return void 0===t&&(t={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(t=trustedTypes.createPolicy("nextjs#bundler",t))),t},__webpack_require__.tu=function(e){return __webpack_require__.tt().createScriptURL(e)},__webpack_require__.p="/t2-model-skinner/_next/",n={272:0},__webpack_require__.f.j=function(e,r){var _=__webpack_require__.o(n,e)?n[e]:void 0;if(0!==_){if(_)r.push(_[2]);else if(272!=e){var t=new Promise(function(r,t){_=n[e]=[r,t]});r.push(_[2]=t);var i=__webpack_require__.p+__webpack_require__.u(e),u=Error();__webpack_require__.l(i,function(r){if(__webpack_require__.o(n,e)&&(0!==(_=n[e])&&(n[e]=void 0),_)){var t=r&&("load"===r.type?"missing":r.type),i=r&&r.target&&r.target.src;u.message="Loading chunk "+e+" failed.\n("+t+": "+i+")",u.name="ChunkLoadError",u.type=t,u.request=i,_[1](u)}},"chunk-"+e,e)}else n[e]=0}},__webpack_require__.O.j=function(e){return 0===n[e]},i=function(e,r){var _,t,i=r[0],u=r[1],c=r[2],o=0;if(i.some(function(e){return 0!==n[e]})){for(_ in u)__webpack_require__.o(u,_)&&(__webpack_require__.m[_]=u[_]);if(c)var a=c(__webpack_require__)}for(e&&e(r);o<i.length;o++)t=i[o],__webpack_require__.o(n,t)&&n[t]&&n[t][0](),n[t]=0;return __webpack_require__.O(a)},(u=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(i.bind(null,0)),u.push=i.bind(null,u.push.bind(u))}();
//# sourceMappingURL=webpack-0d2be6fe958413db.js.map
!function(){"use strict";var e,r,_,t,n,i,u,c={},o={};function __webpack_require__(e){var r=o[e];if(void 0!==r)return r.exports;var _=o[e]={exports:{}},t=!0;try{c[e].call(_.exports,_,_.exports,__webpack_require__),t=!1}finally{t&&delete o[e]}return _.exports}__webpack_require__.m=c,e=[],__webpack_require__.O=function(r,_,t,n){if(_){n=n||0;for(var i=e.length;i>0&&e[i-1][2]>n;i--)e[i]=e[i-1];e[i]=[_,t,n];return}for(var u=1/0,i=0;i<e.length;i++){for(var _=e[i][0],t=e[i][1],n=e[i][2],c=!0,o=0;o<_.length;o++)u>=n&&Object.keys(__webpack_require__.O).every(function(e){return __webpack_require__.O[e](_[o])})?_.splice(o--,1):(c=!1,n<u&&(u=n));if(c){e.splice(i--,1);var a=t()}}return a},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,{a:r}),r},__webpack_require__.d=function(e,r){for(var _ in r)__webpack_require__.o(r,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,get:r[_]})},__webpack_require__.f={},__webpack_require__.e=function(e){return Promise.all(Object.keys(__webpack_require__.f).reduce(function(r,_){return __webpack_require__.f[_](e,r),r},[]))},__webpack_require__.u=function(e){return"static/chunks/"+(737===e?"fb7d5399":e)+"."+({250:"a985869c089b2fd3",354:"c8f476539d33c65e",737:"bc4a70b34221e8c8",767:"5a1b83173dac696e",848:"fc0fe21cdc2e6431"})[e]+".js"},__webpack_require__.miniCssF=function(e){return"static/css/8f9c54e3d59c6be4.css"},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},r={},_="_N_E:",__webpack_require__.l=function(e,t,n,i){if(r[e]){r[e].push(t);return}if(void 0!==n)for(var u,c,o=document.getElementsByTagName("script"),a=0;a<o.length;a++){var p=o[a];if(p.getAttribute("src")==e||p.getAttribute("data-webpack")==_+n){u=p;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",u.timeout=120,__webpack_require__.nc&&u.setAttribute("nonce",__webpack_require__.nc),u.setAttribute("data-webpack",_+n),u.src=__webpack_require__.tu(e)),r[e]=[t];var onScriptComplete=function(_,t){u.onerror=u.onload=null,clearTimeout(b);var n=r[e];if(delete r[e],u.parentNode&&u.parentNode.removeChild(u),n&&n.forEach(function(e){return e(t)}),_)return _(t)},b=setTimeout(onScriptComplete.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=onScriptComplete.bind(null,u.onerror),u.onload=onScriptComplete.bind(null,u.onload),c&&document.head.appendChild(u)},__webpack_require__.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.tt=function(){return void 0===t&&(t={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(t=trustedTypes.createPolicy("nextjs#bundler",t))),t},__webpack_require__.tu=function(e){return __webpack_require__.tt().createScriptURL(e)},__webpack_require__.p="/t2-model-skinner/_next/",n={272:0},__webpack_require__.f.j=function(e,r){var _=__webpack_require__.o(n,e)?n[e]:void 0;if(0!==_){if(_)r.push(_[2]);else if(272!=e){var t=new Promise(function(r,t){_=n[e]=[r,t]});r.push(_[2]=t);var i=__webpack_require__.p+__webpack_require__.u(e),u=Error();__webpack_require__.l(i,function(r){if(__webpack_require__.o(n,e)&&(0!==(_=n[e])&&(n[e]=void 0),_)){var t=r&&("load"===r.type?"missing":r.type),i=r&&r.target&&r.target.src;u.message="Loading chunk "+e+" failed.\n("+t+": "+i+")",u.name="ChunkLoadError",u.type=t,u.request=i,_[1](u)}},"chunk-"+e,e)}else n[e]=0}},__webpack_require__.O.j=function(e){return 0===n[e]},i=function(e,r){var _,t,i=r[0],u=r[1],c=r[2],o=0;if(i.some(function(e){return 0!==n[e]})){for(_ in u)__webpack_require__.o(u,_)&&(__webpack_require__.m[_]=u[_]);if(c)var a=c(__webpack_require__)}for(e&&e(r);o<i.length;o++)t=i[o],__webpack_require__.o(n,t)&&n[t]&&n[t][0](),n[t]=0;return __webpack_require__.O(a)},(u=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(i.bind(null,0)),u.push=i.bind(null,u.push.bind(u))}();
//# sourceMappingURL=webpack-cbee82fe57b0dc2e.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
import { useEffect } from "react";
import { MutableRefObject, useEffect, useRef } from "react";
import type { ModelViewerElement } from "@google/model-viewer";
import useSettings from "./useSettings";
import useSkin from "./useSkin";
@ -32,16 +32,23 @@ export type MaterialDefinition = {
frameTimings?: number[];
};
type FrameInfo = {
frameIndex: number;
frameProgress: number;
};
function useTexture({
material,
materialDef,
textureType,
imageUrl,
frameRef,
}: {
material: ModelMaterial;
materialDef?: MaterialDefinition;
textureType: "baseColorTexture" | "metallicRoughnessTexture";
imageUrl?: string[];
frameRef: MutableRefObject<FrameInfo>;
}) {
const { modelViewer } = useModelViewer();
const { basePath } = useSettings();
@ -70,8 +77,10 @@ function useTexture({
frameCount = 1,
frameTimings,
} = materialDef;
let textureUrls =
imageUrl ?? new Array(frameCount).fill(`${basePath}/white.png`);
switch (textureType) {
case "baseColorTexture":
if (baseColorFactor) {
@ -98,25 +107,29 @@ function useTexture({
textureUrls.map((textureUrl) => modelViewer.createTexture(textureUrl))
);
if (!stale) {
let frameIndex = 0;
let frameProgress = 0;
const frame: FrameRequestCallback = (timestamp) => {
const frameTiming = frameTimings?.[frameIndex] ?? 1;
const texture = textures[frameIndex];
const isMasterTexture = textureType === "baseColorTexture";
const frameInfo = frameRef.current;
const frame: FrameRequestCallback = () => {
const texture = textures[frameInfo.frameIndex];
material.pbrMetallicRoughness[textureType].setTexture(texture);
if (textureType === "baseColorTexture" && emissiveTexture) {
if (isMasterTexture && emissiveTexture) {
material.emissiveTexture.setTexture(texture);
}
frameProgress += 1;
if (isMasterTexture) {
frameInfo.frameProgress += 1;
}
if (frameCount > 1) {
if (frameProgress >= frameTiming) {
frameIndex = (frameIndex + 1) % frameCount;
frameProgress = 0;
const frameTiming = frameTimings?.[frameInfo.frameIndex] ?? 1;
if (isMasterTexture && frameInfo.frameProgress >= frameTiming) {
frameInfo.frameIndex = (frameInfo.frameIndex + 1) % frameCount;
frameInfo.frameProgress = 0;
}
animationFrame = requestAnimationFrame(frame);
}
};
animationFrame = requestAnimationFrame(frame);
frame(0);
}
}
};
@ -125,9 +138,19 @@ function useTexture({
return () => {
stale = true;
cancelAnimationFrame(animationFrame);
if (animationFrame != null) {
cancelAnimationFrame(animationFrame);
}
};
}, [basePath, modelViewer, material, materialDef, textureType, imageUrl]);
}, [
basePath,
modelViewer,
material,
materialDef,
textureType,
imageUrl,
frameRef,
]);
}
interface MaterialProps {
@ -139,18 +162,21 @@ export default function Material({ material, materialDef }: MaterialProps) {
const { getSkinImages } = useSkin();
const { colorImageUrl, metallicImageUrl } =
getSkinImages(materialDef?.file ?? material.name) ?? {};
const frameRef = useRef<FrameInfo>({ frameIndex: 0, frameProgress: 0 });
useTexture({
material,
materialDef,
textureType: "baseColorTexture",
imageUrl: colorImageUrl,
frameRef,
});
useTexture({
material,
materialDef,
textureType: "metallicRoughnessTexture",
imageUrl: metallicImageUrl,
frameRef,
});
return null;

View file

@ -23,7 +23,7 @@ export default function SkinProvider({ children }: { children: ReactNode }) {
const newColorImageUrl = Array.from(
materialSkins[materialFile]?.colorImageUrl ?? []
);
newColorImageUrl.splice(frameIndex, 1, colorImageUrl);
newColorImageUrl[frameIndex] = colorImageUrl;
return {
...materialSkins,
[materialFile]: {
@ -42,7 +42,7 @@ export default function SkinProvider({ children }: { children: ReactNode }) {
const newMetallicImageUrl = Array.from(
materialSkins[materialFile]?.metallicImageUrl ?? []
);
newMetallicImageUrl.splice(frameIndex, 1, metallicImageUrl);
newMetallicImageUrl[frameIndex] = metallicImageUrl;
return {
...materialSkins,
[materialFile]: {