mbt-3d 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +22 -1
- package/dist/mbt-3d.cjs +1 -1
- package/dist/mbt-3d.cjs.map +1 -1
- package/dist/mbt-3d.js +630 -611
- package/dist/mbt-3d.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -279,6 +279,25 @@ declare interface DirectionalLightConfig extends BaseLightConfig {
|
|
|
279
279
|
castShadow?: boolean;
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Environment (HDRI) configuration for realistic lighting and reflections
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```tsx
|
|
287
|
+
* { files: '/scenes/studio.hdr', intensity: 1, background: false }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
declare interface EnvironmentConfig {
|
|
291
|
+
/** URL to HDRI file (.hdr or .exr) */
|
|
292
|
+
files: string;
|
|
293
|
+
/** Environment intensity multiplier. Default: 1 */
|
|
294
|
+
intensity?: number;
|
|
295
|
+
/** Use HDRI as scene background. Default: false */
|
|
296
|
+
background?: boolean;
|
|
297
|
+
/** Blur amount for background (0-1). Default: 0 */
|
|
298
|
+
blur?: number;
|
|
299
|
+
}
|
|
300
|
+
|
|
282
301
|
/**
|
|
283
302
|
* Hemisphere light configuration - soft sky/ground lighting (no shadows)
|
|
284
303
|
*
|
|
@@ -647,7 +666,7 @@ export declare function preloadModel(url: string): void;
|
|
|
647
666
|
* </Scene3D>
|
|
648
667
|
* ```
|
|
649
668
|
*/
|
|
650
|
-
export declare function Scene3D({ children, camera, controls, background, shadows, lights, contactShadows, style, className, }: Scene3DProps): JSX_2.Element;
|
|
669
|
+
export declare function Scene3D({ children, camera, controls, background, shadows, lights, environment, contactShadows, style, className, }: Scene3DProps): JSX_2.Element;
|
|
651
670
|
|
|
652
671
|
/**
|
|
653
672
|
* Props for Scene3D component
|
|
@@ -707,6 +726,8 @@ export declare interface Scene3DProps {
|
|
|
707
726
|
shadows?: boolean;
|
|
708
727
|
/** Array of light configurations for multi-light setup */
|
|
709
728
|
lights?: LightConfigUnion[];
|
|
729
|
+
/** Environment (HDRI) configuration for realistic lighting and reflections */
|
|
730
|
+
environment?: EnvironmentConfig;
|
|
710
731
|
/** Contact shadows configuration (ground shadows under models) */
|
|
711
732
|
contactShadows?: boolean | {
|
|
712
733
|
/** Shadow position [x, y, z]. Default: [0, -1, 0] */
|
package/dist/mbt-3d.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),O=require("@react-three/drei"),se=require("three"),ne=require("three/examples/jsm/utils/SkeletonUtils.js"),B=require("@react-three/fiber"),ae=require("three/examples/jsm/loaders/KTX2Loader.js"),w=require("react/jsx-runtime");function J(n){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const s in n)if(s!=="default"){const l=Object.getOwnPropertyDescriptor(n,s);Object.defineProperty(t,s,l.get?l:{enumerable:!0,get:()=>n[s]})}}return t.default=n,Object.freeze(t)}const E=J(se),Q=J(ne);function le({position:n,controlsConfig:t}){const{camera:s}=B.useThree(),l=e.useRef(null);return e.useEffect(()=>{n&&s&&(s.position.set(n[0],n[1],n[2]),s.updateProjectionMatrix(),l.current&&(l.current.target.set(0,0,0),l.current.update()))},[n,s]),w.jsx(O.OrbitControls,{ref:l,makeDefault:!0,enabled:t.enabled,enablePan:t.enablePan,enableZoom:t.enableZoom,enableRotate:t.enableRotate,minDistance:t.minDistance,maxDistance:t.maxDistance,minPolarAngle:t.minPolarAngle,maxPolarAngle:t.maxPolarAngle,autoRotate:t.autoRotate,autoRotateSpeed:t.autoRotateSpeed})}function ie({background:n}){const t=n==null?void 0:n.startsWith("#");return n?t?w.jsx("color",{attach:"background",args:[n]}):w.jsx(ce,{url:n}):null}function ce({url:n}){const t=O.useTexture(n);return e.useMemo(()=>{t.colorSpace=E.SRGBColorSpace},[t]),w.jsx("primitive",{attach:"background",object:t})}function ue({config:n}){switch(n.type){case"spot":{const{position:t=[5,10,5],intensity:s=50,castShadow:l=!0,angle:f=Math.PI/6,penumbra:g=.5,decay:T=2,distance:x=0,color:h="#ffffff"}=n;return w.jsx("spotLight",{position:t,intensity:s,castShadow:l,angle:f,penumbra:g,decay:T,distance:x,color:h})}case"point":{const{position:t=[0,5,0],intensity:s=20,color:l="#ffffff",distance:f=0,decay:g=2,castShadow:T=!1}=n;return w.jsx("pointLight",{position:t,intensity:s,color:l,distance:f,decay:g,castShadow:T})}case"directional":{const{position:t=[10,20,10],intensity:s=40,color:l="#ffffff",castShadow:f=!0}=n;return w.jsx("directionalLight",{position:t,intensity:s,color:l,castShadow:f})}case"hemisphere":{const{skyColor:t="#ffffff",groundColor:s="#444444",intensity:l=.5,position:f=[0,10,0]}=n,g=e.useMemo(()=>new E.Color(t),[t]),T=e.useMemo(()=>new E.Color(s),[s]);return w.jsx("hemisphereLight",{args:[g,T,l],position:f})}case"ambient":{const{intensity:t=.5,color:s="#ffffff"}=n;return w.jsx("ambientLight",{intensity:t,color:s})}default:return null}}function pe({children:n,camera:t={},controls:s={},background:l,shadows:f=!0,lights:g=[{type:"ambient",intensity:.5},{type:"spot",position:[5,10,5],intensity:50,castShadow:!0}],contactShadows:T=!0,style:x,className:h}){const r={position:t.position||[0,2,5],fov:t.fov||45},o={enabled:s.enabled??!0,enablePan:s.enablePan??!0,enableZoom:s.enableZoom??!0,enableRotate:s.enableRotate??!0,minDistance:s.minDistance,maxDistance:s.maxDistance,minPolarAngle:s.minPolarAngle,maxPolarAngle:s.maxPolarAngle,autoRotate:s.autoRotate??!1,autoRotateSpeed:s.autoRotateSpeed??2},c=typeof T=="object"?{position:T.position||[0,-1,0],opacity:T.opacity??.5,blur:T.blur??2}:T?{position:[0,-1,0],opacity:.5,blur:2}:null;return w.jsx("div",{style:x,className:h,children:w.jsxs(B.Canvas,{shadows:f,camera:{position:r.position,fov:r.fov},style:{width:"100%",height:"100%"},children:[w.jsx(e.Suspense,{fallback:null,children:w.jsx(ie,{background:l})}),g.map((u,y)=>w.jsx(ue,{config:u},`${u.type}-${y}`)),w.jsx(e.Suspense,{fallback:null,children:n}),w.jsx(le,{position:r.position,controlsConfig:o}),c&&w.jsx(O.ContactShadows,{position:c.position,opacity:c.opacity,blur:c.blur})]})})}function G(n,t){const s=e.useRef(new Map),l=e.useRef({}),f=e.useRef({});e.useEffect(()=>{t&&(l.current={...t})},[t]),e.useEffect(()=>{if(!n)return;const h=new Map;n.traverse(r=>{if(r.isMesh){const o=r;o.name&&h.set(o.name,o)}}),s.current=h},[n]),B.useFrame(()=>{const h=s.current;if(h.size===0)return;const r={...l.current,...f.current};for(const[o,c]of Object.entries(r)){const u=h.get(o);u&&u.visible!==c&&(u.visible=c)}});const g=e.useCallback((h,r)=>{f.current[h]=r;const o=s.current.get(h);o&&(o.visible=r)},[]),T=e.useCallback(()=>Array.from(s.current.keys()).sort(),[]),x=e.useCallback(()=>{const h={};return s.current.forEach((r,o)=>{h[o]=r.visible}),h},[]);return{setMeshVisibility:g,getMeshNames:T,getMeshVisibility:x}}function K(n,t){const s=e.useRef(new Map),l=e.useRef(new Map);e.useEffect(()=>{if(!n)return;const r=new Map;n.traverse(o=>{if(o.isMesh){const c=o;(Array.isArray(c.material)?c.material:[c.material]).forEach(y=>{y.name&&!r.has(y.name)&&r.set(y.name,y)})}}),s.current=r,console.log("[useMaterialColor] 🎨 Discovered materials:",Array.from(r.keys())),r.forEach((o,c)=>{if(!Array.isArray(o)){const u=o;if(u.color){const y=u.color.clone();console.log(`[useMaterialColor] 📋 Original color for "${c}": ${y.getHexString()}`),u.color.set(16777215),u.needsUpdate=!0,console.log(`[useMaterialColor] ✅ Reset "${c}" to white (0xffffff)`),l.current.set(c,u.color.clone())}}}),t&&Object.entries(t).forEach(([o,c])=>{const u=r.get(o);if(u&&!Array.isArray(u)){const y=f(c);u.color&&u.color.copy(y),l.current.set(o,y),console.log(`[useMaterialColor] 🎨 Applied custom color for "${o}": ${y.getHexString()}`)}})},[n,t]),B.useFrame(()=>{l.current.forEach((r,o)=>{const c=s.current.get(o);if(c&&!Array.isArray(c)){const u=c;u.color&&!u.color.equals(r)&&(console.log(`[useMaterialColor] 🔄 Applying color to "${o}": ${u.color.getHexString()} -> ${r.getHexString()}`),u.color.copy(r),u.needsUpdate=!0)}})});const f=r=>typeof r=="string"?new E.Color(r):new E.Color(r[0],r[1],r[2]),g=e.useCallback((r,o)=>{const c=f(o);l.current.set(r,c);const u=s.current.get(r);if(u&&!Array.isArray(u)){const y=u;y.color&&(y.color.copy(c),y.needsUpdate=!0)}},[]),T=e.useCallback(()=>Array.from(s.current.keys()).sort(),[]),x=e.useCallback(r=>{const o=s.current.get(r);if(o&&!Array.isArray(o)){const c=o;if(c.color)return"#"+c.color.getHexString()}return null},[]),h=e.useCallback(()=>{const r={};return s.current.forEach((o,c)=>{if(!Array.isArray(o)){const u=o;u.color&&(r[c]="#"+u.color.getHexString())}}),r},[]);return{setMaterialColor:g,getMaterialNames:T,getMaterialColor:x,getAllMaterialColors:h}}function U(n,t){const{gl:s}=B.useThree(),l=e.useRef(new Map),f=e.useRef(new E.TextureLoader),g=e.useRef(null),T=e.useRef(new Map),x=e.useRef(new Set),h=e.useRef("");e.useEffect(()=>{if(!g.current)try{const a=typeof WebAssembly=="object"&&typeof WebAssembly.validate=="function";console.log("[useMaterialTexture] Browser features:"),console.log(` WebAssembly supported: ${a}`),console.log(` WebGL2: ${s.capabilities.isWebGL2}`);const i=new ae.KTX2Loader;i.setTranscoderPath("/basis/"),i.detectSupport(s),g.current=i,console.log("[useMaterialTexture] ✅ KTX2Loader initialized"),console.log("[useMaterialTexture] Transcoder path: /basis/"),fetch("/basis/basis_transcoder.wasm").then(m=>{m.ok?console.log("[useMaterialTexture] ✅ basis_transcoder.wasm is accessible"):console.error("[useMaterialTexture] ❌ basis_transcoder.wasm returned",m.status)}).catch(m=>{console.error("[useMaterialTexture] ❌ Failed to check basis_transcoder.wasm:",m)}),a||(console.warn("[useMaterialTexture] ⚠️ WebAssembly not supported! KTX2 will fallback to CPU decoding (slow)"),console.warn("[useMaterialTexture] ⚠️ Recommend using WebP instead of KTX2 for this browser"))}catch(a){console.error("[useMaterialTexture] ❌ Failed to initialize KTX2Loader:",a)}return()=>{g.current&&(g.current.dispose(),g.current=null)}},[s]),e.useEffect(()=>{if(!n)return;const a=new Map;n.traverse(i=>{if(i.isMesh){const m=i;(Array.isArray(m.material)?m.material:[m.material]).forEach(d=>{d.name&&!a.has(d.name)&&a.set(d.name,d)})}}),l.current=a},[n]);const r=e.useCallback(a=>a.toLowerCase().endsWith(".ktx2")?g.current?g.current:(console.warn("[useMaterialTexture] KTX2Loader not initialized, falling back to TextureLoader"),f.current):f.current,[]);e.useEffect(()=>{if(!t||!n)return;const a=l.current;if(a.size===0)return;const i=JSON.stringify(t);if(h.current===i){console.log("[useMaterialTexture] Textures unchanged, skipping reload");return}h.current=i;let m=!1;const S=new Map;Object.entries(t).forEach(([M,b])=>{S.set(M,typeof b=="string"?{map:b}:b)}),console.log("[useMaterialTexture] Starting texture load for",S.size,"materials");const d=[];S.forEach((M,b)=>{var A,k;const D=a.get(b);if(!D||!D.isMeshStandardMaterial){console.warn(`[useMaterialTexture] Material "${b}" not found or not MeshStandardMaterial`);return}const p=D;console.log(`[useMaterialTexture] 📋 Material "${b}" BEFORE reset:`),console.log(` - map: ${p.map?"EXISTS":"null"} ${p.map?`(uuid: ${p.map.uuid})`:""}`),console.log(` - normalMap: ${p.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${p.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${p.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${p.emissiveMap?"EXISTS":"null"}`),console.log(` - aoMap: ${p.aoMap?"EXISTS":"null"}`),console.log(` - color: ${(A=p.color)==null?void 0:A.getHexString()}`),console.log(` - emissive: ${(k=p.emissive)==null?void 0:k.getHexString()}`),console.log(` - material uuid: ${p.uuid}`),p.map&&(console.log(`[useMaterialTexture] 🗑️ Disposing old map (uuid: ${p.map.uuid})`),p.map.dispose()),p.normalMap&&(console.log("[useMaterialTexture] 🗑️ Disposing old normalMap"),p.normalMap.dispose()),p.roughnessMap&&(console.log("[useMaterialTexture] 🗑️ Disposing old roughnessMap"),p.roughnessMap.dispose()),p.metalnessMap&&(console.log("[useMaterialTexture] 🗑️ Disposing old metalnessMap"),p.metalnessMap.dispose()),p.emissiveMap&&(console.log("[useMaterialTexture] 🗑️ Disposing old emissiveMap"),p.emissiveMap.dispose()),p.aoMap&&(console.log("[useMaterialTexture] 🗑️ Disposing old aoMap"),p.aoMap.dispose()),p.map=null,p.normalMap=null,p.roughnessMap=null,p.metalnessMap=null,p.emissiveMap=null,p.emissive=new E.Color(0),p.emissiveIntensity=0,p.aoMap=null,p.needsUpdate=!0,console.log(`[useMaterialTexture] ✅ Material "${b}" AFTER reset: all maps cleared and disposed`),Object.entries(M).forEach(([$,C])=>{if(!C)return;const j=`${b}_${$}_${C}`,X=T.current.get(j);if(X){console.log(`[useMaterialTexture] Using cached texture: ${b}.${$}`),m||o(p,$,X);return}if(x.current.has(j)){console.log(`[useMaterialTexture] Skipping already loading: ${b}.${$}`);return}d.push({materialName:b,textureType:$,url:C,material:p})})}),console.log(`[useMaterialTexture] Queued ${d.length} textures to load`);let v=0;const R=()=>{if(m||v>=d.length){console.log("[useMaterialTexture] ✅ All textures loaded"),console.log("[useMaterialTexture] 📊 FINAL material states:"),a.forEach((A,k)=>{var C,j;const $=A;console.log(` Material "${k}":`),console.log(` - map: ${$.map?"EXISTS":"null"} ${$.map?`(colorSpace: ${$.map.colorSpace})`:""}`),console.log(` - normalMap: ${$.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${$.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${$.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${$.emissiveMap?"EXISTS":"null"}`),console.log(` - color: ${(C=$.color)==null?void 0:C.getHexString()}`),console.log(` - emissive: ${(j=$.emissive)==null?void 0:j.getHexString()}`),console.log(` - emissiveIntensity: ${$.emissiveIntensity}`),console.log(` - roughness: ${$.roughness}`),console.log(` - metalness: ${$.metalness}`)});return}const M=d[v++],b=`${M.materialName}_${M.textureType}_${M.url}`;console.log(`[useMaterialTexture] Loading (${v}/${d.length}): ${M.materialName}.${M.textureType} from ${M.url}`),x.current.add(b);const D=r(M.url),p=M.url.toLowerCase().endsWith(".ktx2")?"KTX2Loader":"TextureLoader";console.log(`[useMaterialTexture] Using ${p} for ${M.url}`),D.load(M.url,A=>{var j,X,N,I,L,H;if(x.current.delete(b),m){console.log(`[useMaterialTexture] Disposed, cleaning up texture: ${M.materialName}.${M.textureType}`),A.dispose();return}const k=((j=A.image)==null?void 0:j.width)||((N=(X=A.source)==null?void 0:X.data)==null?void 0:N.width)||"unknown",$=((I=A.image)==null?void 0:I.height)||((H=(L=A.source)==null?void 0:L.data)==null?void 0:H.height)||"unknown";console.log(`[useMaterialTexture] ✅ Loaded: ${M.materialName}.${M.textureType} (${k}x${$})`),A.colorSpace=M.textureType==="map"||M.textureType==="emissiveMap"?E.SRGBColorSpace:E.NoColorSpace,A.wrapS=E.RepeatWrapping,A.wrapT=E.RepeatWrapping,A.flipY=!1,T.current.set(b,A),o(M.material,M.textureType,A);const C=M.url.endsWith(".ktx2")?500:150;console.log(`[useMaterialTexture] Waiting111111 ${C}ms before next texture...`),setTimeout(R,0)},A=>{if(A.lengthComputable){const k=Math.round(A.loaded/A.total*100);k%25===0&&console.log(`[useMaterialTexture] Progress ${M.materialName}.${M.textureType}: ${k}%`)}},A=>{x.current.delete(b),m||(console.error(`[useMaterialTexture] ❌ Failed to load ${M.materialName}.${M.textureType} from ${M.url}`),console.error("[useMaterialTexture] Error details:",A),console.error("[useMaterialTexture] Loader type:",p),M.url.endsWith(".ktx2")&&(console.error("[useMaterialTexture] KTX2 error - file may not be in Basis Universal format!"),console.error("[useMaterialTexture] Make sure files are created with: gltf-transform etc1s input.png output.ktx2"))),setTimeout(R,100)})};return R(),()=>{console.log("[useMaterialTexture] Cleanup: disposed"),m=!0}},[n,t,r]);const o=(a,i,m)=>{var S,d;switch(console.log(`[useMaterialTexture] 🎨 Applying texture: ${a.name}.${i} (texture uuid: ${m.uuid})`),i){case"map":a.map=m;break;case"normalMap":a.normalMap=m;break;case"roughnessMap":a.roughnessMap=m;break;case"metalnessMap":a.metalnessMap=m;break;case"emissiveMap":a.emissiveMap=m,a.emissive=new E.Color(16777215),a.emissiveIntensity=1;break;case"alphaMap":console.log(`[useMaterialTexture] Skipping alphaMap for "${a.name}" to prevent disappearing`);break;case"aoMap":a.aoMap=m;break}a.needsUpdate=!0,console.log(`[useMaterialTexture] ✅ Applied ${i} to ${a.name}, needsUpdate=true`),console.log(`[useMaterialTexture] 📊 Material "${a.name}" FINAL state:`),console.log(` - map: ${a.map?"EXISTS":"null"} ${a.map?`(uuid: ${a.map.uuid}, colorSpace: ${a.map.colorSpace})`:""}`),console.log(` - normalMap: ${a.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${a.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${a.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${a.emissiveMap?"EXISTS":"null"}`),console.log(` - aoMap: ${a.aoMap?"EXISTS":"null"}`),console.log(` - color: ${(S=a.color)==null?void 0:S.getHexString()}`),console.log(` - emissive: ${(d=a.emissive)==null?void 0:d.getHexString()}`),console.log(` - emissiveIntensity: ${a.emissiveIntensity}`),console.log(` - roughness: ${a.roughness}`),console.log(` - metalness: ${a.metalness}`)},c=e.useCallback((a,i)=>{const m=typeof i=="string"?{map:i}:i,S=l.current.get(a);if(!S||!S.isMeshStandardMaterial){console.warn(`Material "${a}" not found or not MeshStandardMaterial`);return}const d=S;Object.entries(m).forEach(([v,R])=>{if(!R)return;const M=`${a}_${v}_${R}`,b=T.current.get(M);if(b){o(d,v,b);return}r(R).load(R,p=>{p.colorSpace=v==="map"||v==="emissiveMap"?E.SRGBColorSpace:E.NoColorSpace,p.wrapS=E.RepeatWrapping,p.wrapT=E.RepeatWrapping,T.current.set(M,p),o(d,v,p)},void 0,p=>{console.error(`Failed to load texture ${R}:`,p)})})},[r]),u=e.useCallback(()=>Array.from(l.current.keys()).sort(),[]),y=e.useCallback(a=>{const i=l.current.get(a);if(!i||!i.isMeshStandardMaterial)return;const m=i;m.map=null,m.normalMap=null,m.roughnessMap=null,m.metalnessMap=null,m.emissiveMap=null,m.alphaMap=null,m.aoMap=null,m.needsUpdate=!0},[]);return{setMaterialTextures:c,getMaterialNames:u,clearMaterialTextures:y}}function ee({url:n,position:t=[0,0,0],rotation:s=[0,0,0],scale:l=1,meshVisibility:f,materialColors:g,materialTextures:T,onLoad:x,onError:h}){const{scene:r}=O.useGLTF(n),o=e.useRef(x);o.current=x;const c=e.useMemo(()=>{const y=r.clone();console.log("[Model] 🔍 Scene clone created, checking materials...");const a=[],i=new Set,m=[];let S=0;return y.traverse(d=>{if(S++,d.type==="Bone"&&m.push(d.name),d.isMesh){const v=d;a.push(v.name),v.castShadow=!0,v.receiveShadow=!0,(Array.isArray(v.material)?v.material:[v.material]).forEach(M=>{i.add(M.name),console.log(`[Model] 📦 Material found: "${M.name}" (uuid: ${M.uuid})`);const b=M;console.log(` - Has map: ${b.map?"YES":"NO"}`),console.log(` - Has normalMap: ${b.normalMap?"YES":"NO"}`),console.log(` - Has roughnessMap: ${b.roughnessMap?"YES":"NO"}`),console.log(` - Has metalnessMap: ${b.metalnessMap?"YES":"NO"}`)})}}),console.log(`[Model] 📊 Clone summary: ${a.length} meshes, ${i.size} materials`),setTimeout(()=>{var d;(d=o.current)==null||d.call(o,{meshes:a.sort(),materials:Array.from(i).sort(),bones:m.sort(),nodeCount:S})},0),y},[r]);G(c,f),K(c,g),U(c,T);const u=typeof l=="number"?[l,l,l]:l;return w.jsx("group",{position:t,rotation:s,scale:u,children:w.jsx("primitive",{object:c})})}ee.preload=n=>{O.useGLTF.preload(n)};function te(n,t,s){const{actions:l,names:f}=O.useAnimations(n,t),g=e.useRef(null),T=e.useRef(s==null?void 0:s.defaultAnimation);e.useEffect(()=>{if(f.length===0)return;const o=T.current;let c=f[0];if(o){const y=f.find(a=>a===o||a.includes(o));y&&(c=y)}const u=l[c];u&&(u.reset().fadeIn(.5).play(),g.current=u)},[l,f]);const x=e.useCallback((o,c)=>{const{loop:u=!1,crossFadeDuration:y=.2,restoreDefault:a=!0}=c||{};let i=l[o];if(!i){const S=Object.keys(l).find(d=>d.toLowerCase().includes(o.toLowerCase())||o.toLowerCase().includes(d.toLowerCase()));S&&(i=l[S])}if(!i){console.warn(`Animation "${o}" not found. Available: ${f.join(", ")}`);return}const m=g.current;if(!(m===i&&i.isRunning())&&(m&&m!==i&&m.fadeOut(y),i.reset(),i.fadeIn(y),i.setLoop(u?E.LoopRepeat:E.LoopOnce,u?1/0:1),i.clampWhenFinished=!u,i.play(),u||i.getMixer().update(0),g.current=i,a&&!u&&T.current)){const S=i.getMixer(),d=v=>{if(v.action===i){S.removeEventListener("finished",d);const R=l[T.current];R&&(i.fadeOut(y),R.reset().fadeIn(y).play(),g.current=R)}};S.addEventListener("finished",d)}},[l,f]),h=e.useCallback(()=>{var o;(o=g.current)==null||o.fadeOut(.2),g.current=null},[]),r=e.useCallback(()=>f,[f]);return{playAnimation:x,stopAnimation:h,getAnimationNames:r,actions:l}}function z(n,t){const s=e.useRef(t||{}),l=e.useRef([]),f=e.useRef([]);e.useEffect(()=>{const h=new Set,r=[];n.traverse(o=>{o instanceof E.Mesh&&o.morphTargetDictionary&&o.morphTargetInfluences&&(r.push(o),Object.keys(o.morphTargetDictionary).forEach(c=>{h.add(c)}))}),l.current=Array.from(h).sort(),f.current=r},[n]),B.useFrame(()=>{const h=s.current;f.current.forEach(r=>{!r.morphTargetDictionary||!r.morphTargetInfluences||Object.entries(h).forEach(([o,c])=>{const u=r.morphTargetDictionary[o];u!==void 0&&(r.morphTargetInfluences[u]=c)})})}),e.useEffect(()=>{t&&(s.current={...t})},[t]);const g=e.useCallback((h,r)=>{s.current[h]=Math.max(0,Math.min(1,r))},[]),T=e.useCallback(()=>l.current,[]),x=e.useCallback(()=>({...s.current}),[]);return{setMorphTarget:g,getMorphTargetNames:T,getMorphTargetValues:x}}const oe=e.createContext(null);function fe(){const n=e.useContext(oe);if(!n)throw new Error("BoneAttachment must be used within an AnimatedModel");return n}const q=e.forwardRef(({url:n,position:t=[0,0,0],rotation:s=[0,0,0],scale:l=1,defaultAnimation:f,morphTargets:g,meshVisibility:T,materialColors:x,materialTextures:h,onLoad:r,onError:o,children:c},u)=>{const y=e.useRef(null),a=e.useRef([]),i=e.useRef(r);i.current=r;const{scene:m,animations:S}=O.useGLTF(n),d=e.useMemo(()=>Q.clone(m),[m]),{playAnimation:v,stopAnimation:R,getAnimationNames:M}=te(S,d,{defaultAnimation:f}),{setMorphTarget:b}=z(d,g),{setMeshVisibility:D,getMeshNames:p}=G(d,T),{setMaterialColor:A,getMaterialNames:k,getMaterialColor:$}=K(d,x),{setMaterialTextures:C,clearMaterialTextures:j}=U(d,h);e.useEffect(()=>{if(!d)return;const I=setTimeout(()=>{var Z;const L=[],H=[],F=new Set,V=new Set;let Y=0;d.traverse(W=>{if(Y++,W.type==="Bone"&&L.push(W.name),W.isMesh){const P=W;H.push(P.name),P.castShadow=!0,P.receiveShadow=!0,(Array.isArray(P.material)?P.material:[P.material]).forEach(_=>{F.add(_.name),_.shadowSide=E.DoubleSide}),P.morphTargetDictionary&&Object.keys(P.morphTargetDictionary).forEach(_=>{V.add(_)})}}),a.current=Array.from(V).sort(),(Z=i.current)==null||Z.call(i,{meshes:H.sort(),materials:Array.from(F).sort(),bones:L.sort(),nodeCount:Y,animations:S.map(W=>W.name),morphTargetNames:a.current})},0);return()=>clearTimeout(I)},[d,S]),e.useImperativeHandle(u,()=>({playAnimation:v,stopAnimation:R,getAnimationNames:M,getGroup:()=>y.current,setMorphTarget:b,getMorphTargetNames:()=>a.current,setMeshVisibility:D,getMeshNames:p,setMaterialColor:A,getMaterialNames:k,getMaterialColor:$,setMaterialTextures:C,clearMaterialTextures:j}));const X=e.useMemo(()=>({scene:d,getBone:I=>d.getObjectByName(I)||null}),[d]),N=typeof l=="number"?[l,l,l]:l;return w.jsx(oe.Provider,{value:X,children:w.jsxs("group",{ref:y,position:t,rotation:s,scale:N,children:[w.jsx("primitive",{object:d}),c]})})});q.displayName="AnimatedModel";q.preload=n=>{O.useGLTF.preload(n)};const re=e.forwardRef(({url:n,position:t=[0,0,0],rotation:s=[0,0,0],scale:l=1,morphTargets:f,meshVisibility:g,materialColors:T,materialTextures:x,onMorphTargetsFound:h,onLoad:r,onError:o},c)=>{const{scene:u}=O.useGLTF(n),y=e.useRef(r);y.current=r;const a=e.useRef(h);a.current=h;const i=e.useMemo(()=>u.clone(),[u]),{setMorphTarget:m,getMorphTargetNames:S,getMorphTargetValues:d}=z(i,f),{setMeshVisibility:v,getMeshNames:R}=G(i,g),{setMaterialColor:M,getMaterialNames:b,getMaterialColor:D}=K(i,T),{setMaterialTextures:p,clearMaterialTextures:A}=U(i,x);e.useEffect(()=>{var C;const $=S();$.length>0&&((C=a.current)==null||C.call(a,$))},[i,S]),e.useEffect(()=>{var N;if(!i)return;const $=[],C=new Set,j=[];let X=0;i.traverse(I=>{if(X++,I.type==="Bone"&&j.push(I.name),I.isMesh){const L=I;$.push(L.name),L.castShadow=!0,L.receiveShadow=!0,(Array.isArray(L.material)?L.material:[L.material]).forEach(F=>C.add(F.name))}}),(N=y.current)==null||N.call(y,{meshes:$.sort(),materials:Array.from(C).sort(),bones:j.sort(),nodeCount:X})},[i]),e.useImperativeHandle(c,()=>({setMorphTarget:m,getMorphTargetNames:S,getMorphTargetValues:d,setMeshVisibility:v,getMeshNames:R,setMaterialColor:M,getMaterialNames:b,getMaterialColor:D,setMaterialTextures:p,clearMaterialTextures:A}));const k=typeof l=="number"?[l,l,l]:l;return w.jsx("group",{position:t,rotation:s,scale:k,children:w.jsx("primitive",{object:i})})});re.displayName="MorphableModel";function me({children:n,bone:t,position:s=[0,0,0],rotation:l=[0,0,0],scale:f=1}){const{getBone:g}=fe(),[T,x]=e.useState(null);if(e.useEffect(()=>{const r=g(t);r?x(r):console.warn(`Bone "${t}" not found in model`)},[t,g]),!T)return null;const h=typeof f=="number"?[f,f,f]:f;return B.createPortal(w.jsx("group",{position:s,rotation:l,scale:h,children:n}),T)}function de(n,t){const{scene:s,animations:l}=O.useGLTF(n),f=e.useMemo(()=>Q.clone(s),[s]);return e.useEffect(()=>{var r;if(!f)return;const g=[],T=[],x=new Set;let h=0;f.traverse(o=>{if(h++,o.type==="Bone"&&g.push(o.name),o.isMesh){const c=o;T.push(c.name),c.castShadow=!0,c.receiveShadow=!0,(Array.isArray(c.material)?c.material:[c.material]).forEach(y=>{x.add(y.name),y.shadowSide=E.DoubleSide})}}),(r=t==null?void 0:t.onLoad)==null||r.call(t,{meshes:T.sort(),materials:Array.from(x).sort(),bones:g.sort(),nodeCount:h})},[f,t]),{scene:f,animations:l}}function Me(n){O.useGLTF.preload(n)}exports.AnimatedModel=q;exports.BoneAttachment=me;exports.Model=ee;exports.MorphableModel=re;exports.Scene3D=pe;exports.preloadModel=Me;exports.useAnimationController=te;exports.useClonedModel=de;exports.useMaterialColor=K;exports.useMaterialTexture=U;exports.useMeshVisibility=G;exports.useMorphTargets=z;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react"),O=require("@react-three/drei"),ne=require("three"),ae=require("three/examples/jsm/utils/SkeletonUtils.js"),B=require("@react-three/fiber"),le=require("three/examples/jsm/loaders/KTX2Loader.js"),S=require("react/jsx-runtime");function Q(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const a=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,a.get?a:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const R=Q(ne),ee=Q(ae);function ie({position:e,controlsConfig:t}){const{camera:o}=B.useThree(),a=r.useRef(null);return r.useEffect(()=>{e&&o&&(o.position.set(e[0],e[1],e[2]),o.updateProjectionMatrix(),a.current&&(a.current.target.set(0,0,0),a.current.update()))},[e,o]),S.jsx(O.OrbitControls,{ref:a,makeDefault:!0,enabled:t.enabled,enablePan:t.enablePan,enableZoom:t.enableZoom,enableRotate:t.enableRotate,minDistance:t.minDistance,maxDistance:t.maxDistance,minPolarAngle:t.minPolarAngle,maxPolarAngle:t.maxPolarAngle,autoRotate:t.autoRotate,autoRotateSpeed:t.autoRotateSpeed})}function ce({background:e}){const t=e==null?void 0:e.startsWith("#");return e?t?S.jsx("color",{attach:"background",args:[e]}):S.jsx(ue,{url:e}):null}function ue({url:e}){const t=O.useTexture(e);return r.useMemo(()=>{t.colorSpace=R.SRGBColorSpace},[t]),S.jsx("primitive",{attach:"background",object:t})}function me({config:e}){return S.jsx(O.Environment,{files:e.files,background:e.background??!1,blur:e.blur??0,children:S.jsx("group",{scale:e.intensity??1,children:S.jsx("ambientLight",{intensity:0})})})}function pe({config:e}){switch(e.type){case"spot":{const{position:t=[5,10,5],intensity:o=50,castShadow:a=!0,angle:c=Math.PI/6,penumbra:M=.5,decay:b=2,distance:T=0,color:g="#ffffff"}=e;return S.jsx("spotLight",{position:t,intensity:o,castShadow:a,angle:c,penumbra:M,decay:b,distance:T,color:g})}case"point":{const{position:t=[0,5,0],intensity:o=20,color:a="#ffffff",distance:c=0,decay:M=2,castShadow:b=!1}=e;return S.jsx("pointLight",{position:t,intensity:o,color:a,distance:c,decay:M,castShadow:b})}case"directional":{const{position:t=[10,20,10],intensity:o=40,color:a="#ffffff",castShadow:c=!0}=e;return S.jsx("directionalLight",{position:t,intensity:o,color:a,castShadow:c})}case"hemisphere":{const{skyColor:t="#ffffff",groundColor:o="#444444",intensity:a=.5,position:c=[0,10,0]}=e,M=r.useMemo(()=>new R.Color(t),[t]),b=r.useMemo(()=>new R.Color(o),[o]);return S.jsx("hemisphereLight",{args:[M,b,a],position:c})}case"ambient":{const{intensity:t=.5,color:o="#ffffff"}=e;return S.jsx("ambientLight",{intensity:t,color:o})}default:return null}}function fe({children:e,camera:t={},controls:o={},background:a,shadows:c=!0,lights:M=[{type:"ambient",intensity:.5},{type:"spot",position:[5,10,5],intensity:50,castShadow:!0}],environment:b,contactShadows:T=!0,style:g,className:l}){const s={position:t.position||[0,2,5],fov:t.fov||45},u={enabled:o.enabled??!0,enablePan:o.enablePan??!0,enableZoom:o.enableZoom??!0,enableRotate:o.enableRotate??!0,minDistance:o.minDistance,maxDistance:o.maxDistance,minPolarAngle:o.minPolarAngle,maxPolarAngle:o.maxPolarAngle,autoRotate:o.autoRotate??!1,autoRotateSpeed:o.autoRotateSpeed??2},m=typeof T=="object"?{position:T.position||[0,-1,0],opacity:T.opacity??.5,blur:T.blur??2}:T?{position:[0,-1,0],opacity:.5,blur:2}:null;return S.jsx("div",{style:g,className:l,children:S.jsxs(B.Canvas,{shadows:c,camera:{position:s.position,fov:s.fov},style:{width:"100%",height:"100%"},children:[S.jsx(r.Suspense,{fallback:null,children:S.jsx(ce,{background:a})}),b&&S.jsx(r.Suspense,{fallback:null,children:S.jsx(me,{config:b})}),M.map((h,n)=>S.jsx(pe,{config:h},`${h.type}-${n}`)),S.jsx(r.Suspense,{fallback:null,children:e}),S.jsx(ie,{position:s.position,controlsConfig:u}),m&&S.jsx(O.ContactShadows,{position:m.position,opacity:m.opacity,blur:m.blur})]})})}function K(e,t){const o=r.useRef(new Map),a=r.useRef({}),c=r.useRef({});r.useEffect(()=>{t&&(a.current={...t})},[t]),r.useEffect(()=>{if(!e)return;const g=new Map;e.traverse(l=>{if(l.isMesh){const s=l;s.name&&g.set(s.name,s)}}),o.current=g},[e]),B.useFrame(()=>{const g=o.current;if(g.size===0)return;const l={...a.current,...c.current};for(const[s,u]of Object.entries(l)){const m=g.get(s);m&&m.visible!==u&&(m.visible=u)}});const M=r.useCallback((g,l)=>{c.current[g]=l;const s=o.current.get(g);s&&(s.visible=l)},[]),b=r.useCallback(()=>Array.from(o.current.keys()).sort(),[]),T=r.useCallback(()=>{const g={};return o.current.forEach((l,s)=>{g[s]=l.visible}),g},[]);return{setMeshVisibility:M,getMeshNames:b,getMeshVisibility:T}}function G(e,t){const o=r.useRef(new Map),a=r.useRef(new Map);r.useEffect(()=>{if(!e)return;const l=new Map;e.traverse(s=>{if(s.isMesh){const u=s;(Array.isArray(u.material)?u.material:[u.material]).forEach(h=>{h.name&&!l.has(h.name)&&l.set(h.name,h)})}}),o.current=l,t&&Object.entries(t).forEach(([s,u])=>{const m=l.get(s);if(m&&!Array.isArray(m)){const h=c(u);m.color&&m.color.copy(h),a.current.set(s,h)}})},[e,t]),B.useFrame(()=>{a.current.forEach((l,s)=>{const u=o.current.get(s);if(u&&!Array.isArray(u)){const m=u;m.color&&!m.color.equals(l)&&(m.color.copy(l),m.needsUpdate=!0)}})});const c=l=>typeof l=="string"?new R.Color(l):new R.Color(l[0],l[1],l[2]),M=r.useCallback((l,s)=>{const u=c(s);a.current.set(l,u);const m=o.current.get(l);if(m&&!Array.isArray(m)){const h=m;h.color&&(h.color.copy(u),h.needsUpdate=!0)}},[]),b=r.useCallback(()=>Array.from(o.current.keys()).sort(),[]),T=r.useCallback(l=>{const s=o.current.get(l);if(s&&!Array.isArray(s)){const u=s;if(u.color)return"#"+u.color.getHexString()}return null},[]),g=r.useCallback(()=>{const l={};return o.current.forEach((s,u)=>{if(!Array.isArray(s)){const m=s;m.color&&(l[u]="#"+m.color.getHexString())}}),l},[]);return{setMaterialColor:M,getMaterialNames:b,getMaterialColor:T,getAllMaterialColors:g}}function H(e){const t=e.toLowerCase();if(t.endsWith(".ktx2"))return!0;try{const o=new URL(e,window.location.origin),a=decodeURIComponent(o.hash.replace(/^#/,"")).toLowerCase(),c=decodeURIComponent(o.search).toLowerCase(),M=decodeURIComponent(o.pathname).toLowerCase();return a.endsWith(".ktx2")||c.includes(".ktx2")||M.endsWith(".ktx2")}catch{return t.includes(".ktx2")}}function z(e,t){const{gl:o}=B.useThree(),a=r.useRef(new Map),c=r.useRef(new R.TextureLoader),M=r.useRef(null),b=r.useRef(new Map),T=r.useRef(new Set),g=r.useRef("");r.useEffect(()=>{if(!M.current)try{const n=typeof WebAssembly=="object"&&typeof WebAssembly.validate=="function";console.log("[useMaterialTexture] Browser features:"),console.log(` WebAssembly supported: ${n}`),console.log(` WebGL2: ${o.capabilities.isWebGL2}`);const i=new le.KTX2Loader;i.setTranscoderPath("/basis/"),i.detectSupport(o),M.current=i,console.log("[useMaterialTexture] ✅ KTX2Loader initialized"),console.log("[useMaterialTexture] Transcoder path: /basis/"),fetch("/basis/basis_transcoder.wasm").then(p=>{p.ok?console.log("[useMaterialTexture] ✅ basis_transcoder.wasm is accessible"):console.error("[useMaterialTexture] ❌ basis_transcoder.wasm returned",p.status)}).catch(p=>{console.error("[useMaterialTexture] ❌ Failed to check basis_transcoder.wasm:",p)}),n||(console.warn("[useMaterialTexture] ⚠️ WebAssembly not supported! KTX2 will fallback to CPU decoding (slow)"),console.warn("[useMaterialTexture] ⚠️ Recommend using WebP instead of KTX2 for this browser"))}catch(n){console.error("[useMaterialTexture] ❌ Failed to initialize KTX2Loader:",n)}return()=>{M.current&&(M.current.dispose(),M.current=null)}},[o]),r.useEffect(()=>{if(!e)return;const n=new Map;e.traverse(i=>{if(i.isMesh){const p=i;(Array.isArray(p.material)?p.material:[p.material]).forEach(f=>{f.name&&!n.has(f.name)&&n.set(f.name,f)})}}),a.current=n},[e]);const l=r.useCallback(n=>H(n)?M.current?M.current:(console.warn("[useMaterialTexture] KTX2Loader not initialized, falling back to TextureLoader"),c.current):c.current,[]);r.useEffect(()=>{if(!t||!e)return;const n=a.current;if(n.size===0)return;const i=JSON.stringify(t);if(g.current===i){console.log("[useMaterialTexture] Textures unchanged, skipping reload");return}g.current=i;let p=!1;const w=new Map;Object.entries(t).forEach(([d,$])=>{w.set(d,typeof $=="string"?{map:$}:$)}),console.log("[useMaterialTexture] Starting texture load for",w.size,"materials");const f=[];w.forEach((d,$)=>{var A,L;const D=n.get($);if(!D||!D.isMeshStandardMaterial){console.warn(`[useMaterialTexture] Material "${$}" not found or not MeshStandardMaterial`);return}const y=D;console.log(`[useMaterialTexture] 📋 Material "${$}" BEFORE reset:`),console.log(` - map: ${y.map?"EXISTS":"null"} ${y.map?`(uuid: ${y.map.uuid})`:""}`),console.log(` - normalMap: ${y.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${y.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${y.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${y.emissiveMap?"EXISTS":"null"}`),console.log(` - aoMap: ${y.aoMap?"EXISTS":"null"}`),console.log(` - color: ${(A=y.color)==null?void 0:A.getHexString()}`),console.log(` - emissive: ${(L=y.emissive)==null?void 0:L.getHexString()}`),console.log(` - material uuid: ${y.uuid}`),Object.entries(d).forEach(([x,C])=>{if(!C)return;const j=x,k=y[j];k&&(console.log(`[useMaterialTexture] 🗑️ Disposing old ${j} (uuid: ${k.uuid})`),k.dispose(),y[j]=null)}),d.emissiveMap&&(y.emissive=new R.Color(0),y.emissiveIntensity=0),y.needsUpdate=!0,y.color=new R.Color(16777215),console.log(`[useMaterialTexture] ✅ Material "${$}" AFTER reset: only specified maps cleared`),Object.entries(d).forEach(([x,C])=>{if(!C)return;const j=`${$}_${x}_${C}`,k=b.current.get(j);if(k){console.log(`[useMaterialTexture] Using cached texture: ${$}.${x}`),p||s(y,x,k);return}if(T.current.has(j)){console.log(`[useMaterialTexture] Skipping already loading: ${$}.${x}`);return}f.push({materialName:$,textureType:x,url:C,material:y})})}),console.log(`[useMaterialTexture] Queued ${f.length} textures to load`);let E=0;const v=()=>{if(p||E>=f.length){console.log("[useMaterialTexture] ✅ All textures loaded"),console.log("[useMaterialTexture] 📊 FINAL material states:"),n.forEach((A,L)=>{var C,j;const x=A;console.log(` Material "${L}":`),console.log(` - map: ${x.map?"EXISTS":"null"} ${x.map?`(colorSpace: ${x.map.colorSpace})`:""}`),console.log(` - normalMap: ${x.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${x.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${x.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${x.emissiveMap?"EXISTS":"null"}`),console.log(` - color: ${(C=x.color)==null?void 0:C.getHexString()}`),console.log(` - emissive: ${(j=x.emissive)==null?void 0:j.getHexString()}`),console.log(` - emissiveIntensity: ${x.emissiveIntensity}`),console.log(` - roughness: ${x.roughness}`),console.log(` - metalness: ${x.metalness}`)});return}const d=f[E++],$=`${d.materialName}_${d.textureType}_${d.url}`;console.log(`[useMaterialTexture] Loading (${E}/${f.length}): ${d.materialName}.${d.textureType} from ${d.url}`),T.current.add($);const D=l(d.url),y=H(d.url)?"KTX2Loader":"TextureLoader";console.log(`[useMaterialTexture] Using ${y} for ${d.url}`),D.load(d.url,A=>{var j,k,P,X,I,F;if(T.current.delete($),p){console.log(`[useMaterialTexture] Disposed, cleaning up texture: ${d.materialName}.${d.textureType}`),A.dispose();return}const L=((j=A.image)==null?void 0:j.width)||((P=(k=A.source)==null?void 0:k.data)==null?void 0:P.width)||"unknown",x=((X=A.image)==null?void 0:X.height)||((F=(I=A.source)==null?void 0:I.data)==null?void 0:F.height)||"unknown";console.log(`[useMaterialTexture] ✅ Loaded: ${d.materialName}.${d.textureType} (${L}x${x})`),A.colorSpace=d.textureType==="map"||d.textureType==="emissiveMap"?R.SRGBColorSpace:R.NoColorSpace,A.wrapS=R.RepeatWrapping,A.wrapT=R.RepeatWrapping,A.flipY=!1,b.current.set($,A),s(d.material,d.textureType,A);const C=H(d.url)?500:150;console.log(`[useMaterialTexture] Waiting111111 ${C}ms before next texture...`),setTimeout(v,0)},A=>{if(A.lengthComputable){const L=Math.round(A.loaded/A.total*100);L%25===0&&console.log(`[useMaterialTexture] Progress ${d.materialName}.${d.textureType}: ${L}%`)}},A=>{T.current.delete($),p||(console.error(`[useMaterialTexture] ❌ Failed to load ${d.materialName}.${d.textureType} from ${d.url}`),console.error("[useMaterialTexture] Error details:",A),console.error("[useMaterialTexture] Loader type:",y),H(d.url)&&(console.error("[useMaterialTexture] KTX2 error - file may not be in Basis Universal format!"),console.error("[useMaterialTexture] Make sure files are created with: gltf-transform etc1s input.png output.ktx2"))),setTimeout(v,100)})};return v(),()=>{console.log("[useMaterialTexture] Cleanup: disposed"),p=!0}},[e,t,l]);const s=(n,i,p)=>{var w,f;switch(console.log(`[useMaterialTexture] 🎨 Applying texture: ${n.name}.${i} (texture uuid: ${p.uuid})`),i){case"map":n.map=p;break;case"normalMap":n.normalMap=p;break;case"roughnessMap":n.roughnessMap=p;break;case"metalnessMap":n.metalnessMap=p;break;case"emissiveMap":n.emissiveMap=p,n.emissive=new R.Color(16777215),n.emissiveIntensity=1;break;case"alphaMap":console.log(`[useMaterialTexture] Skipping alphaMap for "${n.name}" to prevent disappearing`);break;case"aoMap":n.aoMap=p;break}n.needsUpdate=!0,console.log(`[useMaterialTexture] ✅ Applied ${i} to ${n.name}, needsUpdate=true`),console.log(`[useMaterialTexture] 📊 Material "${n.name}" FINAL state:`),console.log(` - map: ${n.map?"EXISTS":"null"} ${n.map?`(uuid: ${n.map.uuid}, colorSpace: ${n.map.colorSpace})`:""}`),console.log(` - normalMap: ${n.normalMap?"EXISTS":"null"}`),console.log(` - roughnessMap: ${n.roughnessMap?"EXISTS":"null"}`),console.log(` - metalnessMap: ${n.metalnessMap?"EXISTS":"null"}`),console.log(` - emissiveMap: ${n.emissiveMap?"EXISTS":"null"}`),console.log(` - aoMap: ${n.aoMap?"EXISTS":"null"}`),console.log(` - color: ${(w=n.color)==null?void 0:w.getHexString()}`),console.log(` - emissive: ${(f=n.emissive)==null?void 0:f.getHexString()}`),console.log(` - emissiveIntensity: ${n.emissiveIntensity}`),console.log(` - roughness: ${n.roughness}`),console.log(` - metalness: ${n.metalness}`)},u=r.useCallback((n,i)=>{const p=typeof i=="string"?{map:i}:i,w=a.current.get(n);if(!w||!w.isMeshStandardMaterial){console.warn(`Material "${n}" not found or not MeshStandardMaterial`);return}const f=w;Object.entries(p).forEach(([E,v])=>{if(!v)return;const d=`${n}_${E}_${v}`,$=b.current.get(d);if($){s(f,E,$);return}l(v).load(v,y=>{y.colorSpace=E==="map"||E==="emissiveMap"?R.SRGBColorSpace:R.NoColorSpace,y.wrapS=R.RepeatWrapping,y.wrapT=R.RepeatWrapping,b.current.set(d,y),s(f,E,y)},void 0,y=>{console.error(`Failed to load texture ${v}:`,y)})})},[l]),m=r.useCallback(()=>Array.from(a.current.keys()).sort(),[]),h=r.useCallback(n=>{const i=a.current.get(n);if(!i||!i.isMeshStandardMaterial)return;const p=i;p.map=null,p.normalMap=null,p.roughnessMap=null,p.metalnessMap=null,p.emissiveMap=null,p.alphaMap=null,p.aoMap=null,p.needsUpdate=!0},[]);return{setMaterialTextures:u,getMaterialNames:m,clearMaterialTextures:h}}function te({url:e,position:t=[0,0,0],rotation:o=[0,0,0],scale:a=1,meshVisibility:c,materialColors:M,materialTextures:b,onLoad:T,onError:g}){const{scene:l}=O.useGLTF(e),s=r.useRef(T);s.current=T;const u=r.useMemo(()=>{const h=l.clone();console.log("[Model] 🔍 Scene clone created, checking materials...");const n=[],i=new Set,p=[];let w=0;return h.traverse(f=>{if(w++,f.type==="Bone"&&p.push(f.name),f.isMesh){const E=f;n.push(E.name),E.castShadow=!0,E.receiveShadow=!0,(Array.isArray(E.material)?E.material:[E.material]).forEach(d=>{i.add(d.name),console.log(`[Model] 📦 Material found: "${d.name}" (uuid: ${d.uuid})`);const $=d;console.log(` - Has map: ${$.map?"YES":"NO"}`),console.log(` - Has normalMap: ${$.normalMap?"YES":"NO"}`),console.log(` - Has roughnessMap: ${$.roughnessMap?"YES":"NO"}`),console.log(` - Has metalnessMap: ${$.metalnessMap?"YES":"NO"}`)})}}),console.log(`[Model] 📊 Clone summary: ${n.length} meshes, ${i.size} materials`),setTimeout(()=>{var f;(f=s.current)==null||f.call(s,{meshes:n.sort(),materials:Array.from(i).sort(),bones:p.sort(),nodeCount:w})},0),h},[l]);K(u,c),G(u,M),z(u,b);const m=typeof a=="number"?[a,a,a]:a;return S.jsx("group",{position:t,rotation:o,scale:m,children:S.jsx("primitive",{object:u})})}te.preload=e=>{O.useGLTF.preload(e)};function re(e,t,o){const{actions:a,names:c}=O.useAnimations(e,t),M=r.useRef(null),b=r.useRef(o==null?void 0:o.defaultAnimation);r.useEffect(()=>{if(c.length===0)return;const s=b.current;let u=c[0];if(s){const h=c.find(n=>n===s||n.includes(s));h&&(u=h)}const m=a[u];m&&(m.reset().fadeIn(.5).play(),M.current=m)},[a,c]);const T=r.useCallback((s,u)=>{const{loop:m=!1,crossFadeDuration:h=.2,restoreDefault:n=!0}=u||{};let i=a[s];if(!i){const w=Object.keys(a).find(f=>f.toLowerCase().includes(s.toLowerCase())||s.toLowerCase().includes(f.toLowerCase()));w&&(i=a[w])}if(!i){console.warn(`Animation "${s}" not found. Available: ${c.join(", ")}`);return}const p=M.current;if(!(p===i&&i.isRunning())&&(p&&p!==i&&p.fadeOut(h),i.reset(),i.fadeIn(h),i.setLoop(m?R.LoopRepeat:R.LoopOnce,m?1/0:1),i.clampWhenFinished=!m,i.play(),m||i.getMixer().update(0),M.current=i,n&&!m&&b.current)){const w=i.getMixer(),f=E=>{if(E.action===i){w.removeEventListener("finished",f);const v=a[b.current];v&&(i.fadeOut(h),v.reset().fadeIn(h).play(),M.current=v)}};w.addEventListener("finished",f)}},[a,c]),g=r.useCallback(()=>{var s;(s=M.current)==null||s.fadeOut(.2),M.current=null},[]),l=r.useCallback(()=>c,[c]);return{playAnimation:T,stopAnimation:g,getAnimationNames:l,actions:a}}function q(e,t){const o=r.useRef(t||{}),a=r.useRef([]),c=r.useRef([]);r.useEffect(()=>{const g=new Set,l=[];e.traverse(s=>{s instanceof R.Mesh&&s.morphTargetDictionary&&s.morphTargetInfluences&&(l.push(s),Object.keys(s.morphTargetDictionary).forEach(u=>{g.add(u)}))}),a.current=Array.from(g).sort(),c.current=l},[e]),B.useFrame(()=>{const g=o.current;c.current.forEach(l=>{!l.morphTargetDictionary||!l.morphTargetInfluences||Object.entries(g).forEach(([s,u])=>{const m=l.morphTargetDictionary[s];m!==void 0&&(l.morphTargetInfluences[m]=u)})})}),r.useEffect(()=>{t&&(o.current={...t})},[t]);const M=r.useCallback((g,l)=>{o.current[g]=Math.max(0,Math.min(1,l))},[]),b=r.useCallback(()=>a.current,[]),T=r.useCallback(()=>({...o.current}),[]);return{setMorphTarget:M,getMorphTargetNames:b,getMorphTargetValues:T}}const oe=r.createContext(null);function de(){const e=r.useContext(oe);if(!e)throw new Error("BoneAttachment must be used within an AnimatedModel");return e}const V=r.forwardRef(({url:e,position:t=[0,0,0],rotation:o=[0,0,0],scale:a=1,defaultAnimation:c,morphTargets:M,meshVisibility:b,materialColors:T,materialTextures:g,onLoad:l,onError:s,children:u},m)=>{const h=r.useRef(null),n=r.useRef([]),i=r.useRef(l);i.current=l;const{scene:p,animations:w}=O.useGLTF(e),f=r.useMemo(()=>ee.clone(p),[p]),{playAnimation:E,stopAnimation:v,getAnimationNames:d}=re(w,f,{defaultAnimation:c}),{setMorphTarget:$}=q(f,M),{setMeshVisibility:D,getMeshNames:y}=K(f,b),{setMaterialColor:A,getMaterialNames:L,getMaterialColor:x}=G(f,T),{setMaterialTextures:C,clearMaterialTextures:j}=z(f,g);r.useEffect(()=>{if(!f)return;const X=setTimeout(()=>{var J;const I=[],F=[],_=new Set,Y=new Set;let Z=0;f.traverse(W=>{if(Z++,W.type==="Bone"&&I.push(W.name),W.isMesh){const N=W;F.push(N.name),N.castShadow=!0,N.receiveShadow=!0,(Array.isArray(N.material)?N.material:[N.material]).forEach(U=>{_.add(U.name),U.shadowSide=R.DoubleSide}),N.morphTargetDictionary&&Object.keys(N.morphTargetDictionary).forEach(U=>{Y.add(U)})}}),n.current=Array.from(Y).sort(),(J=i.current)==null||J.call(i,{meshes:F.sort(),materials:Array.from(_).sort(),bones:I.sort(),nodeCount:Z,animations:w.map(W=>W.name),morphTargetNames:n.current})},0);return()=>clearTimeout(X)},[f,w]),r.useImperativeHandle(m,()=>({playAnimation:E,stopAnimation:v,getAnimationNames:d,getGroup:()=>h.current,setMorphTarget:$,getMorphTargetNames:()=>n.current,setMeshVisibility:D,getMeshNames:y,setMaterialColor:A,getMaterialNames:L,getMaterialColor:x,setMaterialTextures:C,clearMaterialTextures:j}));const k=r.useMemo(()=>({scene:f,getBone:X=>f.getObjectByName(X)||null}),[f]),P=typeof a=="number"?[a,a,a]:a;return S.jsx(oe.Provider,{value:k,children:S.jsxs("group",{ref:h,position:t,rotation:o,scale:P,children:[S.jsx("primitive",{object:f}),u]})})});V.displayName="AnimatedModel";V.preload=e=>{O.useGLTF.preload(e)};const se=r.forwardRef(({url:e,position:t=[0,0,0],rotation:o=[0,0,0],scale:a=1,morphTargets:c,meshVisibility:M,materialColors:b,materialTextures:T,onMorphTargetsFound:g,onLoad:l,onError:s},u)=>{const{scene:m}=O.useGLTF(e),h=r.useRef(l);h.current=l;const n=r.useRef(g);n.current=g;const i=r.useMemo(()=>m.clone(),[m]),{setMorphTarget:p,getMorphTargetNames:w,getMorphTargetValues:f}=q(i,c),{setMeshVisibility:E,getMeshNames:v}=K(i,M),{setMaterialColor:d,getMaterialNames:$,getMaterialColor:D}=G(i,b),{setMaterialTextures:y,clearMaterialTextures:A}=z(i,T);r.useEffect(()=>{var C;const x=w();x.length>0&&((C=n.current)==null||C.call(n,x))},[i,w]),r.useEffect(()=>{var P;if(!i)return;const x=[],C=new Set,j=[];let k=0;i.traverse(X=>{if(k++,X.type==="Bone"&&j.push(X.name),X.isMesh){const I=X;x.push(I.name),I.castShadow=!0,I.receiveShadow=!0,(Array.isArray(I.material)?I.material:[I.material]).forEach(_=>C.add(_.name))}}),(P=h.current)==null||P.call(h,{meshes:x.sort(),materials:Array.from(C).sort(),bones:j.sort(),nodeCount:k})},[i]),r.useImperativeHandle(u,()=>({setMorphTarget:p,getMorphTargetNames:w,getMorphTargetValues:f,setMeshVisibility:E,getMeshNames:v,setMaterialColor:d,getMaterialNames:$,getMaterialColor:D,setMaterialTextures:y,clearMaterialTextures:A}));const L=typeof a=="number"?[a,a,a]:a;return S.jsx("group",{position:t,rotation:o,scale:L,children:S.jsx("primitive",{object:i})})});se.displayName="MorphableModel";function Me({children:e,bone:t,position:o=[0,0,0],rotation:a=[0,0,0],scale:c=1}){const{getBone:M}=de(),[b,T]=r.useState(null);if(r.useEffect(()=>{const l=M(t);l?T(l):console.warn(`Bone "${t}" not found in model`)},[t,M]),!b)return null;const g=typeof c=="number"?[c,c,c]:c;return B.createPortal(S.jsx("group",{position:o,rotation:a,scale:g,children:e}),b)}function ge(e,t){const{scene:o,animations:a}=O.useGLTF(e),c=r.useMemo(()=>ee.clone(o),[o]);return r.useEffect(()=>{var l;if(!c)return;const M=[],b=[],T=new Set;let g=0;c.traverse(s=>{if(g++,s.type==="Bone"&&M.push(s.name),s.isMesh){const u=s;b.push(u.name),u.castShadow=!0,u.receiveShadow=!0,(Array.isArray(u.material)?u.material:[u.material]).forEach(h=>{T.add(h.name),h.shadowSide=R.DoubleSide})}}),(l=t==null?void 0:t.onLoad)==null||l.call(t,{meshes:b.sort(),materials:Array.from(T).sort(),bones:M.sort(),nodeCount:g})},[c,t]),{scene:c,animations:a}}function he(e){O.useGLTF.preload(e)}exports.AnimatedModel=V;exports.BoneAttachment=Me;exports.Model=te;exports.MorphableModel=se;exports.Scene3D=fe;exports.preloadModel=he;exports.useAnimationController=re;exports.useClonedModel=ge;exports.useMaterialColor=G;exports.useMaterialTexture=z;exports.useMeshVisibility=K;exports.useMorphTargets=q;
|
|
2
2
|
//# sourceMappingURL=mbt-3d.cjs.map
|